如何判断点是否处于经过2D变换的矩形内部?
判断点是否在变换后矩形内的逆变换解法
核心思路
直接判断点在变换后矩形内需要处理复杂的多边形边界检测,更高效的方式是将待判断点通过逆变换映射回原矩形的坐标系:只要映射后的点落在原中心(0,0)、宽w高h的矩形内部(即 -w/2 < px' < w/2 且 -h/2 < py' < h/2),就说明原点点在变换后的矩形中。
原变换顺序为:缩放(sclX, sclY) → 旋转deg角度 → 平移(x,y),因此逆变换必须按完全颠倒的顺序执行:逆平移 → 逆旋转 → 逆缩放。
逆变换分步推导
1. 逆平移
原平移操作是给点的坐标加上(x,y),逆平移则是将待判断点减去平移量:
px₁ = px - x py₁ = py - y
2. 逆旋转
原旋转是绕原点旋转deg度,对应的旋转矩阵为:
[cosθ -sinθ] [sinθ cosθ]
其中θ是将角度转换为弧度后的结果(θ = deg × π / 180)。逆旋转等价于旋转-deg度,对应的矩阵为:
[cosθ sinθ] [-sinθ cosθ]
用该矩阵计算逆平移后的点,得到:
px₂ = px₁ × cosθ + py₁ × sinθ py₂ = -px₁ × sinθ + py₁ × cosθ
3. 逆缩放
原缩放是将x坐标乘sclX、y坐标乘sclY,逆缩放则是除以对应的缩放因子(需确保sclX和sclY不为0,否则变换不可逆):
px' = px₂ / sclX py' = py₂ / sclY
代码实现(Python)
import math def contains(rect, transform, px, py): # 提取矩形和变换参数 w, h = rect["w"], rect["h"] x, y, deg, sclX, sclY = transform["x"], transform["y"], transform["deg"], transform["sclX"], transform["sclY"] # 处理缩放因子为0的情况(变换后矩形坍缩,直接返回False) if sclX == 0 or sclY == 0: return False # 角度转弧度 theta = math.radians(deg) cos_theta = math.cos(theta) sin_theta = math.sin(theta) # 执行逆变换 # 1. 逆平移 px1 = px - x py1 = py - y # 2. 逆旋转 px2 = px1 * cos_theta + py1 * sin_theta py2 = -px1 * sin_theta + py1 * cos_theta # 3. 逆缩放 px_prime = px2 / sclX py_prime = py2 / sclY # 判断是否在原矩形内部(开区间,如需包含边界改为<=和>=) return (-w/2 < px_prime < w/2) and (-h/2 < py_prime < h/2)
注意事项
- 若需要包含矩形边界,将判断条件中的
<替换为<=,>替换为>= - 当
sclX或sclY为0时,变换后的矩形会坍缩为线或点,可根据需求调整边界判断逻辑 - 所有三角函数计算需使用弧度值,避免角度与弧度混淆
内容的提问来源于stack exchange,提问作者Eilan Laken
相关产品推荐
相关产品推荐

