Вопрос

Эй, ребята, я пытаюсь вычислить вершины повернутого прямоугольника (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);

}
Это было полезно?

Решение

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

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

где (x, y) - исходные точки, (x', y') - повернутые координаты, а t - угол, измеренный в радианах от оси x.Вращение происходит против часовой стрелки, как написано.

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

Другие советы

Я думаю, что вы были на правильном пути, используя 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.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top