2010-10-20 2 views
4

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

ответ

0

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

5

Параметры 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

Это, конечно, работает только правильно , если ось проходит через начало координат (0, 0, 0). –

+0

@chris_l: Спасибо, обновлено. – casablanca

+0

@chris, это можно зафиксировать, вычитая первую точку из второй, а затем используя результат в качестве вектора оси. Работает, если они не совпадают, но тогда они не будут иметь 2 разных точки на линии –

1

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

 Смежные вопросы

  • Нет связанных вопросов^_^