使用方向和轴旋转 3D 对象

Posted

技术标签:

【中文标题】使用方向和轴旋转 3D 对象【英文标题】:Rotate 3D object with Direction and Axis 【发布时间】:2012-12-11 12:19:55 【问题描述】:

我正致力于在 Java3D 中显示 3D 模型 (IFC)。我需要用 IFC 模型给出的 2 个向量、一个方向向量和一个轴向量来旋转对象。

但我不知道如何获得正确的角度。

代码:

// Create vectors
Vector3f directionVector = new Vector3f(dx, dy, dz);
Vector3f axisVector = new Vector3f(ax, ay, az);

//Calculate angle
float angle = axisVector.angle(directionVector);

//create AxisAngle4f
AxisAngle4f axisAngle = new AxisAngle4f(axisVector, angle);

axisVector 总是 (0.0, 0.0, 1.0),所以需要在 Z 轴上旋转

但是当我计算角度时,它似乎总是 1.5707964 (90°):

Example 1:
dir:    (-1.0, 0.0, 0.0)
axis:   (0.0, 0.0, 1.0)
angle:  1.5707964 (90.00000250447816)
AA:     (0.0, 0.0, 1.0, 1.5707964)

Example 2:
dir:    (0.0, 1.0, 0.0)
axis:   (0.0, 0.0, 1.0)
angle:  1.5707964 (90.00000250447816)
AA:     (0.0, 0.0, 1.0, 1.5707964)

Example 3:
dir:    (1.0, 0.0, 0.0)
axis:   (0.0, 0.0, 1.0)
angle:  1.5707964 (90.00000250447816)
AA:     (0.0, 0.0, 1.0, 1.5707964)

我通过测试知道 -1.0 表示倒转 180°。

谁能帮我理解我做错了什么?

编辑

Documentation 用于放置对象(方向和轴)

结果截图:

橙色:是地板 绿色:是屋顶 红色:是旋转点 左:侧面透视 右图:俯视图 3个slab的组有方向方向(0.0,1.0,0.0) 2个slab的组有direction方向(1.0,0.0,0.0) 屋顶方向:(-1.0, 0.0, 0.0)

我做了 *2 测试来模拟 -1.0 的 180°。正如您在上一个示例中看到的那样,屋顶被正确绘制。

【问题讨论】:

【参考方案1】:

您不需要方向向量和轴向量之间的角度。由于您的轴向量始终为 (0.0, 0.0, 1.0),因此您可以定义一个 (1.0, 0.0, 0.0) 的常量向量,您可以将其与方向向量进行比较,即:

// Create vectors
Vector3f directionVector = new Vector3f(dx, dy, dz);
Vector3f axisVector = new Vector3f(ax, ay, az);
Vector3f constantBaseVector = new Vector3f(1, 0, 0);

//Calculate angle
float angle = constantBaseVector.angle(directionVector);

//create AxisAngle4f
AxisAngle4f axisAngle = new AxisAngle4f(axisVector, angle);

【讨论】:

但是 baseVector (1, 0, 0) 仅在 z 轴为 (0, 0, 1) 时才有效。所以它现在可以工作了,谢谢。【参考方案2】:

每个轴之间的角度应为 90°,计算任意两个向量之间的角度只会给出 0° - 180° 范围内的值,而不是您需要的 360°。

另外,如果 zAxis 不是 (0, 0, 1),那么您需要计算旋转轴以及角度。

相反,您可以从 3 个轴方向创建一个旋转矩阵,并从中创建一个变换对象。 y 轴是 x 和 z 轴的叉积:

// Given xAxis and zAxis.
Vector3f xAxis = new Vector3f(1, 0, 0);
Vector3f zAxis = new Vector3f(0, 0, 1);

// Create yAxis.
Vector3f yAxis = new Vector3f();
yAxis.cross(zAxis, xAxis);

// Create rotation matrix from axes.
Matrix4f rotationMatrix = new Matrix4f();
rotationMatrix.setRow(0, new Vector4f(xAxis));
rotationMatrix.setRow(1, new Vector4f(yAxis));
rotationMatrix.setRow(2, new Vector4f(zAxis));
rotationMatrix.setRow(3, new Vector4f(0, 0, 0, 1));

// Create transform.
Transform3D transform = new Transform3D(rotationMatrix);

// Transform points.
Vector3f vector = new Vector3f(0, 1, 0);
transform.transform(vector);
System.out.println(vector);

【讨论】:

【参考方案3】:

我猜axisVector.angle(directionVector) 返回两个向量之间的角度。

在您的所有三个示例中,您将基轴上的单位向量与 z 轴的单位向量进行比较,根据定义,它们相互垂直。你期望得到什么?

对我来说,-x 和 z 之间的角度是 90°,y 和 z 之间的角度是 90°,x 和 z 之间的角度是 90°。所以所有的数据都是正确的,你期望得到什么?

编辑:

示例一:(-1, 0, 0) 和 (0, 0, 1) 之间的角度 = 90° 示例二: (0, 1, 0) 和 (0, 0, 1) 之间的角度 = 90° 示例三:(1, 0, 0) 和 (0, 0, 1) 之间的夹角 = 90°

请在笛卡尔坐标系中绘制这些向量,并且应该清楚。另外请注意,两个向量之间的角度是这两个向量定义的平面上的最小角度。

【讨论】:

据我所知,我希望 1.0 为 90°,-1.0 为 180°。至于方向向量中 x 和 y 的区别我不知道。我将通过一些指向有关此主题的 Ifc 文档的链接来更新我的问题。 请看我上面的编辑。另外,请详细说明 1.0 和 -1.0 的含义(这些是标量值,而不是向量)。 我已经用我的结果截图更新了我的问题。谢谢你帮助我。

以上是关于使用方向和轴旋转 3D 对象的主要内容,如果未能解决你的问题,请参考以下文章

旋转其中一个后,如何将两个对象移动到同一方向?

CSS进阶知识点--3D转换及perspective 属性

如何旋转对象沿着矢量Unity3D指向

在 Unity 3D 中旋转对象

使用 Three.js 将 3D 对象旋转到鼠标

Java OpenGL - 如何使对象随相机旋转?