java – 如何为陀螺制作动画?

前端之家收集整理的这篇文章主要介绍了java – 如何为陀螺制作动画?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
它是光明节,我正在尝试动画陀螺(dreidel):

我可以让它在自己的轴上旋转.这是我的代码

  1. import static javafx.scene.paint.Color.*;
  2.  
  3. import javafx.animation.KeyFrame;
  4. import javafx.animation.KeyValue;
  5. import javafx.animation.Timeline;
  6. import javafx.application.Application;
  7. import javafx.beans.property.DoubleProperty;
  8. import javafx.beans.property.SimpleDoubleProperty;
  9. import javafx.geometry.Point3D;
  10. import javafx.scene.Camera;
  11. import javafx.scene.Group;
  12. import javafx.scene.PerspectiveCamera;
  13. import javafx.scene.Scene;
  14. import javafx.scene.SceneAntialiasing;
  15. import javafx.scene.paint.PhongMaterial;
  16. import javafx.scene.shape.Box;
  17. import javafx.scene.shape.Cylinder;
  18. import javafx.scene.shape.Sphere;
  19. import javafx.scene.transform.Rotate;
  20. import javafx.scene.transform.Translate;
  21. import javafx.stage.Stage;
  22. import javafx.util.Duration;
  23.  
  24. public class DreidelAnim extends Application {
  25.  
  26. private double bodyBase = 30;
  27. private double bodyHeight = bodyBase * 3 / 2;
  28. private double baseRadius = bodyBase / 2;
  29.  
  30. @Override
  31. public void start(Stage stage) throws Exception {
  32. DoubleProperty spinAngle = new SimpleDoubleProperty();
  33. Rotate spin = new Rotate(0,Rotate.Z_AXIS);
  34. spin.angleProperty().bind(spinAngle);
  35.  
  36. Timeline spinAnim = new Timeline(new KeyFrame(Duration.seconds(2),new KeyValue(spinAngle,360)));
  37. spinAnim.setCycleCount(Timeline.INDEFINITE);
  38. spinAnim.play();
  39.  
  40. Group dreidel = createDreidel();
  41. Translate zTrans = new Translate(0,-(bodyHeight/2 + baseRadius));
  42. dreidel.getTransforms().addAll(spin,zTrans);
  43.  
  44. Scene scene = new Scene(dreidel,200,true,SceneAntialiasing.BALANCED);
  45. scene.setFill(SKYBLUE);
  46. scene.setCamera(createCamera());
  47.  
  48. stage.setScene(scene);
  49. stage.show();
  50. }
  51.  
  52. private Group createDreidel() {
  53. double handleHeight = bodyBase * 3/4;
  54. Cylinder handle = new Cylinder(bodyBase / 6,handleHeight);
  55. handle.setTranslateZ(-(bodyHeight + handleHeight) / 2);
  56. handle.setRotationAxis(Rotate.X_AXIS);
  57. handle.setRotate(90);
  58. handle.setMaterial(new PhongMaterial(RED));
  59.  
  60. Box body = new Box(bodyBase,bodyBase,bodyHeight);
  61. body.setMaterial(new PhongMaterial(BLUE));
  62.  
  63. Sphere base = new Sphere(baseRadius);
  64. base.setTranslateZ(bodyHeight / 2);
  65. base.setMaterial(new PhongMaterial(GREEN));
  66.  
  67. return new Group(handle,body,base);
  68. }
  69.  
  70. private Camera createCamera() {
  71. PerspectiveCamera camera = new PerspectiveCamera(true);
  72. camera.setFarClip(1000);
  73.  
  74. int xy = 150;
  75. Translate trans = new Translate(-xy,xy,-120);
  76. Rotate rotXY = new Rotate(70,new Point3D(1,1,0));
  77. Rotate rotZ = new Rotate(45,new Point3D(0,1));
  78. camera.getTransforms().addAll(trans,rotXY,rotZ);
  79.  
  80. return camera;
  81. }
  82.  
  83. public static void main(String[] args) {
  84. launch();
  85. }
  86. }

我创建了一个简单的模型,围绕其轴旋转,并将其翻译为其尖端(0,0).结果如下:

如何才能实现与顶部图片类似的旋转轴旋转?

解决方法

物体旋转的轴的旋转称为 Precession.旋转顶部运动需要2次旋转:

>物体围绕其内轴旋转(与红色手柄平行).
>围绕静态轴旋转其中一个内部轴(在本例中为z).

从表面上看,你需要2个动画实例.但是,两个旋转实际上是相同的.两者的轴心点是(0,0)(在zTrans之后)并且它们都在z轴周围,只有一个以一定角度倾斜.

这是修改后的代码

  1. import static javafx.scene.paint.Color.*;
  2.  
  3. import javafx.animation.KeyFrame;
  4. import javafx.animation.KeyValue;
  5. import javafx.animation.Timeline;
  6. import javafx.application.Application;
  7. import javafx.beans.property.DoubleProperty;
  8. import javafx.beans.property.SimpleDoubleProperty;
  9. import javafx.geometry.Point3D;
  10. import javafx.scene.Camera;
  11. import javafx.scene.Group;
  12. import javafx.scene.PerspectiveCamera;
  13. import javafx.scene.Scene;
  14. import javafx.scene.SceneAntialiasing;
  15. import javafx.scene.paint.PhongMaterial;
  16. import javafx.scene.shape.Box;
  17. import javafx.scene.shape.Cylinder;
  18. import javafx.scene.shape.Sphere;
  19. import javafx.scene.transform.Rotate;
  20. import javafx.scene.transform.Translate;
  21. import javafx.stage.Stage;
  22. import javafx.util.Duration;
  23.  
  24. public class FinalDreidelSpin extends Application {
  25.  
  26. private double bodyBase = 30;
  27. private double bodyHeight = bodyBase * 3 / 2;
  28. private double baseRadius = bodyBase / 2;
  29.  
  30. @Override
  31. public void start(Stage stage) throws Exception {
  32. double tiltAngle = 40;
  33. DoubleProperty spinAngle = new SimpleDoubleProperty();
  34.  
  35. Rotate spin = new Rotate(0,Rotate.Z_AXIS);
  36. Rotate tilt = new Rotate(tiltAngle,Rotate.X_AXIS);
  37.  
  38. spin.angleProperty().bind(spinAngle);
  39.  
  40. Timeline spinAnim = new Timeline();
  41. spinAnim.getKeyFrames().add(new KeyFrame(Duration.seconds(2),tilt,spin,zTrans);
  42.  
  43. Scene scene = new Scene(new Group(dreidel,createAxes()),-100);
  44. Rotate rotXY = new Rotate(70,rotZ);
  45.  
  46. return camera;
  47. }
  48.  
  49. private Group createAxes() {
  50. int axisWidth = 1;
  51. int axisLength = 400;
  52.  
  53. Cylinder xAxis = new Cylinder(axisWidth,axisLength);
  54. xAxis.setMaterial(new PhongMaterial(CYAN));
  55.  
  56. Cylinder yAxis = new Cylinder(axisWidth,axisLength);
  57. yAxis.setRotationAxis(Rotate.Z_AXIS);
  58. yAxis.setRotate(90);
  59. yAxis.setMaterial(new PhongMaterial(MAGENTA));
  60.  
  61. Cylinder zAxis = new Cylinder(axisWidth,axisLength);
  62. zAxis.setRotationAxis(Rotate.X_AXIS);
  63. zAxis.setRotate(90);
  64. zAxis.setMaterial(new PhongMaterial(YELLOW));
  65.  
  66. return new Group(xAxis,yAxis,zAxis);
  67. }
  68.  
  69. public static void main(String[] args) {
  70. launch();
  71. }
  72. }

添加了轴表示以方便查看.请注意,getTransforms()列表不要求其对象是唯一的(与getChildren()不同),这允许我们重用相同的动画.如下所述,动画的顺序也很重要.

倾斜是围绕x或y轴的简单旋转.
如果我们倾斜然后旋转,getTransforms().addAll(tilt,zTrans),我们将得到内部旋转(上面列出的1),只是倾斜:

如果我们旋转然后倾斜,getTransforms().addAll(spin,我们就会得到进动(上面列出的2):

在完整代码中组合2将得到所需的结果:

猜你在找的Java相关文章