围绕裁剪矩形中心旋转大矩形后的新坐标计算方法
围绕裁剪矩形中心旋转大矩形的坐标计算方法
这个问题本质是图形学里的基础坐标旋转变换,我一步步拆解给你,保证能搞明白:
首先先明确所有已知条件,避免坐标系混淆:
- 裁剪矩形(小矩形):左上角坐标
(xc, yc),宽度wc,高度hc,它的中心坐标可以直接算出:(cx, cy) = (xc + wc/2, yc + hc/2) - 大矩形的原始坐标:你提到是以小矩形左上角为基准的相对坐标,假设为
(xb_rel, yb_rel),那它的全局(屏幕)绝对坐标就是(xc + xb_rel, yc + yb_rel) - 旋转角度:θ(注意区分顺时针/逆时针,不同UI/图形框架的默认旋转方向可能不一样,后面会说明)
整个计算核心思路是:把旋转中心移到坐标系原点,完成旋转后再移回原坐标系,分三步执行:
步骤1:转换为以裁剪中心为原点的相对坐标
我们需要把大矩形的坐标,转换成以裁剪矩形中心为原点的相对坐标,这样旋转公式才能直接生效:
dx = 大矩形相对裁剪左上角的x坐标 - 裁剪宽度的一半 dy = 大矩形相对裁剪左上角的y坐标 - 裁剪高度的一半
代入公式就是:
dx = xb_rel - wc/2 dy = yb_rel - hc/2
(这里直接用相对坐标计算,比先算绝对坐标再转换更省事)
步骤2:应用旋转公式
这里要注意屏幕坐标系和数学坐标系的差异:数学里y轴向上,多数UI框架的y轴是向下的,所以旋转方向会反过来。
情况1:逆时针旋转θ角度(数学坐标系默认方向)
公式为:
dx_new = dx * cosθ - dy * sinθ dy_new = dx * sinθ + dy * cosθ
情况2:顺时针旋转θ角度(多数UI框架默认方向)
相当于逆时针旋转 -θ,代入上面的公式化简后得到:
dx_new = dx * cosθ + dy * sinθ dy_new = -dx * sinθ + dy * cosθ
⚠️ 重要提示:所有三角函数的参数需要用弧度,如果你的角度是度数,记得先转弧度(弧度 = 度数 × π / 180)
步骤3:转换回全局坐标系
把旋转后的相对坐标加回裁剪中心的坐标,就得到大矩形旋转后的绝对坐标:
xb_new = cx + dx_new yb_new = cy + dy_new
代码示例(Python)
我写了一个实用的函数,包含角度转换、顺时针旋转适配,直接套用即可:
import math def get_rotated_rect_pos(xc, yc, wc, hc, xb_rel, yb_rel, rotate_deg): # 计算裁剪矩形中心坐标 crop_center_x = xc + wc / 2 crop_center_y = yc + hc / 2 # 大矩形相对裁剪中心的坐标 dx = xb_rel - wc / 2 dy = yb_rel - hc / 2 # 度数转弧度 theta = math.radians(rotate_deg) cos_t = math.cos(theta) sin_t = math.sin(theta) # 顺时针旋转计算 dx_rotated = dx * cos_t + dy * sin_t dy_rotated = -dx * sin_t + dy * cos_t # 转换回全局坐标 new_x = crop_center_x + dx_rotated new_y = crop_center_y + dy_rotated return (round(new_x, 2), round(new_y, 2))
实际例子验证
假设:
- 裁剪矩形左上角
(100, 100),宽200,高100 → 中心坐标(200, 150) - 大矩形相对裁剪左上角的坐标是
(50, 50) - 顺时针旋转90度
代入函数计算:
dx = 50 - 200/2 = -50,dy = 50 - 100/2 = 0
theta = π/2,cosθ=0,sinθ=1
dx_rotated = (-50)0 + 01 = 0,dy_rotated = -(-50)1 + 00 = 50
new_x = 200 + 0 = 200,new_y = 150 + 50 = 200
结果为 (200,200),完全符合预期:原来的点在裁剪中心左侧50,顺时针转90度后到中心下方50(屏幕y轴向下,所以y坐标增加50)。
内容的提问来源于stack exchange,提问作者Gabriel Stein




