2009-09-24 3 views
6

Эй, ребята, я пытаюсь вычислить вершины вращающегося прямоугольника (2D).Расчет вершин вращающегося прямоугольника

Это достаточно легко, если прямоугольник не был повернут, я решил, что это часть.

Если прямоугольник повернут, я подумал о двух возможных способах вычисления вершин. 1) Посмотрите, как преобразовать вершины из локального пространства/объекта/модели (те, которые я понял ниже) в мировое пространство. Я, честно говоря, понятия не имею, и если это лучший способ, то мне кажется, что я бы многому научился, если бы мог понять это ...

2) Используйте триггер, чтобы как-то выяснить, где конечные точки прямоугольник относительно положения прямоугольника в мировом пространстве. Это было так, как я пытался это сделать до сих пор, я просто не понял, как это сделать.

Вот функция, которая вычисляет вершины до сих пор, спасибо за любую помощь

void Rect::calculateVertices() 
{ 
    if(m_orientation == 0) // if no rotation 
    { 
     setVertices(
     &Vertex((m_position.x - (m_width/2) * m_scaleX), (m_position.y + (m_height/2) * m_scaleY), m_position.z), 
     &Vertex((m_position.x + (m_width/2) * m_scaleX), (m_position.y + (m_height/2) * m_scaleY), m_position.z), 
     &Vertex((m_position.x + (m_width/2) * m_scaleX), (m_position.y - (m_height/2) * m_scaleY), m_position.z), 
     &Vertex((m_position.x - (m_width/2) * m_scaleX), (m_position.y - (m_height/2) * m_scaleY), m_position.z)); 
    } 
    else 
    { 
     // if the rectangle has been rotated.. 
    } 

    //GLfloat theta = RAD_TO_DEG(atan(((m_width/2) * m_scaleX)/((m_height/2) * m_scaleY))); 
    //LOG->writeLn(&theta); 

} 

ответ

16

Я бы просто преобразовать каждую точку, применяя ту же матрицу вращения для каждого из них. Если это 2D планарного вращения, он будет выглядеть следующим образом:

x' = x*cos(t) - y*sin(t) 
y' = x*sin(t) + y*cos(t) 

где (х, у) являются исходные точки, (х «у») являются повернутые координаты, и т угол измеряется в радиан от оси х. Вращение против часовой стрелки, как указано.

Моей рекомендацией было бы сделать это на бумаге один раз. Нарисуйте прямоугольник, вычислите новые координаты и перерисуйте прямоугольник, чтобы убедиться, что он правильный, прежде чем вы код. Затем используйте этот пример как единичный тест, чтобы убедиться, что вы правильно его закодировали.

+1

+1 - Я предпочитаю поворачивать назад, а затем выполнять любую работу, упрощая жизнь. –

+2

Таким образом, вы можете обойтись только при выполнении двух триггерных операций (если вы сохраняете результаты 'cos (t)' и 'sin (t)' перед вычислением любых повернутых вершин). – jnylen

+0

Как эта формула должна вращаться по часовой стрелке? –

2

Я думаю, что вы были на правильном пути, используя atan(), чтобы вернуть угол. Однако вы хотите передать height, деленный на width, а не наоборот. Это даст вам по умолчанию (невращаемый) угол в верхнюю правую вершину прямоугольника. Вы должны быть в состоянии сделать все остальное, как это:

// Get the original/default vertex angles 
GLfloat vertex1_theta = RAD_TO_DEG(atan(
      (m_height/2 * m_scaleY) 
      /(m_width/2 * m_scaleX))); 
GLfloat vertex2_theta = -vertex1_theta; // lower right vertex 
GLfloat vertex3_theta = vertex1_theta - 180; // lower left vertex 
GLfloat vertex4_theta = 180 - vertex1_theta; // upper left vertex 

// Now get the rotated vertex angles 
vertex1_theta += rotation_angle; 
vertex2_theta += rotation_angle; 
vertex3_theta += rotation_angle; 
vertex4_theta += rotation_angle; 

//Calculate the distance from the center (same for each vertex) 
GLfloat r = sqrt(pow(m_width/2*m_scaleX, 2) + pow(m_height/2*m_scaleY, 2)); 

/* Calculate each vertex (I'm not familiar with OpenGL, DEG_TO_RAD 
* might be a constant instead of a macro) 
*/ 
vertexN_x = m_position.x + cos(DEG_TO_RAD(vertexN_theta)) * r; 
vertexN_y = m_position.y + sin(DEG_TO_RAD(vertexN_theta)) * r; 

// Now you would draw the rectangle, proceeding from vertex1 to vertex4. 

Очевидно более longwinded, чем это необходимо, для наглядности. Конечно, решение duffymo с использованием матрицы преобразования, вероятно, более изящно и эффективно :)

EDIT: Теперь мой код действительно должен работать. Я изменил (width/height) на (height/width) и использовал радиус радиуса от центра прямоугольника для вычисления вершин. Рабочий код Python (черепаха) на http://pastebin.com/f1c76308c

+0

DEG_TO_RAD - это макрос, который я написал. –

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