【问题标题】:Calculating vertices of a rotated rectangle计算旋转矩形的顶点
【发布时间】:2009-09-24 00:00:19
【问题描述】:

我正在尝试计算旋转矩形 (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);

}

【问题讨论】:

    标签: c++ math matrix trigonometry rectangles


    【解决方案1】:

    我只是变换每个点,对每个点应用相同的旋转矩阵。如果是 2D 平面旋转,它看起来像这样:

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

    其中 (x, y) 是原始点,(x', y') 是旋转后的坐标,t 是从 x 轴以弧度测量的角度。旋转是逆时针方向。

    我的建议是在纸上完成一次。绘制一个矩形,计算新坐标,然后重新绘制矩形,让自己确信它是正确的,然后再编写代码。然后将此示例用作单元测试,以确保您正确编码。

    【讨论】:

    • +1 - 我更喜欢旋转回来然后做任何工作,让生活更简单。
    • 这样,您只需执行 2 次三角操作即可完成(如果您在计算任何旋转顶点之前存储了 cos(t)sin(t) 的结果)。
    • 这个公式如何顺时针旋转?
    • 忘记我的问题。只需将角度设为负数即可:)
    • @duffymo 你有这个转换的来源吗?效果很好,只是想了解。
    【解决方案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),并使用矩形中心的恒定半径来计算顶点。在http://pastebin.com/f1c76308c 处工作的 Python (turtle) 代码

    【讨论】:

    • DEG_TO_RAD 是我写的宏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    • 2013-04-08
    • 2021-11-06
    相关资源
    最近更新 更多