【python 矩形绕中心旋转坐标计算】
·
旋转+最小外接圆
import math
def rotated_bbox(x, y, w, h, angle_deg):
"""
计算矩形 (x, y, w, h) 旋转 angle_deg 度后最小外接矩形的 xywh
(x, y) 为左上角坐标,旋转中心为矩形中心
返回 (new_x, new_y, new_w, new_h)
"""
# 转弧度
angle = math.radians(angle_deg)
# 计算中心点
cx = x + w / 2
cy = y + h / 2
# 矩形四个角点(以中心为原点前的坐标)
corners = [
(x - cx, y - cy), # 左上
(x + w - cx, y - cy), # 右上
(x + w - cx, y + h - cy), # 右下
(x - cx, y + h - cy), # 左下
]
# 旋转每个点
rotated = []
for px, py in corners:
rx = px * math.cos(angle) - py * math.sin(angle)
ry = px * math.sin(angle) + py * math.cos(angle)
rotated.append((rx, ry))
print(f'旋转后顶点坐标:{rotated}')
# 找出旋转后坐标的最小外接矩形
xs = [cx + p[0] for p in rotated]
ys = [cy + p[1] for p in rotated]
new_x = min(xs)
new_y = min(ys)
new_w = max(xs) - min(xs)
new_h = max(ys) - min(ys)
return new_x, new_y, new_w, new_h
可视化
import math
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle, Polygon
def rotated_bbox(x, y, w, h, angle_deg, ax=None):
"""
计算矩形 (x, y, w, h) 旋转 angle_deg 度后最小外接矩形的 xywh,
同时在 ax 上可视化。
"""
angle = math.radians(angle_deg)
cx = x + w / 2
cy = y + h / 2
# 原始矩形四个角点
corners = [(x, y), (x + w, y), (x + w, y + h), (x, y + h)]
# 旋转后的四个角点
rotated = []
for px, py in corners:
rx = cx + (px - cx) * math.cos(angle) - (py - cy) * math.sin(angle)
ry = cy + (px - cx) * math.sin(angle) + (py - cy) * math.cos(angle)
rotated.append((rx, ry))
# 最小外接矩形
xs = [p[0] for p in rotated]
ys = [p[1] for p in rotated]
new_x, new_y = min(xs), min(ys)
new_w, new_h = max(xs) - min(xs), max(ys) - min(ys)
if ax is not None:
# 原始矩形(蓝色虚线)
ax.add_patch(
Rectangle(
(x, y),
w,
h,
fill=False,
edgecolor="blue",
linestyle="--",
linewidth=1.5,
label="original-rect",
)
)
# 旋转后矩形(红色多边形)
ax.add_patch(
Polygon(
rotated,
closed=True,
fill=False,
edgecolor="red",
linewidth=2,
label="roated-rect",
)
)
# 最小外接矩形(绿色实线)
ax.add_patch(
Rectangle(
(new_x, new_y),
new_w,
new_h,
fill=False,
edgecolor="green",
linewidth=1.5,
label="outer-rect",
)
)
ax.scatter([cx], [cy], color="black", marker="x", label="center")
ax.set_aspect("equal")
ax.legend()
ax.set_title(f"rotation {angle_deg}° ")
return new_x, new_y, new_w, new_h
# === 示例演示 ===
if __name__ == "__main__":
fig, ax = plt.subplots(figsize=(6, 6))
x, y, w, h = 100, 50, 80, 40
angle = 30
new_box = rotated_bbox(x, y, w, h, angle, ax=ax)
print("旋转后最小外接矩形 xywh:", new_box)
plt.show()

更多推荐
所有评论(0)