我有一个Objective-c实用程序,可以渲染凸包。 (这是为了解决另一个计算凸包的程序中的错误,为空间统计分析做准备)。我正在尝试渲染一组三角形,每个三角形都有一个向外指向的矢量。我可以毫无问题地得到三角形,但这些向量让我发疯。
我希望矢量是简单的圆柱体。问题在于我不能仅仅声明圆柱的顶部和底部在3D中的位置的坐标(例如,就像我可以用于三角形)。我必须制作它们然后旋转并沿着z轴从它们的默认位置转换它们。我读过很多关于欧拉角,角轴旋转和四元数的信息,其中大部分是相关的,但并不针对我需要的东西:大多数人都有一组物体,然后需要旋转物体以响应一些输入。我需要将对象正确放置在3D“场景”中。
我正在使用Cocoa3DTutorial课来帮助我,而且就我所知,它们的工作效果很好,但旋转位正在扼杀我。
这是我目前的努力。它给了我正确定位的圆柱体,但都沿着z轴指向(如图中所示:。我们正在向-z方向看。后面伸出的三角形不是船体的一部分;用于测试/调试。正交圆柱体或多或少是坐标轴,并且球体用于确保轴正确定位,因为我必须使用旋转来正确放置这些圆柱体。而且,当我使用该算法时, out-vectors也失败了,虽然以不同的方式出现在平面上,但是所有指向+ z而不是-z中的一些
来自Render3DDocument.m的:
// Make the out-pointing vector
C3DTCylinder *outVectTube;
C3DTEntity *outVectEntity;
Point3DFloat *sideCtr = [thisSide centerOfMass];
outVectTube = [C3DTCylinder cylinderWithBase: tubeRadius top: tubeRadius height: tubeRadius*10 slices: 16 stacks: 16];
outVectEntity = [C3DTEntity entityWithStyle:triColor
geometry:outVectTube];
Point3DFloat *outVect = [[thisSide inVect] opposite];
Point3DFloat *unitZ = [Point3DFloat pointWithX:0 Y:0 Z:1.0f];
Point3DFloat *rotAxis = [outVect crossWith:unitZ];
double rotAngle = [outVect angleWith:unitZ];
[outVectEntity setRotationX: rotAxis.x
Y: rotAxis.y
Z: rotAxis.z
W: rotAngle];
[outVectEntity setTranslationX:sideCtr.x - ctrX
Y:sideCtr.y - ctrY
Z:sideCtr.z - ctrZ];
[aScene addChild:outVectEntity];
(注意,Point3DFloat基本上是一个矢量类,Side(就像thisSide)是一组四个Point3DFloats,每个顶点一个,一个指向船体中心的矢量) 的
来自C3DTEntity.m的:
if (_hasTransform) {
glPushMatrix();
// Translation
if ((_translation.x != 0.0) || (_translation.y != 0.0) || (_translation.z != 0.0)) {
glTranslatef(_translation.x, _translation.y, _translation.z);
}
// Scaling
if ((_scaling.x != 1.0) || (_scaling.y != 1.0) || (_scaling.z != 1.0)) {
glScalef(_scaling.x, _scaling.y, _scaling.z);
}
// Rotation
glTranslatef(-_rotationCenter.x, -_rotationCenter.y, -_rotationCenter.z);
if (_rotation.w != 0.0) {
glRotatef(_rotation.w, _rotation.x, _rotation.y, _rotation.z);
} else {
if (_rotation.x != 0.0)
glRotatef(_rotation.x, 1.0f, 0.0f, 0.0f);
if (_rotation.y != 0.0)
glRotatef(_rotation.y, 0.0f, 1.0f, 0.0f);
if (_rotation.z != 0.0)
glRotatef(_rotation.z, 0.0f, 0.0f, 1.0f);
}
glTranslatef(_rotationCenter.x, _rotationCenter.y, _rotationCenter.z);
}
我在上面的代码中添加了一个位,该位使用围绕轴的单个旋转(“if(_rotation.w!= 0.0)”位),而不是一组三个旋转。我的代码很可能是问题所在,但我看不出如何。
答案 0 :(得分:0)
如果你的出路没有指向正确的直升机,你可能需要检查三角形的绕组 - 它们是否都以相同的方式定位?
此外,为每个outvec绘制一条线可能会有所帮助(使用三角形的三个顶点的平均值作为原点,并在方向上绘制几个单位长度的线(取决于场景的比例)通过这种方式,您可以确保所有向量都正确定位。
你如何计算你的风潮?
答案 1 :(得分:0)
问题似乎在于glrotatef()期望度数,我给它弧度。另外,顺时针旋转为正,因此旋转的符号是错误的。这是更正后的代码:
double rotAngle = -[outVect angleWith:unitZ]; // radians
[outVectEntity setRotationX: rotAxis.x
Y: rotAxis.y
Z: rotAxis.z
W: rotAngle * 180.0 / M_PI ];
我现在可以看到我的其他程序的inVects错了(下面的outVects正在穿过船体,而不是从每个面部指出),我现在可以在其他程序中找到该错误...明天: