2009-09-24 155 views
6

嘿,我试图计算旋转矩形(2D)的顶点。计算旋转矩形的顶点

如果矩形没有旋转,我很容易,我想这一部分了。

如果矩形已经旋转,我想到两种可能的方法来计算顶点。 1)找出如何将顶点从本地/对象/模型空间(我下面想到的)转换到世界空间。我真的没有线索,如果这是最好的方式,那么我觉得我会从中学到很多东西,如果我能想出来......

2)使用trig来弄清楚哪里的端点矩形相对于世界空间中矩形的位置。这一直是我一直在努力的方式,直到现在我还没有想出如何。

下面是计算顶点迄今为止功能,感谢您的帮助

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

我只想改变每个点,应用相同的旋转矩阵各去一次。如果它是一个二维平面的旋转,它看起来像这样:

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

其中(x,y)是原始点,(X“ Y”)是旋转坐标,并且t是在测量的角来自X轴的弧度。书面形式的旋转是逆时针的。

我的建议是在纸上做一次。绘制一个矩形,计算新的坐标,并重新绘制矩形,以确保在编码之前它是正确的。然后使用这个例子作为单元测试来确保你编码正确。

+1

+1 - 我倾向于旋转回来,然后做任何工作,使生活更简单。 – 2009-09-24 00:45:43

+2

通过这种方式,您只需执行2个触发操作(如果在计算任何旋转的顶点之前存储'cos(t)'和'sin(t)'的结果)。 – jnylen 2009-09-24 01:55:41

+0

这个公式将如何顺时针旋转? – 2012-09-06 19:35:38

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. 

为清楚起见,显然比必要的更加冗长。当然,使用变换矩阵的duffymo的解决方案可能更优雅和高效:)

编辑:现在我的代码应该实际工作。我将(width/height)更改为(height/width),并使用矩形中心的恒定半径来计算顶点。工作Python(海龟)代码http://pastebin.com/f1c76308c

+0

DEG_TO_RAD是我写的一个宏。 – 2009-10-04 06:33:42