我的任务是为生成图形的 STL 模型的图形绘制程序编写基于 python 的插件。图是由顶点和边组成的对象,其中顶点由 3D 球(镶嵌二十面体)表示,边由两端连接两个球的圆柱体表示。3D 模型的最终结果是将其转储到 STL 文件中以进行 3D 打印。我能够毫无问题地生成球和圆柱体的 3D 模型,但是在生成整体模型以及让球和圆柱体正确连接时遇到了一些问题。
我最初的想法是在原点创建镶嵌二十面体,然后将它们转换为顶点的位置。这工作正常。然后,对于每条边,我会在原点创建一个圆柱体,将其旋转到正确的角度,使其指向正确的方向,然后将其平移到两个顶点之间的中点,以便嵌入圆柱体的末端在二十面体中。这就是事情出错的地方。我在正确旋转时遇到了一些困难。为了计算旋转,我正在执行以下操作:
首先,我找到两点之间的角度如下(其中源和目标都是图中的顶点,属于我当前正在处理的边):
deltaX = source.x - target.x
deltaY = source.y - target.y
deltaZ = source.z - target.z
xyAngle = math.atan2(deltaX, deltaY)
xzAngle = math.atan2(deltaX, deltaZ)
yzAngle = math.atan2(deltaY, deltaZ)
计算的角度看起来很合理,据我所知,它实际上代表了顶点之间的角度。例如,如果我在 (1, 1, 0) 处有一个顶点,在 (3, 3, 0) 处有另一个顶点,则连接它们的角边确实显示为两个顶点之间的 45 度角。(那个,或 -135 度,取决于哪个顶点是源,哪个是目标)。
计算完角度后,我创建一个圆柱体并按已计算的角度旋转它,就像这样,使用我创建的其他一些类: c = cylinder() c.createCylinder(edgeThickness, edgeLength)
c.rotateX(-yzAngle)
c.rotateY(xzAngle)
c.rotateZ(-xyAngle)
c.translate(edgePosition.x, edgePosition.y, edgePosition.z)
(其中 edgePosition 是图中两个顶点之间的中点,edgeThickness 是正在创建的圆柱体的半径,edgeLength 是两个顶点之间的距离)。
如前所述,气缸的旋转没有按预期工作。它似乎在 x/y 平面上进行了正确的旋转,但是一旦边的顶点在所有三个分量(x、y 和 z)中都不同,旋转就会失败。这是一个 x 和 y 分量不同但 z 分量不同的图形示例:
这是生成的 STL 文件,如 Makerware 中所示(用于将 3D 模型发送到 3D 打印机):
(左下角的额外圆柱体是我目前为了测试目的而留下的——一个指向 z 轴方向的圆柱体,位于原点)。
如果我采用同一张图并将中间顶点在 z 轴上移出,那么现在所有边都涉及所有三个轴上的角度,我得到如下结果:
如应用程序所示:
生成的 STL 文件,如 Makerware 中所示:
...以及从侧面看的相同模型:
正如你所看到的,圆柱体肯定没有像我想象的那样与球相遇。我的问题是:我做这件事的方法是有缺陷的,还是我在轮换的某个地方犯了一些小但关键的错误?我很确定旋转功能本身没有问题,因为我已经能够独立验证它们是否按预期工作。我还尝试创建一个旋转函数,该函数接受偏航、俯仰和滚动并同时执行所有三项,它似乎生成了相同的结果,如下所示:
c.rotateYawPitchRoll(xzAngle, -yzAngle, -xyAngle)
所以......有人对我可能做错了什么有任何想法吗?
更新:正如 joojaa 指出的那样,它是计算正确角度以及应用它们的顺序的组合。为了让事情正常进行,我首先计算 x 轴上的旋转,如下所示:
zyAngle = math.atan2(deltaVector.z, deltaVector.y)
其中 deltaVector 是目标向量和源向量之间的差异。但是,此轮换尚未应用!下一步是计算y轴上的旋转,如下:
angle = vector.angleBetweenVectors(vector(target.x - source.x, target.y - source.y, target.z - source.z), vector(target.x - source.x, target.y - source.y, 0.0))
一旦计算了两个旋转,它们就会被应用......以相反的顺序!首先是 x,然后是 y:
c.rotateY(angle)
c.rotateX(-zyAngle) #... where c is a cylinder object
似乎仍然存在一些错误,但这似乎至少适用于一个简单的测试用例。