判断点(x,y)是否在轴对齐矩形内,只需检查x∈[x_min,x_max]且y∈[y_min,y_max];边界处理需统一采用闭区间或半开区间,避免混用导致逻辑错误。

用 std::pair 或结构体表示点,直接比较坐标边界
矩形若为轴对齐(边平行于坐标轴),判断点 (x, y) 是否在其中,本质是两个一维区间判断:x 是否在矩形 x 范围内,且 y 是否在矩形 y 范围内。无需调用任何几何库,纯逻辑运算即可。
常见错误是边界处理不一致——比如误用 而非 ,导致点恰好落在右/下边上被判定为“外部”。实际应根据需求明确是否包含边界(通常数学上“在矩形内”含闭区间)。
- 若矩形由左上角
(x1, y1)和右下角(x2, y2)定义(且保证x1 、y1 ),则条件为:x >= x1 && x = y1 && y - 若矩形由中心
(cx, cy)、半宽hw、半高hh给出,等价转换为:x >= cx - hw && x = cy - hh && y - 注意:C++ 中浮点数比较需谨慎,若坐标为
float或double,建议引入小量eps避免精度误差,例如x + eps >= x1
封装成函数时,优先用 const 引用传参避免拷贝
点和矩形数据若为自定义结构(如 struct Point { double x, y; };),函数签名应避免值传递开销,尤其在高频调用或批量判断场景中。
示例函数:
立即学习“C++免费学习笔记(深入)”;
struct Rect {
double x1, y1, x2, y2; // 左上、右下(已归一化)
};
bool pointInRect(const Point& p, const Rect& r) {
return p.x >= r.x1 && p.x <= r.x2 && p.y >= r.y1 && p.y <= r.y2;
}若矩形未保证 x1 ,应在构造或传入前归一化(交换值),否则逻辑失效。这点容易被忽略,尤其从图像 API(如 OpenCV 的 cv::Rect)取坐标时,y 正方向可能向下,但只要 y1 和 y2 是上下边界数值,比较本身不受影响。
处理 OpenCV 的 cv::Rect 时注意 y 轴方向与数学习惯一致
OpenCV 的 cv::Rect 用 (x, y, width, height) 表示,其中 y 是顶边纵坐标,向下递增。这和常规数学坐标系 y 向上不同,但**不影响点在矩形内的判断逻辑**——因为仍是轴对齐,只需把矩形映射为 [x, x+width) × [y, y+height) 区间。
- 默认 OpenCV 使用左闭右开区间(
contains()方法也如此),即点(x+width, y)不在内;若需闭区间,改用并把右下角设为y + height - 1(整数坐标) - 直接调用 OpenCV 自带方法更稳妥:
cv::Rect r(10, 20, 100, 50); bool in = r.contains(cv::Point(50, 30)); - 但注意
cv::Rect::contains()对浮点cv::Point2f仍按整数截断处理,有精度丢失风险
非轴对齐矩形?别硬写,用向量叉积或变换坐标系
如果矩形旋转了,上面的坐标比较完全失效。此时不能再只看 x/y 值,必须转到矩形局部坐标系,或用向量投影法。
最简方案是坐标变换:将点平移并旋转,使矩形回到轴对齐状态,再套用前述逻辑。关键步骤是获取矩形的单位 x/y 轴向量(由顶点算出),然后做点积投影。
更通用但稍重的方式是射线法或绕数法,但对凸四边形(如矩形)更高效的是:检查点是否在四条边的“内侧”——每条边对应一个向量叉积符号一致(如都 ≥ 0)。例如边 AB,计算 cross(AB, AP),符号决定 P 在 AB 左/右侧。
真正写的时候,别手撸全部向量运算;若项目已用 Eigen 或 GLM,直接用 transformPoint 或 dot/cross 函数。自己实现务必测试退化情况(如矩形扁平、点重合顶点)。
轴对齐是特例,也是绝大多数练习和 UI 场景的默认假设;一旦涉及旋转,问题性质就从“范围判断”升级为“计算几何”,边界条件和数值稳定性立刻变复杂。










