OpenGL Вращение объекта вокруг линии - PullRequest
4 голосов
/ 21 октября 2010

Я программирую на OpenGL и C ++. Я знаю 2 точки на 1 линии (диагональная линия) и хочу повернуть объект вокруг этой диагональной линии. Как я могу сделать это? Я знаю, как использовать glrotatef, чтобы вращать его вокруг оси x, y или z, но я не уверен в этом.

Ответы [ 3 ]

5 голосов
/ 21 октября 2010

Параметры x, y и z для glRotate могут указывать любую произвольную ось, а не только оси x, y и z. Чтобы найти ось, проходящую через вашу линию, просто вычтите конечные точки линии, чтобы получить вектор оси: если две точки - (x1, y1, z1) и (x2, y2, z2), необходимая ось - (x2-x1, y2-y1, z2-z1).

Редактировать: Как указывало @chris_l, это работает, только если линия проходит через начало координат. Если нет, сначала примените перевод (-x1, -y1, -z1) так, чтобы линия проходила через начало координат, затем примените указанное выше вращение и переведите его обратно на (x1, y1, z1).

1 голос
/ 21 ноября 2010

Эй, как насчет кватернионов / векторной математики?=) Я сделал это с помощью небольшого «патча» в своем классе 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);
0 голосов
/ 21 октября 2010

glrotate делает вращение вокруг оси.Один метод состоит в том, чтобы выполнить преобразования, которые выравнивают ось вращения с одной из осей координат, выполняют вращение, затем обращают вспять первый шаг.Если вам нужна скорость, вы можете объединить операции в специальную матрицу преобразования и применить их за один шаг.Здесь есть описание здесь .

...