Cry*_*nda 4 java animation geometry javafx
我正在尝试重新创建玻尔原子模型,此时我已经设法使电子相对于轨道中的电子总数具有足够的位置,但现在我正在努力使它们旋转围绕所述轨道。 我遇到的问题是路径过渡使它们从所述位置朝向轨道中心,而不是使它们围绕轨道旋转。
好吧,我有这个节点:
@FXML
private Circle orbital;
@FXML
private Circle Electron;
@FXML
private Circle Electron2;
@FXML
private Circle Electron3;
Run Code Online (Sandbox Code Playgroud)
这是让它们旋转的方法:
private void animate(Circle electron, Circle orbital, double angulo, int duration) {
Path path = new Path();
double anguloRadianes = Math.toRadians(angulo);//pass the angle to radians
double X = orbital.getCenterX() + orbital.getRadius() * Math.cos(anguloRadianes);//calculate the x coordinate of the position of the electron
double Y = orbital.getCenterY() + orbital.getRadius() * Math.sin(anguloRadianes);//calculate the y coordinate of the position of the electron
path.getElements().add(new javafx.scene.shape.MoveTo(X, Y));//Put the electrons in their respective places
path.getElements().add(new javafx.scene.shape.ArcTo(orbital.getRadius(), orbital.getRadius(), angulo, electron.getCenterX(), electron.getCenterY(), false, false));//This should trace the path of the electrons, which should be around the orbital
//Here start the animations
PathTransition pathTransition = new PathTransition();
pathTransition.setNode(electron);
pathTransition.setPath(path);
pathTransition.setInterpolator(javafx.animation.Interpolator.LINEAR);
pathTransition.setCycleCount(PathTransition.INDEFINITE);
pathTransition.setDuration(Duration.millis(duration));
pathTransition.play();
}
Run Code Online (Sandbox Code Playgroud)
这就是我调用测试方法的方式:
public void calcular(ActionEvent event){
try{
int num = Integer.parseInt(cantidad.getText());//gets the number of electrons for the orbital
double ang = 360 / num;//divide the 360 degrees of the circle by the total number of electrons
double x = orbital.getCenterX();
double y = orbital.getCenterY();
double rad = orbital.getRadius();
animate(Electron, orbital, ang * 1, 750);
animate(Electron2, orbital, ang * 2, 750);
animate(Electron3, orbital, ang * 3, 750);
}
catch (Exception e){
System.out.println(e);
}
}
Run Code Online (Sandbox Code Playgroud)
你可以:
PathTransition。或者
2D 示例演示了在时间轴技术中使用 PathTransition 和旋转。
import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Background;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;
public class SolApp extends Application {
private static final double S = 400, C = S / 2, O = S * 3/8;
private static final Duration T = Duration.seconds(10);
private static final Color INDIA_INK = Color.web("#3c3f4a");
@Override
public void start(Stage stage) {
Circle sun = new Circle(
C, C,
S/10,
Color.ORANGERED
);
Circle earth = new Circle(
C + O, C,
S/40,
Color.PALETURQUOISE
);
Circle orbit = new Circle(C, C, O);
orbit.setFill(null);
orbit.setStroke(Color.GREEN);
orbit.setStrokeWidth(2);
Pane space = new Pane(sun, orbit, earth);
space.setPrefSize(S, S);
space.setBackground(Background.fill(INDIA_INK));
// Animation orbiter = getTimelineOrbiter(earth);
Animation orbiter = getPathTransitionOrbiter(orbit, earth);
stage.setScene(new Scene(space));
stage.show();
orbiter.play();
}
private static Transition getPathTransitionOrbiter(Circle orbit, Circle earth) {
PathTransition orbiter = new PathTransition(T, orbit, earth);
orbiter.setInterpolator(Interpolator.LINEAR);
orbiter.setCycleCount(Animation.INDEFINITE);
return orbiter;
}
private static Timeline getTimelineOrbiter(Circle earth) {
Rotate rotate = new Rotate();
rotate.setPivotX(C);
rotate.setPivotY(C);
earth.getTransforms().add(rotate);
Timeline orbiter = new Timeline(
new KeyFrame(
Duration.ZERO,
new KeyValue(
rotate.angleProperty(),
0
)
),
new KeyFrame(
T,
new KeyValue(
rotate.angleProperty(),
360
)
)
);
orbiter.setCycleCount(Animation.INDEFINITE);
return orbiter;
}
public static void main(String[] args) {
launch(args);
}
}
Run Code Online (Sandbox Code Playgroud)
如果要调整轨道的起点,可以在播放轨道器动画之前应用以下代码,根据需要调整除数在 0 和 1 之间。
orbiter.jumpTo(T.divide(.17));
Run Code Online (Sandbox Code Playgroud)
这将允许您将节点定位在任意路径上的任何位置(即使您没有沿着该路径设置动画)。
对于圆形和球体,就像此处示例中的那些,您不会注意到节点方向,但对于非对称节点,您可能希望定向节点方向,使其指向您需要的方向,因为它位于路径或沿着它旅行。
同样的技术也适用于 3D 场景中的对象动画。
import javafx.animation.*;
import javafx.application.Application;
import javafx.geometry.Point3D;
import javafx.scene.*;
import javafx.scene.image.Image;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;
public class SolAppThreeD extends Application {
private static final double S = 400, C = S / 2, O = S * 3/8;
private static final Duration T = Duration.seconds(10);
private static final Color INDIA_INK = Color.web("#3c3f4a");
@Override
public void start(Stage stage) {
Rectangle rectangle = new Rectangle(10, 10, Color.ORANGERED.darker().darker());
Image illuminationMap = rectangle.snapshot(null, null);
Sphere sun = new Sphere(
S/10
);
sun.setMaterial(new PhongMaterial(Color.ORANGERED, null, null, null, illuminationMap));
sun.setTranslateX(C);
sun.setTranslateY(C);
PointLight sunsRadiance = new PointLight(Color.LIGHTYELLOW);
sunsRadiance.translateXProperty().bind(sun.translateXProperty());
sunsRadiance.translateYProperty().bind(sun.translateYProperty());
sunsRadiance.translateZProperty().bind(sun.translateZProperty());
Sphere earth = new Sphere(
S/40
);
earth.setMaterial(new PhongMaterial(Color.DARKTURQUOISE));
earth.setTranslateX(C + O);
earth.setTranslateY(C);
// an f(xyz) Torus could be used instead here for higher fidelity.
// https://github.com/FXyz/FXyzLib/blob/master/src/org/fxyz/shapes/Torus.java
Circle orbit = new Circle(C, C, O);
orbit.setFill(null);
orbit.setStroke(Color.GREEN.deriveColor(0, 1, 1, .8));
orbit.setStrokeWidth(4);
Animation orbiter = getPathTransitionOrbiter(orbit, earth);
Group space = new Group(sun, sunsRadiance, orbit, earth);
PerspectiveCamera camera = new PerspectiveCamera();
DirectionalLight cameraLight = new DirectionalLight(Color.GRAY);
cameraLight.translateXProperty().bind(camera.translateXProperty());
cameraLight.translateYProperty().bind(camera.translateYProperty());
cameraLight.translateZProperty().bind(camera.translateZProperty());
Rotate xform = new Rotate(-80, new Point3D(1, 0, 0));
xform.setPivotX(C);
xform.setPivotY(C);
space.getTransforms().add(xform);
Group root = new Group(cameraLight, space);
Scene scene = new Scene(root, S, S, true, SceneAntialiasing.BALANCED);
scene.setCamera(camera);
scene.setFill(INDIA_INK);
stage.setScene(scene);
stage.show();
orbiter.play();
}
private static Transition getPathTransitionOrbiter(Circle orbit, Node satellite) {
PathTransition orbiter = new PathTransition(T, orbit, satellite);
orbiter.setInterpolator(Interpolator.LINEAR);
orbiter.setCycleCount(Animation.INDEFINITE);
return orbiter;
}
public static void main(String[] args) {
launch(args);
}
}
Run Code Online (Sandbox Code Playgroud)
AnimationTimer第三种(更复杂)技术(此处未显示)是使用AnimationTimerhandle ,每次调用计时器中的方法来更新场景时计算和调整节点的平移属性。此技术通常用于游戏循环或物理模型中,其中使用速度矢量对对象进行建模,速度矢量根据重力、碰撞和弹跳等物理属性更新其位置。
| 归档时间: |
|
| 查看次数: |
90 次 |
| 最近记录: |