在Javafx中围绕中心旋转对象 [英] Rotate object around center in Javafx
问题描述
我的应用程序使用交互式网格库读取obj文件,并将其保存在meshview中。我想要的是围绕对象的中心旋转对象。
My application read obj file using interactive mesh library and save it it in meshview. What I want is to rotate the object around its center.
现在,我的代码显示了对象,但是当我旋转它时,它围绕某个点旋转,这导致了对象去窗外。我宁愿将对象绕其中心旋转。我知道我必须将对象平移到原点,然后旋转然后再次平移,但是我不知道该怎么做。
Right now my code displays the object but when I rotate it, it is rotated around some point which cause the object to go outside the window. I rather want to rotate the object around its center. I know I have to translate object to origin then rotate then translate again, but I don't know how to do.
这是我的代码:
public class JavaFx3DObj extends Application
{
private static final String Filename = "model/bunny.obj";
private static final double MODEL_SCALE_FACTOR = 10;
private static final double MODEL_X_OFFSET = 0; // standard
private static final double MODEL_Y_OFFSET = 0; // standard
private static final int VIEWPORT_SIZE = 800;
private double mouseOldX, mouseOldY = 0;
private Rotate rotateX = new Rotate(0, Rotate.X_AXIS);
private Rotate rotateY = new Rotate(0, Rotate.Y_AXIS);
private Rotate rotateZ = new Rotate(0, Rotate.Z_AXIS);
private Group root;
private Group buildScene()
{
File file = new File(Filename);
ObjModelImporter importer = new ObjModelImporter();
importer.read(file);
MeshView[] meshViews = importer.getImport();
importer.close();
// To make the object appear in the middle of the scene
for (MeshView meshView : meshViews)
{
meshView.setTranslateX(VIEWPORT_SIZE / 2 + MODEL_X_OFFSET);
meshView.setTranslateY(VIEWPORT_SIZE / 2 + MODEL_Y_OFFSET);
meshView.setTranslateZ(VIEWPORT_SIZE / 2);
meshView.setScaleX(MODEL_SCALE_FACTOR);
meshView.setScaleY(MODEL_SCALE_FACTOR);
meshView.setScaleZ(MODEL_SCALE_FACTOR);
}
root = new Group(meshViews);
return root;
}
@Override
public void start(Stage stage) throws Exception
{
Group root = buildScene();
PerspectiveCamera camera = new PerspectiveCamera(false);
camera.setTranslateX(100);
camera.setTranslateY(0);
camera.setTranslateZ(100);
camera.getTransforms().addAll (rotateX, rotateY, new Translate(0, 0, 400));
root.setRotationAxis(Rotate.Y_AXIS);
root.setRotate(200);
Scene scene = new Scene(root, 900, 500, true);
scene.setFill(Color.rgb(10, 10, 40));
scene.setCamera(camera);
scene.setOnMousePressed(event ->
{
mouseOldX = event.getSceneX();
mouseOldY = event.getSceneY();
});
scene.setOnMouseDragged(event ->
{
rotateX.setAngle(rotateX.getAngle() - (event.getSceneY() - mouseOldY));
rotateY.setAngle(rotateY.getAngle() + (event.getSceneX() - mouseOldX));
mouseOldX = event.getSceneX();
mouseOldY = event.getSceneY();
});
stage.setTitle("JavaFx3DObj");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
推荐答案
您需要做的是在应用旋转之前设置旋转的枢轴。
因此,您的代码如下所示:
What you need to do is set the pivot of the rotation before applying it. So your code looks like that:
public class JavaFx3DObj extends Application {
private static final String Filename = "model/bunny.obj";
private static final double MODEL_SCALE_FACTOR = 10;
private static final double MODEL_X_OFFSET = 0; // standard
private static final double MODEL_Y_OFFSET = 0; // standard
private static final int VIEWPORT_SIZE = 800;
private double mouseOldX, mouseOldY = 0;
private Rotate rotateX = new Rotate(0, Rotate.X_AXIS);
private Rotate rotateY = new Rotate(0, Rotate.Y_AXIS);
private Rotate rotateZ = new Rotate(0, Rotate.Z_AXIS);
private Group root;
private Group buildScene() {
File file = new File(Filename);
ObjModelImporter importer = new ObjModelImporter();
importer.read(file);
MeshView[] meshViews = importer.getImport();
importer.close();
// To make the object appear in the middle of the scene
for (MeshView meshView : meshViews) {
meshView.setTranslateX(VIEWPORT_SIZE / 2 + MODEL_X_OFFSET);
meshView.setTranslateY(VIEWPORT_SIZE / 2 + MODEL_Y_OFFSET);
meshView.setTranslateZ(VIEWPORT_SIZE / 2);
meshView.setScaleX(MODEL_SCALE_FACTOR);
meshView.setScaleY(MODEL_SCALE_FACTOR);
meshView.setScaleZ(MODEL_SCALE_FACTOR);
}
root = new Group(meshViews);
return root;
}
@Override
public void start(Stage stage) throws Exception {
Group root = buildScene();
PerspectiveCamera camera = new PerspectiveCamera(false);
camera.setTranslateX(100);
camera.setTranslateY(0);
camera.setTranslateZ(100);
camera.getTransforms().addAll (rotateX, rotateY, new Translate(0, 0, 400));
root.setRotationAxis(Rotate.Y_AXIS);
root.setRotate(200);
Scene scene = new Scene(root, 900, 500, true);
scene.setFill(Color.rgb(10, 10, 40));
scene.setCamera(camera);
//################ Set pivot points ################\\
rotateX.setPivotX(VIEWPORT_SIZE / 2 + MODEL_X_OFFSET);
rotateX.setPivotY(VIEWPORT_SIZE / 2 + MODEL_Y_OFFSET);
rotateX.setPivotZ(VIEWPORT_SIZE / 2);
rotateY.setPivotX(VIEWPORT_SIZE / 2 + MODEL_X_OFFSET);
rotateY.setPivotY(VIEWPORT_SIZE / 2 + MODEL_Y_OFFSET);
rotateY.setPivotZ(VIEWPORT_SIZE / 2);
rotateZ.setPivotX(VIEWPORT_SIZE / 2 + MODEL_X_OFFSET);
rotateZ.setPivotY(VIEWPORT_SIZE / 2 + MODEL_Y_OFFSET);
rotateZ.setPivotZ(VIEWPORT_SIZE / 2);
//################ End pivot points ################\\
scene.setOnMousePressed(event -> {
mouseOldX = event.getSceneX();
mouseOldY = event.getSceneY();
});
scene.setOnMouseDragged(event -> {
rotateX.setAngle(rotateX.getAngle() - (event.getSceneY() - mouseOldY));
rotateY.setAngle(rotateY.getAngle() + (event.getSceneX() - mouseOldX));
mouseOldX = event.getSceneX();
mouseOldY = event.getSceneY();
});
stage.setTitle("JavaFx3DObj");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
我只能用多维数据集对其进行测试,因为我这样做没有ObjLoader / ObjFile,但这应该可以让您绕一个点旋转。
I only could test it with a cube since I do not have the ObjLoader/ObjFile, but this should allow you to rotate around a single point.
当心。如果平移对象,则必须将枢轴点设置为新位置。
Watch out. If you translate the object, you have to set the pivot points to the new position.
这篇关于在Javafx中围绕中心旋转对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!