我一直在负责编写一个基于Python的插件生成的图表的STL模型的图形绘图程序。 作为一个对象的曲线图由顶点和边,其中一个顶点由3D球(的镶嵌二十面体)所表示的,和边缘为代表,在任一端的两个球连接的圆筒。 3D模型的最终结果是,它会被人抛弃了为3D打印的STL文件。 我能够生成用于球和气缸没有任何问题的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 =汽缸(c.createCylinder(edgeThickness,其边缘)
c.rotateX(-yzAngle)
c.rotateY(xzAngle)
c.rotateZ(-xyAngle)
c.translate(edgePosition.x, edgePosition.y, edgePosition.z)
(其中edgePosition是图中的两个顶点之间的中点,edgeThickness是被创建的圆柱体的半径,并且其边缘是这两个顶点之间的距离)。
如前所述,其预期不工作气缸的旋转。 这似乎做的X / Y平面内的正确的旋转,但只要边缘具有在所有三个分量(x,y和z)不同顶点,旋转失败。 下面是在x的不同的曲线图,和y分量的一个例子,而不是在z分量:
而这里的产生STL文件,如Makerware(这是用来3D模型发送到3D打印机)所示:
(左下方额外缸找位是什么目前我已经离开了在用于测试目的 - 在z轴,位于原点的方向指向一缸)。
如果我采取相同的图形和移动中间顶点出在Z轴,所以现在所有的边缘在所有三个轴涉及的角度,我得到的结果类似如下:
作为显示在应用程序:
产生的STL文件,如秀Makerware:
...并且从侧面看的是同一个模型:
正如你所看到的,汽缸绝对不与球满足像我认为他们会。 我的问题是这样的:我的方法做这个有缺陷的,或者是说我在我的轮换使得一些地方小,但重大的错误? 我敢肯定这不是一个问题与旋转功能本身,我已经能够独立核实他们的工作预期。 我也尝试创建一个旋转函数,它在偏航,俯仰和滚转和做所有这三个在一次,它似乎产生相同的结果,如下所示:
c.rotateYawPitchRoll(xzAngle, -yzAngle, -xyAngle)
所以......任何人有什么我可能是做错了什么想法?
UPDATE:作为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
目前似乎仍然是一些错误,但这似乎是一个简单的测试用例来至少工作。