使用方向和轴旋转 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 对象的主要内容,如果未能解决你的问题,请参考以下文章