C++ / openGL:使用四元数将 QUAD 朝某个点旋转

发布于 2024-09-08 15:28:00 字数 2474 浏览 5 评论 0原文

当我在某个位置有一个 QUAD 时,如何旋转它,使其法线指向给定点?想象一下彩色块只是矩形四边形,那么这张图片就说明了我的意思。四边形的方向都指向球体的中心。

替代文本 http://emrahgunduz.com/wp-content/ uploads/2009/01/material_id_gui-600x364.jpg

也许第二张图片显示了更多我想要做的事情: 替代文本 http://img689.imageshack.us/img689/3130/screenshot20100708at555.png< /a>

我正在使用 openGL / C++ (和 Eigen 库)。我有这个代码来绘制一个简单的四边形:

#include "ofMain.h"
#include "Quad.h"
Quad::Quad(Vector3f oPosition):position(oPosition) {
}

void Quad::update() {
}

void Quad::draw() {
    float size = 1.3;
    glColor3f(1.0f, 0.0f, 0.6f);
    glPushMatrix();
        glTranslatef(position.x(), position.y(), position.z());
        glScalef(size, size,size);
        glBegin(GL_QUADS);
            glVertex3f(0,0,0);
            glVertex3f(1,0,0);
            glVertex3f(1,1,0);
            glVertex3f(0,1,0);
        glEnd();
    glPopMatrix();
}

更新 17-07 亲爱的读者,

刚刚进一步旋转四边形。我随机定位几个四边形,然后使用以下回复中的描述使用此代码将它们旋转到 look_at vector3f:

void Quad::draw() {
    float size = 0.5;
    glColor3f(1.0f, 0.0f, 0.6f);
    glPushMatrix();
        Vector3f center = look_at - position;
        Vector3f center_norm = center.normalized();
        float r_angle   = acos(center_norm.dot(normal));
        Vector3f axis = normal.normalized().cross(center_norm);

        glPointSize(8);
        glLineWidth(4.0f);

        // draw the center point
        glColor3f(1.0f, 0.0f, 0.0f);
        glBegin(GL_POINTS); 
            glVertex3fv(look_at.data());
        glEnd();

        // draw the quad
        glColor4f(0.0f, 0.0f, 0.0f, 0.85f); 
        glTranslatef(position.x(), position.y(), position.z());
        glRotatef(r_angle * RAD_TO_DEG, axis.x(), axis.y(), axis.z());
        glScalef(size, size,size);
        glBegin(GL_QUADS);
            glVertex3f(-0.5,-0.5,0);
            glVertex3f(0.5,-0.5,0);
            glVertex3f(0.5,0.5,0);
            glVertex3f(-0.5,0.5,0);
        glEnd();

    glPopMatrix();
}

结果如下所示: 替代文本

正如你所看到的,我已经快到了,尽管四边形的旋转仍然有点“奇怪”。如果您看到下面带有彩色四边形的图像,您可以清楚地看到旋转的差异。如何旋转四边形才能获得与下面的彩色球体相同的结果?

When I have a QUAD at a certain position, how can I rotate it in such a way that its normal points toward a given point? Imagine the colored blocks are just rectangular quads, then this image shows a bit what I mean. The quads are all oriented in such a way they point toward the center of the sphere.

alt text http://emrahgunduz.com/wp-content/uploads/2009/01/material_id_gui-600x364.jpg

Maybe this second image shows a bit more what I'm trying to do:
alt text http://img689.imageshack.us/img689/3130/screenshot20100708at555.png

I'm using openGL / C++ (and the Eigen lib). And I have this code to draw a simple quad:

#include "ofMain.h"
#include "Quad.h"
Quad::Quad(Vector3f oPosition):position(oPosition) {
}

void Quad::update() {
}

void Quad::draw() {
    float size = 1.3;
    glColor3f(1.0f, 0.0f, 0.6f);
    glPushMatrix();
        glTranslatef(position.x(), position.y(), position.z());
        glScalef(size, size,size);
        glBegin(GL_QUADS);
            glVertex3f(0,0,0);
            glVertex3f(1,0,0);
            glVertex3f(1,1,0);
            glVertex3f(0,1,0);
        glEnd();
    glPopMatrix();
}

Update 17-07
Dear reader,

Just got a little bit further with rotating the quads. I'm positioning a couple of quads randomly and then I rotate them towards a look_at vector3f using this code using the descriptions from the replies below:

void Quad::draw() {
    float size = 0.5;
    glColor3f(1.0f, 0.0f, 0.6f);
    glPushMatrix();
        Vector3f center = look_at - position;
        Vector3f center_norm = center.normalized();
        float r_angle   = acos(center_norm.dot(normal));
        Vector3f axis = normal.normalized().cross(center_norm);

        glPointSize(8);
        glLineWidth(4.0f);

        // draw the center point
        glColor3f(1.0f, 0.0f, 0.0f);
        glBegin(GL_POINTS); 
            glVertex3fv(look_at.data());
        glEnd();

        // draw the quad
        glColor4f(0.0f, 0.0f, 0.0f, 0.85f); 
        glTranslatef(position.x(), position.y(), position.z());
        glRotatef(r_angle * RAD_TO_DEG, axis.x(), axis.y(), axis.z());
        glScalef(size, size,size);
        glBegin(GL_QUADS);
            glVertex3f(-0.5,-0.5,0);
            glVertex3f(0.5,-0.5,0);
            glVertex3f(0.5,0.5,0);
            glVertex3f(-0.5,0.5,0);
        glEnd();

    glPopMatrix();
}

The result looks like this:
alt text

As you can see I'm almost there, though the rotation of the quads is still a bit "strange". I you see the image below with the colored quads you clearly see the difference in rotation. How can I rotate the quad in such a way I get the same result as the colored sphere below?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

云雾 2024-09-15 15:28:00

旋转轴=标准化(crossproduct(currentNormal,desiredNormal))

旋转角度= acos(dotproduct(normalize(currentNormal),标准化(desiredNormal))。

您可以从轴和角度构建旋转矩阵或四元数。确切的公式可以在任何关于四元数的资源,

具体取决于您是否围绕其底部或尖端旋转法线。

您可能需要翻转角度或轴, ">此资源似乎有足够的关于四元数、旋转和 3d 空间的信息。

Rotation axis = normalize(crossproduct(currentNormal, desiredNormal))

Rotation angle = acos(dotproduct(normalize(currentNormal), normalize(desiredNormal)).

You can build either rotation matrix or quaternion from axis and angle. Exact formula can be found in any resource about quaternions.

You may need to flip angle or axis depending on whether you rotate normal around its' base or around its' tip.

Also THIS resource seems to have enough information about quaternions, rotations, and 3d space in general.

究竟谁懂我的在乎 2024-09-15 15:28:00

您可能已经找到了这个 - http://gpwiki.org/index.php/OpenGL :Tutorials:Using_Quaternions_to_represent_rotation - 但当我上次研究这个主题时,我发现它很有用。

You may have already found this - http://gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation - but I found it useful when I last looked into this topic.

素罗衫 2024-09-15 15:28:00

如果“在某个位置”意味着您知道当前的法线,那么事情就是这样:

  1. 旧法线和新法线的点积是它们之间角度的余弦。
  2. 它们的叉积是一个轴,您应该围绕该轴执行所需的旋转。
  3. 从给定轴和角度构造旋转四元数是有据可查的基本特征。
  4. 旋转四边形本身很棘手,具体取决于您希望它如何旋转。

If "at a certain position" means that you know your current normal, than here is the thing:

  1. Dot product of an old and new normal is a cosine of an angle between them.
  2. Their cross product is an axis around which you should perform desired rotation
  3. Construction of rotation quaternion from given axis and angle is well documented and basic feature.
  4. Rotating the quad itself is tricky and depends on how what exactly you want it to be rotated.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文