无法将openGL中的圆柱正确旋转到所需位置

时间:2010-09-07 05:21:01

标签: objective-c opengl

我有一个Objective-c实用程序,可以渲染凸包。 (这是为了解决另一个计算凸包的程序中的错误,为空间统计分析做准备)。我正在尝试渲染一组三角形,每个三角形都有一个向外指向的矢量。我可以毫无问题地得到三角形,但这些向量让我发疯。

我希望矢量是简单的圆柱体。问题在于我不能仅仅声明圆柱的顶部和底部在3D中的位置的坐标(例如,就像我可以用于三角形)。我必须制作它们然后旋转并沿着z轴从它们的默认位置转换它们。我读过很多关于欧拉角,角轴旋转和四元数的信息,其中大部分是相关的,但并不针对我需要的东西:大多数人都有一组物体,然后需要旋转物体以响应一些输入。我需要将对象正确放置在3D“场景”中。

我正在使用Cocoa3DTutorial课来帮助我,而且就我所知,它们的工作效果很好,但旋转位正在扼杀我。

这是我目前的努力。它给了我正确定位的圆柱体,但都沿着z轴指向(如图中所示:alt text。我们正在向-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)”位),而不是一组三个旋转。我的代码很可能是问题所在,但我看不出如何。

2 个答案:

答案 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正在穿过船体,而不是从每个面部指出),我现在可以在其他程序中找到该错误...明天: alt text