OpenGL 对象绕线旋转

发布于 2024-09-28 12:53:01 字数 128 浏览 10 评论 0原文

我正在使用 OpenGL 和 C++ 进行编程。我知道 1 条线(对角线)上有 2 个点,并且希望围绕该对角线旋转对象。我该怎么做呢?我知道如何使用 glrotatef 围绕 x、y 或 z 轴旋转它,但对此不确定。

I am programming in OpenGL and C++. I know 2 points on 1 line (a diagonal line) and wish to rotate an object around that diagonal line. How can I go about doing this? I know how to use glrotatef to rotate it around the x, y or z axis but am not sure about this.

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

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

发布评论

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

评论(3

痞味浪人 2024-10-05 12:53:02

glrotate 绕轴旋转。一种方法是执行将旋转轴与其中一个坐标轴对齐的变换,执行旋转,然后反转第一步。如果您需要速度,您可以将这些操作组合成一个特殊的转换矩阵,然后一步应用它们。 此处有说明。

glrotate does the rotation about an axis. One method is to perform transformations which align rotation axis with one of coordinate axis, perform the rotation, then reverse the first step. If you need speed you can combine the operations into a special transformation matrix and apply them in one step. There's a description here.

誰ツ都不明白 2024-10-05 12:53:01

glRotate 的 x、y 和 z 参数可以指定任意轴,而不仅仅是 x、y 和 z 轴。要找到穿过直线的轴,只需减去直线的端点即可得到轴向量:如果两个点是 (x1, y1, z1)(x2, y2, z2),您需要的轴是(x2-x1, y2-y1, z2-z1)

编辑:正如@chris_l指出的,只有当线穿过原点时,这才有效。如果不是,首先应用 (-x1, -y1, -z1) 平移,使直线穿过原点,然后应用上述旋转,并通过 (x1 ,y1,z1)。

The x, y and z parameters to glRotate can specify any arbitrary axis, not just the x, y and z axes. To find an axis passing through your line, just subtract the end-points of the line to get an axis vector: if the two points are (x1, y1, z1) and (x2, y2, z2), the axis you need is (x2-x1, y2-y1, z2-z1).

Edit: As @chris_l pointed out, this works only if the line passes through the origin. If not, first apply a translation of (-x1, -y1, -z1) so that the line passes through the origin, then apply the above rotation, and translate it back by (x1, y1, z1).

破晓 2024-10-05 12:53:01

嘿,做一些四元数/向量数学怎么样? =) 我已经在 Vector 类上使用小“补丁”来完成此操作:

double NumBounds(double value)
{
    if (fabs(value) < (1 / 1000000.0f))
        return 0; else
            return value;
}

class Vector
{
    private:
        double x, y, z;

    public:
        Vector(const Vector &v)
        {
            x = NumBounds(v.x); y = NumBounds(v.y); z = NumBounds(v.z);
        }

        Vector(double _x, double _y, double _z)
        {
            x = NumBounds(_x); y = NumBounds(_y); z = NumBounds(_z);
        }

        Vector Normalize()
        {
            if (Length() != 0)
                return Vector(x / Length(), y / Length(), z / Length()); else
                    return *this;
        }

        double operator[](unsigned int index) const
        {
            if (index == 0)
                return NumBounds(x); else
            if (index == 1)
                return NumBounds(y); else
            if (index == 2)
                return NumBounds(z); else
                    return 0;
        }

        void operator=(const Vector &v)
        {
            x = NumBounds(v.x); y = NumBounds(v.y); z = NumBounds(v.z);
        }

        Vector operator+(const Vector &v)
        {
            return Vector(x + v.x, y + v.y, z + v.z);
        }

        Vector operator-(const Vector &v)
        {
            return Vector(x - v.x, y - v.y, z - v.z);
        }

        double operator*(const Vector &v)
        {
            return NumBounds((x * v.x) + (y * v.y) + (z * v.z));
        }

        Vector operator*(double s)
        {
            return Vector(x * s, y * s, z * s);
        }

        Vector DotProduct(const Vector &v)
        {
            double k1 = (y * v.z) - (z * v.y);
            double k2 = (z * v.x) - (x * v.z);
            double k3 = (x * v.y) - (y * v.x);

            return Vector(NumBounds(k1), NumBounds(k2), NumBounds(k3));
        }

        Vector Rotate(Vector &axis, double Angle)
        {
            Vector v = *this;

            return ((v - axis * (axis * v)) * cos(angle)) + (axis.DotProduct(v) * sin(angle)) + (axis * (axis * v));
        }
};

使用此类,您可以轻松地围绕任何其他向量旋转任何向量:

Vector a(1.0f, 0.0f, 0.0f), b(0.0f, 1.0f, 0.0f), c(0.0f, 0.0f, 0.0f);

c = a.Rotate(b, M_PI / 2.0f); // rotate vector a around vector b for 90 degrees (PI / 2 radians): should be Vector(0, 0, 1);

Hey, how about doing some quaternions / vector maths? =) I've done that using small "patch" on my Vector class:

double NumBounds(double value)
{
    if (fabs(value) < (1 / 1000000.0f))
        return 0; else
            return value;
}

class Vector
{
    private:
        double x, y, z;

    public:
        Vector(const Vector &v)
        {
            x = NumBounds(v.x); y = NumBounds(v.y); z = NumBounds(v.z);
        }

        Vector(double _x, double _y, double _z)
        {
            x = NumBounds(_x); y = NumBounds(_y); z = NumBounds(_z);
        }

        Vector Normalize()
        {
            if (Length() != 0)
                return Vector(x / Length(), y / Length(), z / Length()); else
                    return *this;
        }

        double operator[](unsigned int index) const
        {
            if (index == 0)
                return NumBounds(x); else
            if (index == 1)
                return NumBounds(y); else
            if (index == 2)
                return NumBounds(z); else
                    return 0;
        }

        void operator=(const Vector &v)
        {
            x = NumBounds(v.x); y = NumBounds(v.y); z = NumBounds(v.z);
        }

        Vector operator+(const Vector &v)
        {
            return Vector(x + v.x, y + v.y, z + v.z);
        }

        Vector operator-(const Vector &v)
        {
            return Vector(x - v.x, y - v.y, z - v.z);
        }

        double operator*(const Vector &v)
        {
            return NumBounds((x * v.x) + (y * v.y) + (z * v.z));
        }

        Vector operator*(double s)
        {
            return Vector(x * s, y * s, z * s);
        }

        Vector DotProduct(const Vector &v)
        {
            double k1 = (y * v.z) - (z * v.y);
            double k2 = (z * v.x) - (x * v.z);
            double k3 = (x * v.y) - (y * v.x);

            return Vector(NumBounds(k1), NumBounds(k2), NumBounds(k3));
        }

        Vector Rotate(Vector &axis, double Angle)
        {
            Vector v = *this;

            return ((v - axis * (axis * v)) * cos(angle)) + (axis.DotProduct(v) * sin(angle)) + (axis * (axis * v));
        }
};

Using this class you can easily rotate any vector around any other one:

Vector a(1.0f, 0.0f, 0.0f), b(0.0f, 1.0f, 0.0f), c(0.0f, 0.0f, 0.0f);

c = a.Rotate(b, M_PI / 2.0f); // rotate vector a around vector b for 90 degrees (PI / 2 radians): should be Vector(0, 0, 1);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文