我正在try 重建玻尔原子模型,目前我已经设法让Electron 相对于轨道上的Electron 总数有一个合适的位置,但现在我很难让它们绕着这个轨道旋转. The problem I have is that the path transition makes them go from said places, towards the center of the orbital, instead of making them rotate around it.

好的,我有这样的 node :

 @FXML
private Circle orbital;
@FXML
private Circle Electron;
@FXML
private Circle Electron2;
@FXML
private Circle Electron3;

这就是应该让它们旋转的方法:

  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();
}

这就是我调用测试方法的方式:

  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);
   }
}

推荐答案

你可以:

  • 遵循一条路径,并使用这条路径用PathTransition度环绕某个物体.

2D场景中的路径动画

该2D示例演示了在时间轴中同时使用路径变换和旋转技术.

2d

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.或ANGERED
        );
        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);
    }
}

在路径上定位 node

如果要调整环游的起点,可以在播放轨道器动画之前应用以下行,根据需要调整0到1之间的除数.

orbiter.jumpTo(T.divide(.17));

这将允许您沿任意路径将 node 放置在任何位置(即使您没有沿路径设置动画).

确定 node 的方向

对于圆和球体(如此处示例中的圆和球体),您不会注意到 node 方向,但对于非对称 node ,您可能希望将 node 设置为orient,以使其在放置在路径上或沿路径移动时指向所需的方向.

3D场景中的路径动画

同样的技术也适用于3D场景中的动画对象.

3d

import javafx.animation.*;
import javafx.application.Application;
import javafx.geometry.Point3D;
import javafx.scene.*;
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) {
        Sphere sun = new Sphere(
                S/10
        );
        sun.setMaterial(new PhongMaterial(Color.或ANGERED));
        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);
    }
}

Using an AnimationTimer

第三种(更复杂的)技术(此处未显示)将设置为use an AnimationTimer,每次调用计时器中的handle方法以更新场景时,计算和调整 node 的平移属性.此技术通常用于游戏循环或物理模型中,其中使用速度向量对对象进行建模,速度向量根据重力、碰撞和反弹等物理属性更新其位置.

Java相关问答推荐

使用包私有构造函数强制子类Java类

Oracle DUAL表上使用DDL时jOOQ问题的解析'

工件部署期间出错[Tomcat 8.5.45]

我无法将附件发送到NetBeans之外

Java Swing:初始化身份验证类后未检测到ATM_Interface键事件

JavaFX Maven Assembly插件一直打包到错误的JDK版本

如何获得执行人?

从Spring5迁移到Spring6:无法在雅加达包中找到类

PDFBox未加载内容

如何使用Jackson将XML元素与值和属性一起封装

如何在Application.yaml中连接字符串?

如何将Java文档配置为在指定的项目根目录中生成?

Dijkstra搜索算法的实现

有谁能帮我修一下这个吗?使输出变得更加整洁

视图被推出线性布局-Android

循环不起作用只有第一个元素重复

在单例类上获取Java锁,了解原因

JavaFX中ListView中的问题

在JSON上获取反斜杠

从 Java 17 切换回 Java 8 后出现的问题