java 如何使用路径转换方法使节点绕圆旋转?

2nbm6dog  于 12个月前  发布在  Java
关注(0)|答案(1)|浏览(98)

我正在尝试重建玻尔原子模型,此时我已经设法让电子相对于轨道中的电子总数有一个适当的位置,但现在我正在努力使它们围绕所述轨道旋转。而不是让它们绕着它旋转。
好的,我有这个节点:

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

63lcw9qa

63lcw9qa1#

您可以:

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

字符串

在路径上定位节点

如果要调整环绕的起点,可以在播放环绕器动画之前应用以下行,并根据需要在0与1之间调整除数。

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


这将允许您将节点放置在任意路径上的任意位置(即使您没有沿路径设置动画)。

定位节点

对于圆与球体(如此处示例中的那些),您不会注意到节点方向,但对于非对称节点,您可能希望确定节点的方向,使其指向放置在路径上或沿着路径移动时所需的方向。

3D场景中的路径动画

同样的技术也适用于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);
    }
}

使用AnimationTimer

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

相关问题