【问题标题】:Find corners of a rotated rectangle given its center point and rotation在给定中心点和旋转的情况下找到旋转矩形的角
【发布时间】:2017-06-13 10:20:57
【问题描述】:

如果我知道矩形的中心点(在全局坐标空间中)、宽度和高度以及围绕该中心点的旋转,谁能给我一个算法来找到矩形的所有四个角的位置?

澄清编辑: 我指的宽度和高度是矩形边的长度。

【问题讨论】:

  • 这是使用标准旋转矩阵 [ { c s } { -s c } ] 其中 c = cos(angle) 和 s = sin(angle) 的 2D 矢量变换

标签: math trigonometry


【解决方案1】:

使用矩阵编写 Python 代码:

import numpy as np
import math
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle, Circle

#center of rectangle
X = 2698.77 
Y = 1283.01
center = np.array([[X],[Y]])

angle_deg = 83.5694 #angle rectangle
angle = math.radians(angle_deg)

# rectangle's dimension
width = 2022.23
height = 1978.78

R_lt = np.array([[np.cos(angle),-np.sin(angle)],[-np.sin(angle),-np.cos(angle)]])
A = np.dot(R_lt,np.array([[width/2], [height/2]])) + center

R_rt = np.array([[np.cos(angle),np.sin(angle)],[-np.sin(angle),np.cos(angle)]])
B = np.dot(R_rt,np.array([[width/2], [height/2]])) + center

R_rb = np.array([[-np.cos(angle),np.sin(angle)],[np.sin(angle),np.cos(angle)]])
C = np.dot(R_rb,np.array([[width/2], [height/2]])) + center

R_lb = np.array([[-np.cos(angle),-np.sin(angle)],[np.sin(angle),-np.cos(angle)]])
D = np.dot(R_lb,np.array([[width/2], [height/2]])) + center

corners = [A,B,C,D]

【讨论】:

    【解决方案2】:

    每个顶点的坐标:

     Center point = (center.x, center.y)
     Angle        = angle
     Height       = height
     Width        = width      
    
    
    
    TOP RIGHT VERTEX:
    Top_Right.x = center.x + ((width / 2) * cos(angle)) - ((height / 2) * sin(angle))
    Top_Right.y = center.y + ((width / 2) * sin(angle)) + ((height / 2) * cos(angle))
    
    
    
    TOP LEFT VERTEX:
    Top_Left.x = center.x - ((width / 2) * cos(angle)) - ((height / 2) * sin(angle))
    Top_Left.y = center.y - ((width / 2) * sin(angle)) + ((height / 2) * cos(angle))
    
    
    
    BOTTOM LEFT VERTEX:
    Bot_Left.x = center.x - ((width / 2) * cos(angle)) + ((height / 2) * sin(angle))
    Bot_Left.y = center.y - ((width / 2) * sin(angle)) - ((height / 2) * cos(angle))
    
    
    
    BOTTOM RIGHT VERTEX:
    Bot_Right.x = center.x + ((width / 2) * cos(angle)) + ((height / 2) * sin(angle))
    Bot_Right.y = center.y + ((width / 2) * sin(angle)) - ((height / 2) * cos(angle))
    

    此算法是这 3 个步骤的压缩版本:

    第 1 步:将矩形围绕原点居中

    第 2 步:将旋转矩阵应用于每个顶点

    第 3 步:通过将中心点添加到每个坐标,将旋转后的矩形移动到正确的位置

    这里有更深入的解释https://math.stackexchange.com/questions/126967/rotating-a-rectangle-via-a-rotation-matrix

    【讨论】:

    • 嗨。你可以添加中间点吗?矩形有 9 个点。 4 个角点和 4 个中间点(顶部中间、底部中间、右侧中间、左侧中间)。
    • @chitgoks 如果我理解正确的话,我认为获得矩形边的中点的最简单方法是在每个旋转角点上使用中点公式。 purplemath.com/modules/midpoint.htm
    • 是使用Math.atan2的角度结果吗?
    【解决方案3】:

    如果您需要所有的角,创建从矩形中心到其两侧的两个垂直向量,然后将这些向量添加到矩形中心或从矩形中心减去这些向量可能会更快形成点。

    这可能会更快,因为您不需要重复调​​用 sin() 和 cos() 函数(每个函数只调用一次)。

    假设我们有一个 Vector 库(用于更简洁的代码 - 仅有助于矢量算术),这里是 Python 中的代码:

    def get_corners_from_rectangle(center: Vector, angle: float, dimensions: Vector):
       # create the (normalized) perpendicular vectors
       v1 = Vector(cos(angle), sin(angle))
       v2 = Vector(-v1[1], v1[0])  # rotate by 90
    
       # scale them appropriately by the dimensions
       v1 *= dimensions[0] / 2
       v2 *= dimensions[1] / 2
    
       # return the corners by moving the center of the rectangle by the vectors
       return [
          center + v1 + v2,
          center - v1 + v2,
          center - v1 - v2,
          center + v1 - v2,
       ]
    

    【讨论】:

      【解决方案4】:

      右上角有相对于中心的坐标 w/2, h/2。旋转后其绝对坐标为

       x = cx + w/2 * Cos(Phi) - h/2 * Sin(Phi)
       y = cy + w/2 * Sin(Phi) + h/2 * Cos(Phi)
      

      【讨论】:

      • 刚试过这个,如果矩形没有旋转,这个可以工作。我可以在哪里考虑矩形旋转的角度?
      • 这个公式给出了矩形角的坐标,旋转了角度 Phi。
      • 啊,好吧,我只是插入了 Phi 的实际值。谢谢!
      猜你喜欢
      • 2018-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多