如何旋转的Java 3D对象?(How to rotate an object in Java 3D

2019-08-02 13:11发布

我有一个圆锥我的Java 3D画了下面的代码:

Cone cone = new Cone(2f, 3f);

Transform3D t3d = new Transform3D();
TransformGroup coneTransform = new TransformGroup(t3d);
coneTransform.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

t3d.setTranslation(new Vector3f(0f,0f,0f);
coneTransform.setTransform(t3d);
coneTransform.addChild(cone);

this.addChild(coneTransform);

假设我有锥坐在点(1,1,1)和我想要的锥尖点下去的假想线通过(0,0,0)和(1,1,1)运行...如何我能做到这一点?

这里是什么,我一直在努力的例子:

Transform3D t3d = new Transform3D();  

Vector3f direction = new Vector3f(1,2,1);    

final double angleX = direction.angle(new Vector3f(1,0,0));
final double angleY = direction.angle(new Vector3f(0,1,0));
final double angleZ = direction.angle(new Vector3f(0,0,1));

t3d.rotX(angleX);
t3d.rotY(angleY);
t3d.rotZ(angleZ);

t3d.setTranslation(direction);

coneTransform.setTransform(t3d);

预先感谢所有帮助!

Answer 1:

我只是学习Java 3D我的那一刻,从我目前的知识,旋转方法设置的转换为只关于轴旋转。 因此,如果要执行围绕多个轴旋转,那么你就需要使用第二的Transform3D。
即:

Transform3D rotation = new Transform3D();
Transform3D temp = new Transform3D();

rotation.rotX(Math.PI/2);
temp.rotZ(Math.PI/2);
rotation.mul(temp); // multiply the 2 transformation matrices together.

至于Math.PI的原因,这是因为它使用弧度,而不是度,其中Math.PI相当于180度。

寻找你的当前方向和你预期的方向之间的角度是不是太辛苦 - 你可以使用Vector3fs,用角()方法。 一个Vector将设立与初始方向,另一个预期。 然而,这并不能告诉你哪些轴的角度谎言。 这样做需要的载体的检查,看哪些段设置。 [当然,也有可能是我目前知道的API的东西]



Answer 2:

这不是一个Java3D的具体的答案。

一般而言,基质可以构建为使得有描述它4层的载体。

1)A面(或侧)载体
2)向上矢量
3)的方向矢量
4)一种位置

4x4矩阵中的每一行。

因此,对于我们有以下的矩阵一个简单的身份矩阵(我会定义列主要矩阵,对于行的主要基质,所有你需要做的就是围绕掉这样的矩阵指数即行2列3成为整个排(3,2)矩阵)。

1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

在此,第一列是侧向量。 第二列中的向上矢量。 第三方向和所述第四位置。

从逻辑上讲,我们可以看到,矢量(1,0,0,0)沿x轴点(并且因此是侧向量)。 矢量(0,1,0,0)沿y轴的点(并因此是向上矢量)。 第三个(0,0,1,0)沿Z轴的点(并因此是方向矢量)。 第四个(0,0,0,1),表示该对象不移动的。

现在让我们说,我们要沿着X轴面对的问题。

显然,这将意味着,我们有(1,0,0,0),我们的方向向量的向量。 截至仍然是(0,1,0,0)和位置仍为0,0,0 1,所以将我们身边载体是什么呢? 那么,从逻辑上讲,将沿Z轴点。 但是,哪一种方式? 办好你的手指,使得一个手指点着,一到一边,一升起来。 现在旋转,使得前指部也面临同样的方向一侧指着手指。 哪种方式现在是指着一边指着手指? 相反的方向与原始方向指向手指。 因此,该基体是

 0 0 1 0
 0 1 0 0
-1 0 0 0
 0 0 0 1

这时,事情似乎变得有点复杂。 这是很简单的采取的任意位置和任意角度去看待(我会打电话给他们VPOS和vFocus)。 它是很容易通过从vFocus减去VPOS以形成从VPOS到vFocus向量(vFocus.x - vPos.x,vFocus.y - vPos.y,vFocus.z - vPos.z,vFocus.w - vPos.w) 。 请记住所有的位置应该用“1”在W位置四面八方应该有一个“0”定义。 这是自动的照顾,当你做上面两个WS 1将抵消并留下0反正减法,我们现在已经使vFocus我们就叫它VDIR的位置的矢量指向。 不幸的是,有VPOS和vFocus之间的差异的长度。 然而,如果我们通过其长度(vDir.x /长度,vDir.y /长度,vDir.z /长度,vDir.w /长度)除以VDIR矢量然后我们正常化它,我们有以1:1的总长度的方向。

在这个ponit我们现在有我们的第三和我们的矩阵的第四列。 现在,让我们assuem起来仍是(0,1,0,0)或VUP。 我们可以假设,方向和VUP的交叉积将产生一个矢量,即(单元的长度,并且也)垂直于由VDIR和VUP形成的平面。 这为我们提供了我们的身边载体或VLAT。 现在..我们没有那种承担了矢量所以它不是完全正确。 现在,我们可以精确地采取VLAT和VDIR的交叉乘积计算的话,我们有所有4个载体。

因此,最终的矩阵定义如下

vLat.x vUp.x vDir.x vPos.x
vLat.y vUp.y vDir.y vPos.y
vLat.z vUp.z vDir.z vPos.z
vLat.w vUp.w vDir.w vPos.w

这不是严格完整的答案,你会得到问题,你对靠近你的(0,1,0,0)向量的点看,但应该在大多数情况下工作。



Answer 3:

我终于想通了什么,我想用四元数,这是我了解这里做: http://www.cs.uic.edu/~jbell/Courses/Eng591_F1999/outline_2.html这里是我的解决方案。

创建圆锥:

 private void attachCone(float size) {
        Cone cone = new Cone(size, size* 2);

        // The group for rotation
        arrowheadRotationGroup = new TransformGroup();
        arrowheadRotationGroup.
             setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        arrowheadRotationGroup.addChild(cone);

        // The group for positioning the cone
        arrowheadPositionGroup = new TransformGroup();
        arrowheadPositionGroup. 
              setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        arrowheadPositionGroup.addChild(arrowheadRotationGroup);

        super.addChild(arrowheadPositionGroup);
    }

现在,当我要旋转的锥体中指定为从点(0,0,0)至(direction.x,direction.y,direction.z)矢量某一方向指向,我使用:

private final Vector3f yAxis = new Vector3f(0f, 1f, 0f);
private Vector3f direction; 

private void rotateCone() {
        // Get the normalized axis perpendicular to the direction 
        Vector3f axis = new Vector3f();
        axis.cross(yAxis, direction);
        axis.normalize();

        // When the intended direction is a point on the yAxis, rotate on x
        if (Float.isNaN(axis.x) && Float.isNaN(axis.y) && Float.isNaN(axis.z)) 
        {
            axis.x = 1f;
            axis.y = 0f;
            axis.z = 0f;
        }
        // Compute the quaternion transformations
        final float angleX = yAxis.angle(direction);
        final float a = axis.x * (float) Math.sin(angleX / 2f);
        final float b = axis.y * (float) Math.sin(angleX / 2f);
        final float c = axis.z * (float) Math.sin(angleX / 2f);
        final float d = (float) Math.cos(angleX / 2f);

        Transform3D t3d = new Transform3D();
        Quat4f quat = new Quat4f(a, b, c, d);
        t3d.set(quat);
        arrowheadRotationGroup.setTransform(t3d);

        Transform3D translateToTarget = new Transform3D();
        translateToTarget.setTranslation(this.direction);
        arrowheadPositionGroup.setTransform(translateToTarget);
    }


Answer 4:

我想,这应该这样做:

coneTransform.rotX(Math.PI / 4);
coneTransform.rotY(Math.PI / 4);


Answer 5:

你可以给你的Transform3D旋转矩阵。 你可以使用旋转矩阵计算器网上一个旋转矩阵: http://toolserver.org/~dschwen/tools/rotationmatrix.html这里是我的例子:

    Matrix3f mat = new Matrix3f(0.492403876506104f, 0.586824088833465f,
            -0.642787609686539f, 0.413175911166535f, 0.492403876506104f,
            0.766044443118978f, 0.766044443118978f, -0.642787609686539f, 0f);

    Transform3D trans = new Transform3D();

    trans.set(mat);


文章来源: How to rotate an object in Java 3D?