在Java3D中围绕特定点旋转

在Java3D中围绕特定点旋转,java,3d,rotation,java-3d,Java,3d,Rotation,Java 3d,我有一个应用程序,其中所有场景对象都是从.obj文件加载的(它们是从Blender导出的)。我需要绕着特定点旋转其中一个物体。目前,我有以下代码: public void rotateTo() { // translate to origin, rotate, translate back Vector3f origin = new Vector3f(); Vector3f pivot = new Vector3f(.0f, .5f, .0f); this.g

我有一个应用程序,其中所有场景对象都是从
.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
对象

但是这个方法并不像我预期的那样有效。我也尝试了一些解决方案,但它们对我也不起作用

我想,也许可以尝试在
GeometryArray
的帮助下执行此操作,但我不明白如何执行此操作。此外,我可以尝试导出具有不同原点的对象,但我认为这不是一个干净的解决方案,因为这样我就需要使用代码将它们移动到正确的位置

这是我的目标:

我试图围绕绿点旋转它,但在所有情况下,它都围绕红点旋转,或者根本不旋转,或者平移到某个点而不旋转


另外,我知道Java3D是一个古老的库,可以使用更强大的工具,但这是我大学教授的要求,我不能拒绝使用它。

可以使用矩阵乘法实现变换的合成。下面的示例将立方体绕X轴旋转180°,枢轴位于其顶面的中心

问题中提到了三个步骤:平移使轴位于原点、旋转和向后平移。注释出步骤以查看发生了什么

  • 注释掉所有步骤后,方框显示在中心,红色面朝前

  • 取消注释第一步。盒子向下移动,使其顶部位于屏幕的中心

  • 取消对第二步的注释。长方体绕X轴旋转(通过长方体顶部的左右轴)。绿色的一面现在朝前,盒子的底部现在位于屏幕的中心

  • 取消注释第三步。长方体向上移动,整体效果是它通过顶面绕左右轴旋转

在Java 3D中,对向量v的变换T的应用被定义为T*v,因此两个变换T和U的组合是U*T,其中T首先完成,U其次完成。请注意顺序是如何颠倒的。一般来说,变换T1,T2,…,Tn的组合是Tn*…*T2*T1,其中T1首先完成,Tn最后完成

这可以使用以下模式在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()
这样的方法会覆盖现有的转换,而不是与之组合,这是代码无法工作的原因之一

我觉得这篇文章很有帮助


现在一切都好了,非常感谢!我错过了,
set…
方法覆盖现有转换。
// 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();
  }
}