You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

围绕裁剪矩形中心旋转大矩形后的新坐标计算方法

围绕裁剪矩形中心旋转大矩形的坐标计算方法

这个问题本质是图形学里的基础坐标旋转变换,我一步步拆解给你,保证能搞明白:

首先先明确所有已知条件,避免坐标系混淆:

  • 裁剪矩形(小矩形):左上角坐标 (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

火山引擎 最新活动