use*_*551 6 java animation javafx javafx-8 javafx-3d
它是光明节,我正在尝试动画陀螺(dreidel):
我可以让它在自己的轴上旋转.这是我的代码:
import static javafx.scene.paint.Color.*;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.geometry.Point3D;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.Cylinder;
import javafx.scene.shape.Sphere;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
import javafx.util.Duration;
public class DreidelAnim extends Application {
private double bodyBase = 30;
private double bodyHeight = bodyBase * 3 / 2;
private double baseRadius = bodyBase / 2;
@Override
public void start(Stage stage) throws Exception {
DoubleProperty spinAngle = new SimpleDoubleProperty();
Rotate spin = new Rotate(0, Rotate.Z_AXIS);
spin.angleProperty().bind(spinAngle);
Timeline spinAnim = new Timeline(new KeyFrame(Duration.seconds(2), new KeyValue(spinAngle, 360)));
spinAnim.setCycleCount(Timeline.INDEFINITE);
spinAnim.play();
Group dreidel = createDreidel();
Translate zTrans = new Translate(0, 0, -(bodyHeight/2 + baseRadius));
dreidel.getTransforms().addAll(spin, zTrans);
Scene scene = new Scene(dreidel, 200, 200, true, SceneAntialiasing.BALANCED);
scene.setFill(SKYBLUE);
scene.setCamera(createCamera());
stage.setScene(scene);
stage.show();
}
private Group createDreidel() {
double handleHeight = bodyBase * 3/4;
Cylinder handle = new Cylinder(bodyBase / 6, handleHeight);
handle.setTranslateZ(-(bodyHeight + handleHeight) / 2);
handle.setRotationAxis(Rotate.X_AXIS);
handle.setRotate(90);
handle.setMaterial(new PhongMaterial(RED));
Box body = new Box(bodyBase, bodyBase, bodyHeight);
body.setMaterial(new PhongMaterial(BLUE));
Sphere base = new Sphere(baseRadius);
base.setTranslateZ(bodyHeight / 2);
base.setMaterial(new PhongMaterial(GREEN));
return new Group(handle, body, base);
}
private Camera createCamera() {
PerspectiveCamera camera = new PerspectiveCamera(true);
camera.setFarClip(1000);
int xy = 150;
Translate trans = new Translate(-xy, xy, -120);
Rotate rotXY = new Rotate(70, new Point3D(1, 1, 0));
Rotate rotZ = new Rotate(45, new Point3D(0, 0, 1));
camera.getTransforms().addAll(trans, rotXY, rotZ);
return camera;
}
public static void main(String[] args) {
launch();
}
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个简单的模型,围绕它的轴旋转,然后翻译它以使其尖端打开(0, 0, 0).结果如下:
如何才能实现与顶部图片类似的旋转轴旋转?
物体旋转的轴的旋转称为进动.旋转顶部运动需要2次旋转:
从表面上看,你需要2个Animation实例.但是,两个旋转实际上是相同的.两者的枢轴点(0, 0, 0)(在zTrans)之后并且它们都围绕z轴,其中只有一个以一定角度倾斜.
这是修改后的代码:
import static javafx.scene.paint.Color.*;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.geometry.Point3D;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.Cylinder;
import javafx.scene.shape.Sphere;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
import javafx.util.Duration;
public class FinalDreidelSpin extends Application {
private double bodyBase = 30;
private double bodyHeight = bodyBase * 3 / 2;
private double baseRadius = bodyBase / 2;
@Override
public void start(Stage stage) throws Exception {
double tiltAngle = 40;
DoubleProperty spinAngle = new SimpleDoubleProperty();
Rotate spin = new Rotate(0, Rotate.Z_AXIS);
Rotate tilt = new Rotate(tiltAngle, Rotate.X_AXIS);
spin.angleProperty().bind(spinAngle);
Timeline spinAnim = new Timeline();
spinAnim.getKeyFrames().add(new KeyFrame(Duration.seconds(2), new KeyValue(spinAngle, 360)));
spinAnim.setCycleCount(Timeline.INDEFINITE);
spinAnim.play();
Group dreidel = createDreidel();
Translate zTrans = new Translate(0, 0, -(bodyHeight/2 + baseRadius));
dreidel.getTransforms().addAll(spin, tilt, spin, zTrans);
Scene scene = new Scene(new Group(dreidel, createAxes()), 200, 200, true, SceneAntialiasing.BALANCED);
scene.setFill(SKYBLUE);
scene.setCamera(createCamera());
stage.setScene(scene);
stage.show();
}
private Group createDreidel() {
double handleHeight = bodyBase * 3/4;
Cylinder handle = new Cylinder(bodyBase / 6, handleHeight);
handle.setTranslateZ(-(bodyHeight + handleHeight) / 2);
handle.setRotationAxis(Rotate.X_AXIS);
handle.setRotate(90);
handle.setMaterial(new PhongMaterial(RED));
Box body = new Box(bodyBase, bodyBase, bodyHeight);
body.setMaterial(new PhongMaterial(BLUE));
Sphere base = new Sphere(baseRadius);
base.setTranslateZ(bodyHeight / 2);
base.setMaterial(new PhongMaterial(GREEN));
return new Group(handle, body, base);
}
private Camera createCamera() {
PerspectiveCamera camera = new PerspectiveCamera(true);
camera.setFarClip(1000);
int xy = 150;
Translate trans = new Translate(-xy, xy, -100);
Rotate rotXY = new Rotate(70, new Point3D(1, 1, 0));
Rotate rotZ = new Rotate(45, new Point3D(0, 0, 1));
camera.getTransforms().addAll(trans, rotXY, rotZ);
return camera;
}
private Group createAxes() {
int axisWidth = 1;
int axisLength = 400;
Cylinder xAxis = new Cylinder(axisWidth, axisLength);
xAxis.setMaterial(new PhongMaterial(CYAN));
Cylinder yAxis = new Cylinder(axisWidth, axisLength);
yAxis.setRotationAxis(Rotate.Z_AXIS);
yAxis.setRotate(90);
yAxis.setMaterial(new PhongMaterial(MAGENTA));
Cylinder zAxis = new Cylinder(axisWidth, axisLength);
zAxis.setRotationAxis(Rotate.X_AXIS);
zAxis.setRotate(90);
zAxis.setMaterial(new PhongMaterial(YELLOW));
return new Group(xAxis, yAxis, zAxis);
}
public static void main(String[] args) {
launch();
}
}
Run Code Online (Sandbox Code Playgroud)
我添加了轴表示以方便查看.请注意,getTransforms()列表不要求其对象是唯一的(不像getChildren()),这允许我们重用相同的动画.如下所述,动画的顺序也很重要.
倾斜是围绕x或y轴的简单旋转.
如果我们tilt然后spin,getTransforms().addAll(tilt, spin, zTrans)我们将得到内部旋转(上面列出的1),只倾斜:
如果我们spin然后tilt,getTransforms().addAll(spin, tilt, zTrans)我们将获得进动(上面列出的2):
在完整代码中组合2将得到所需的结果:
| 归档时间: |
|
| 查看次数: |
305 次 |
| 最近记录: |