计算旋转矩形的顶点

发布于 2024-08-05 04:13:49 字数 1151 浏览 5 评论 0原文

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

}

I am trying to calculate the vertices of a rotated rectangle (2D).

It's easy enough if the rectangle has not been rotated, I figured that part out.

If the rectangle has been rotated, I thought of two possible ways to calculate the vertices.

  1. Figure out how to transform the vertices from local/object/model space (the ones I figured out below) to world space. I honestly have no clue, and if it is the best way then I feel like I would learn a lot from it if I could figure it out.

  2. Use trig to somehow figure out where the endpoints of the rectangle are relative to the position of the rectangle in world space. This has been the way I have been trying to do up until now, I just haven't figured out how.

Here's the function that calculates the vertices thus far, thanks for any help

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);

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

流星番茄 2024-08-12 04:13:49

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

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

其中 (x, y) 是原始点,(x', y') 是旋转坐标,t 是以弧度为单位从 x 轴测量的角度。如所写,旋转为逆时针。

我的建议是在纸上完成一次。绘制一个矩形,计算新坐标,然后重新绘制矩形,以确保在编码之前它是正确的。然后使用此示例作为单元测试,以确保您正确编码。

I would just transform each point, applying the same rotation matrix to each one. If it's a 2D planar rotation, it would look like this:

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

where (x, y) are the original points, (x', y') are the rotated coordinates, and t is the angle measured in radians from the x-axis. The rotation is counter-clockwise as written.

My recommendation would be to do it out on paper once. Draw a rectangle, calculate the new coordinates, and redraw the rectangle to satisfy yourself that it's correct before you code. Then use this example as a unit test to ensure that you coded it properly.

阪姬 2024-08-12 04:13:49

我认为您使用 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

I think you were on the right track using atan() to return an angle. However you want to pass height divided by width instead of the other way around. That will give you the default (unrotated) angle to the upper-right vertex of the rectangle. You should be able to do the rest like this:

// 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.

Obviously more longwinded than necessary, for the sake of clarity. Of course, duffymo's solution using a transformation matrix is probably more elegant and efficient :)

EDIT: Now my code should actually work. I changed (width / height) to (height / width) and used a constant radius from the center of the rectangle to calculate the vertices. Working Python (turtle) code at http://pastebin.com/f1c76308c

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文