围绕Java3D中的特定点旋转
Rotate around specific point in Java3D
我有一个应用程序,其中所有场景对象都是从 .obj
文件加载的(它们是从 Blender 导出的)。我需要围绕特定点旋转其中一个对象。目前,我有以下代码:
public void rotateTo() {
// translate to origin, rotate, translate back
Vector3f origin = new Vector3f();
Vector3f pivot = new Vector3f(.0f, .5f, .0f);
this.getTransform(this.transform);
this.transform.get(origin);
double angle = -Math.PI / 2;
double newX = origin.getX() + Math.cos(angle) * (pivot.getX() - origin.getX()) - Math.sin(angle) * (pivot.getY() - origin.getY());
double newY = origin.getY() + Math.sin(angle) * (pivot.getX() - origin.getX()) + Math.cos(angle) * (pivot.getY() - origin.getY());
this.transform.set(new Vector3f((float)newX, (float)newY, .0f), 0.15f);
this.setTransform(this.transform);
this.transform.set(origin, 0.15f);
this.setTransform(this.transform);
}
其中this
指的是我需要旋转的TransformGroup
对象,this.transform
指的是Transform3D
对象。
但是这个方法并没有达到我的预期效果。我也尝试了 this and this 解决方案,但它们也不适合我。
我想,或许可以在 GeometryArray
的帮助下尝试执行此操作,但我不明白如何执行此操作。此外,我可以尝试导出具有不同原点的对象,但我认为这不是一个干净的解决方案,因为那样我就需要使用代码将它们移动到正确的位置。
这是我的对象:
我试图围绕绿点旋转它,但在所有情况下它都围绕红点旋转,或者根本不旋转,或者平移到某个点而不旋转。
P.S。我知道,Java3D 是一个古老的库,可以使用更强大的工具,但这是我大学教授的要求,我不能拒绝使用它。
变换的组合可以使用矩阵乘法来实现。下面是一个将立方体绕 X 轴旋转 180° 的示例,轴心位于其顶面的中心。
题目中提到的三个步骤:平移使轴心在原点,旋转,平移回来。注释掉步骤以查看发生了什么。
所有步骤都被注释掉后,方框出现在中心,红色的一面朝前。
取消第一步的注释。方框向下移动,使其顶部位于屏幕中央。
取消注释第二步。盒子绕 X 轴(左右轴,通过盒子的顶部)旋转。绿色的一面现在朝前,盒子的底部现在位于屏幕中央。
取消注释第三步。盒子向上移动,整体效果是它通过顶面绕左右轴旋转。
将变换T应用于向量v定义为T*v 在 Java 3D 中,所以两个变换的组合 T 和 U 其中 T首先要完成 U 然后要完成的是 U*T。注意顺序是如何颠倒的。一般来说,变换的组合 T1, T2, ..., Tn 其中 T1 先完成,Tn 最后完成是 Tn*...*T2*T1.
这可以使用以下模式在 Java 3D 中表示:
Transform3D t1 = ..., t2 = ..., t3 = ...;
// first do t1, then t2, then t3
Transform3D all = new Transform3D(); // all = identity
all.mul(t1, all); // all = t1 * all
all.mul(t2, all); // all = t2 * all
all.mul(t3, all); // all = t3 * all
// now all == t3 * t2 * t1
Transform3D.set(Vector3d,double)
和 TransformGroup.setTransform()
等方法会覆盖现有转换而不是与其组合,这是您的代码不起作用的原因之一。
我发现这篇文章 http://www.developer.com/java/other/article.php/3717101/Understanding-Transforms-in-Java-3D.htm 很有帮助。
// based on http://www.java3d.org/starting.html
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.SimpleUniverse;
import javax.media.j3d.*;
import javax.vecmath.*;
public class Demo
{
public Demo() {
SimpleUniverse universe = new SimpleUniverse();
BranchGroup group = new BranchGroup();
group.addChild(createModel());
universe.getViewingPlatform().setNominalViewingTransform();
universe.addBranchGraph(group);
}
Node createModel() {
double radius = 0.3;
ColorCube cube = new ColorCube(radius);
// rotation of cube about the center of the top face
// i.e. the point (x=0, y=radius, z=0)
Transform3D transform = new Transform3D();
// step 1: translate cube down so that (0, radius, 0) is at the origin
Transform3D translate1 = new Transform3D();
translate1.setTranslation(new Vector3d(0.0, -radius, 0.0));
transform.mul(translate1, transform);
// step 2: rotate cube about X axis by 180 degrees
Transform3D rotate = new Transform3D();
rotate.rotX(Math.PI);
transform.mul(rotate, transform);
// step 3: translate cube back up
Transform3D translate2 = new Transform3D();
translate2.setTranslation(new Vector3d(0.0, +radius, 0.0));
transform.mul(translate2, transform);
// create a TransformGroup
TransformGroup tg = new TransformGroup();
tg.setTransform(transform);
tg.addChild(cube);
return tg;
}
public static void main(String[] args) {
new Demo();
}
}
我有一个应用程序,其中所有场景对象都是从 .obj
文件加载的(它们是从 Blender 导出的)。我需要围绕特定点旋转其中一个对象。目前,我有以下代码:
public void rotateTo() {
// translate to origin, rotate, translate back
Vector3f origin = new Vector3f();
Vector3f pivot = new Vector3f(.0f, .5f, .0f);
this.getTransform(this.transform);
this.transform.get(origin);
double angle = -Math.PI / 2;
double newX = origin.getX() + Math.cos(angle) * (pivot.getX() - origin.getX()) - Math.sin(angle) * (pivot.getY() - origin.getY());
double newY = origin.getY() + Math.sin(angle) * (pivot.getX() - origin.getX()) + Math.cos(angle) * (pivot.getY() - origin.getY());
this.transform.set(new Vector3f((float)newX, (float)newY, .0f), 0.15f);
this.setTransform(this.transform);
this.transform.set(origin, 0.15f);
this.setTransform(this.transform);
}
其中this
指的是我需要旋转的TransformGroup
对象,this.transform
指的是Transform3D
对象。
但是这个方法并没有达到我的预期效果。我也尝试了 this and this 解决方案,但它们也不适合我。
我想,或许可以在 GeometryArray
的帮助下尝试执行此操作,但我不明白如何执行此操作。此外,我可以尝试导出具有不同原点的对象,但我认为这不是一个干净的解决方案,因为那样我就需要使用代码将它们移动到正确的位置。
这是我的对象:
我试图围绕绿点旋转它,但在所有情况下它都围绕红点旋转,或者根本不旋转,或者平移到某个点而不旋转。
P.S。我知道,Java3D 是一个古老的库,可以使用更强大的工具,但这是我大学教授的要求,我不能拒绝使用它。
变换的组合可以使用矩阵乘法来实现。下面是一个将立方体绕 X 轴旋转 180° 的示例,轴心位于其顶面的中心。
题目中提到的三个步骤:平移使轴心在原点,旋转,平移回来。注释掉步骤以查看发生了什么。
所有步骤都被注释掉后,方框出现在中心,红色的一面朝前。
取消第一步的注释。方框向下移动,使其顶部位于屏幕中央。
取消注释第二步。盒子绕 X 轴(左右轴,通过盒子的顶部)旋转。绿色的一面现在朝前,盒子的底部现在位于屏幕中央。
取消注释第三步。盒子向上移动,整体效果是它通过顶面绕左右轴旋转。
将变换T应用于向量v定义为T*v 在 Java 3D 中,所以两个变换的组合 T 和 U 其中 T首先要完成 U 然后要完成的是 U*T。注意顺序是如何颠倒的。一般来说,变换的组合 T1, T2, ..., Tn 其中 T1 先完成,Tn 最后完成是 Tn*...*T2*T1.
这可以使用以下模式在 Java 3D 中表示:
Transform3D t1 = ..., t2 = ..., t3 = ...;
// first do t1, then t2, then t3
Transform3D all = new Transform3D(); // all = identity
all.mul(t1, all); // all = t1 * all
all.mul(t2, all); // all = t2 * all
all.mul(t3, all); // all = t3 * all
// now all == t3 * t2 * t1
Transform3D.set(Vector3d,double)
和 TransformGroup.setTransform()
等方法会覆盖现有转换而不是与其组合,这是您的代码不起作用的原因之一。
我发现这篇文章 http://www.developer.com/java/other/article.php/3717101/Understanding-Transforms-in-Java-3D.htm 很有帮助。
// based on http://www.java3d.org/starting.html
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.SimpleUniverse;
import javax.media.j3d.*;
import javax.vecmath.*;
public class Demo
{
public Demo() {
SimpleUniverse universe = new SimpleUniverse();
BranchGroup group = new BranchGroup();
group.addChild(createModel());
universe.getViewingPlatform().setNominalViewingTransform();
universe.addBranchGraph(group);
}
Node createModel() {
double radius = 0.3;
ColorCube cube = new ColorCube(radius);
// rotation of cube about the center of the top face
// i.e. the point (x=0, y=radius, z=0)
Transform3D transform = new Transform3D();
// step 1: translate cube down so that (0, radius, 0) is at the origin
Transform3D translate1 = new Transform3D();
translate1.setTranslation(new Vector3d(0.0, -radius, 0.0));
transform.mul(translate1, transform);
// step 2: rotate cube about X axis by 180 degrees
Transform3D rotate = new Transform3D();
rotate.rotX(Math.PI);
transform.mul(rotate, transform);
// step 3: translate cube back up
Transform3D translate2 = new Transform3D();
translate2.setTranslation(new Vector3d(0.0, +radius, 0.0));
transform.mul(translate2, transform);
// create a TransformGroup
TransformGroup tg = new TransformGroup();
tg.setTransform(transform);
tg.addChild(cube);
return tg;
}
public static void main(String[] args) {
new Demo();
}
}