, @user1803551, , .
:

, net dreidel, :

.
, .
, TriangleMesh , 9 (3D-), 16 (2D) 14 , . width, - height. L = 4 * width, H = 2 * width + height.
, 0 0 - 2 - 1 8 - 3 - 7, 0 {width / 2, width / 2, width / 2}, 8 {width, 2 * width}, [0, 1]: {width / L, 2 * width / H}.


:
float width = 375f;
float height = 351f;
3D-:
class DreidelMesh extends Group {
float width = 375f;
float height = 351f;
public DreidelMesh(){
MeshView bodyMesh = new MeshView(createBodyMesh());
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(new Image(getClass().getResourceAsStream("3dreidel3d.png")));
bodyMesh.setMaterial(material);
Cylinder handle = new Cylinder(45, 260);
handle.setTranslateY(-(handle.getHeight() + width) / 2);
material = new PhongMaterial(Color.web("#daaf6d"));
handle.setMaterial(material);
getTransforms().add(new Rotate(90, Rotate.X_AXIS));
getChildren().addAll(bodyMesh, handle);
}
private TriangleMesh createBodyMesh() {
TriangleMesh m = new TriangleMesh();
float L = 4f * width;
float H = 2f * width + height;
float w2 = width / 2f;
m.getPoints().addAll(
w2, w2, w2,
w2, w2, -w2,
w2, -w2, w2,
w2, -w2, -w2,
-w2, w2, w2,
-w2, w2, -w2,
-w2, -w2, w2,
-w2, -w2, -w2,
0f, w2 + height, 0f
);
m.getTexCoords().addAll(
width / L, 0f,
2f * width/ L, 0f,
0f, width / H,
width / L, width / H,
2f * width/ L, width / H,
3f * width/ L, width / H,
1f, width / H,
0f, 2f * width / H,
width / L, 2f * width / H,
2f * width/ L, 2f * width / H,
3f * width/ L, 2f * width / H,
1f, 2f * width / H,
width / 2f / L, 1f,
3f * width / 2f / L, 1f,
5f * width / 2f / L, 1f,
7f * width / 2f / L, 1f
);
m.getFaces().addAll(
0, 8, 2, 3, 1, 7,
2, 3, 3, 2, 1, 7,
4, 9, 5, 10, 6, 4,
6, 4, 5, 10, 7, 5,
0, 8, 1, 7, 8, 12,
4, 9, 0, 8, 8, 13,
5, 10, 4, 9, 8, 14,
1, 11, 5, 10, 8, 15,
2, 3, 6, 4, 3, 0,
3, 0, 6, 4, 7, 1,
0, 8, 4, 9, 2, 3,
2, 3, 4, 9, 6, 4,
1, 11, 3, 6, 5, 10,
5, 10, 3, 6, 7, 5
);
return m;
}
}

, , ( ), :
@Override
public void start(Stage stage) {
double tiltAngle = 15;
DoubleProperty spinAngle = new SimpleDoubleProperty();
DoubleProperty precessionAngle = new SimpleDoubleProperty();
Rotate spin = new Rotate(0, Rotate.Z_AXIS);
Rotate precession = new Rotate(0, Rotate.Z_AXIS);
Rotate tilt = new Rotate(tiltAngle, Rotate.X_AXIS);
spin.angleProperty().bind(spinAngle);
precession.angleProperty().bind(precessionAngle);
Timeline spinAnim = new Timeline();
spinAnim.getKeyFrames().add(new KeyFrame(Duration.seconds(1.5), new KeyValue(spinAngle, 360)));
spinAnim.setCycleCount(Timeline.INDEFINITE);
spinAnim.play();
Timeline precessionAnim = new Timeline();
precessionAnim.getKeyFrames().add(new KeyFrame(Duration.seconds(4), new KeyValue(precessionAngle, 360)));
precessionAnim.setCycleCount(Timeline.INDEFINITE);
precessionAnim.play();
Group dreidel = new Group(new DreidelMesh());
Translate zTrans = new Translate(0, 0, - dreidel.getBoundsInLocal().getMaxZ());
dreidel.getTransforms().addAll(precession, tilt, spin, zTrans);
Scene scene = new Scene(new Group(dreidel), 300, 300, true, SceneAntialiasing.BALANCED);
scene.setFill(SKYBLUE);
scene.setCamera(createCamera());
stage.setScene(scene);
stage.setTitle("JavaFX 3D - Dreidel");
stage.show();
}
, .