找到旋转矩形的包围矩形

6

我有一个矩形,其坐标为(x1,y1)和(x2,y2),需要使用旋转矩阵将其绕中心旋转θ度。

 |  cosθ  sinθ |
 | -sinθ  cosθ |

我需要在旋转后找到边界矩形的坐标。

旋转前

0,0
 |"""""""""""""""""""""""""""""""""""""""""""|
 |                                           |
 |  x1,y1                                    |
 |       |"""""""""""""|                     |
 |       |             |                     |
 |       |             |                     | 
 |       |             |                     |
 |       """""""""""""" x2,y2                |
 |                                           |
 |                                           |
  """"""""""""""""""""""""""""""""""""""""""" W,H

旋转后

 0,0
     |"""""""""""""""""""""""""""""""""""""""""""|
     |           ?,?                             |
     |            |""""/\"""""|                  |      
     |            |   /   \   |                  |
     |            |  /      \ |                  |
     |            | /        /|                  |
     |            |/        / |                  |
     |            |\       /  |                  |
     |            |  \    /   |                  |
     |            |    \ /    |                  |
     |             """""""""""  ?,?              |
     |                                           |
     |                                           |
      """"""""""""""""""""""""""""""""""""""""""" W,H

有没有通用的公式可以找到边界矩形的坐标?谢谢...Haris.
2个回答

6
只需在您的图纸上标记所有Fi角度,您就可以看到:
Old_Width = X2_Old - X1_Old, Old_Height = Y2_Old - Y1_Old
New_Height = Old_Width * Abs(Sin(Fi)) + Old_Height * Abs(Cos(Fi))
New_Width = Old_Width * Abs(Cos(Fi)) + Old_Height * Abs(Sin(Fi))
X1_New = X1_Old - (New_Width - OldWidth) / 2 = 
         (X1_Old + X2_Old - New_Width) / 2

在此输入图片描述

Delphi测试:


(注:该段文字为标题,无需翻译)
procedure TForm1.DrawRotatedRectWithFrame(X0, Y0, X1, Y1: Integer; Fi: Double);
var
  P: array[0..3] of TPoint;
  CX, CY, WX, WY, NW, NH : Integer;
  CF, SF: Double;
begin
  CX := (X0 + X1) div 2;  //Center point
  CY := (Y0 + Y1) div 2;
  WX := (X1 - X0) div 2;  //Half-width
  WY := (Y1 - Y0) div 2;
  SinCos(Fi, SF, CF);
  //calculate vertices of rotated rectangle
  P[0] := Point(Round(CX  -WX*CF + WY * SF), Round(CY - WX * SF - WY * CF));
  P[1] := Point(Round(CX  +WX*CF + WY * SF), Round(CY + WX * SF - WY * CF));
  P[2] := Point(Round(CX  +WX*CF - WY * SF), Round(CY + WX * SF + WY * CF));
  P[3] := Point(Round(CX  -WX*CF - WY * SF), Round(CY - WX * SF + WY * CF));
  Canvas.Polygon(P); //draw rotated rectangle

  Canvas.Rectangle(CX - 2, CY - 2, CX + 3, CY + 3); //mark center point
  NH := Round(Abs(WX * SF) + Abs(WY * CF));  //boundrect half-height
  NW := Round(Abs(WX * CF) + Abs(WY * SF));  //boundrect half-width
  Canvas.Brush.Style := bsClear;
  Canvas.Rectangle(CX - NW, CY - NH, CX + NW, CY + NH); //draw bound rectangle
end;

输出示例:

这里输入图片描述


这对于超过90度的旋转有效吗? - SQB
@SQB 是的,它适用于所有角度(已测试)。 - MBo

3
点(x1, y1)旋转到(x1 cos θ - y1 sin θ, x1 sin θ + y1 cos θ),而点(x2, y2)旋转到(x2 cos θ - y2 sin θ, x2 sin θ + y2 cos θ)。另外两个点可以相应地计算出来。
边界矩形的坐标为(x3, y3)和(x4, y4),其中x3是所有新x坐标中最小的,y3是所有新y坐标中最小的,x4是所有新x坐标中最大的,而y4是所有新y坐标中最大的。

哪个角落生成最小的x(等等)取决于您的角度或旋转。对于0°到90°的角度,x3将来自(x1, y1),因此x3= x1cosθ - y1sinθ。对于从90°到180°的角度,它将来自(x2, y1),依此类推。 因此,您可以根据旋转角度决定使用哪些点,或者只需取所有x和y中的最小值和最大值。


但我认为你应该在https://math.stackexchange.com/上提出这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接