圆角矩形无标准c++几何类型,其点在内判断需分区域:先排除外框,再判中心矩形,最后按四角圆弧距离公式验证,并需处理半径过大、坐标系差异、整数溢出及中心锚定等边界情况。

圆角矩形的数学定义决定了不能直接用 rect.contains()
标准 C++ 没有内置的“圆角矩形”几何类型,std::vector 或 cv::Rect 这类结构只支持直角矩形。所谓“圆角矩形”,本质是:一个中心对齐(或左上对齐)的矩形,四角被半径为 r 的圆弧截去。判断点 (x, y) 是否在内,需分区域处理——不能简单套用 x >= left && x = top && y 。
关键在于识别点落在哪个区域:中心矩形区、左右侧条带、上下侧条带,还是四个圆角区。只有落在圆角区的点,才需要计算到对应圆心的距离。
手动拆解四区域 + 圆角距离判断(最通用、无依赖)
假设圆角矩形由左上角 (x0, y0)、宽 w、高 h、圆角半径 r 定义(r 不能超过 w/2 或 h/2,否则无效)。给定点 px, py:
- 先快速排除:若
px x0 + w || py y0 + h,直接返回false - 再检查是否在“去角后”的中心矩形内:
px >= x0 + r && px = y0 + r && py → 是则 <code>true - 否则进入圆角区判断:
- 左上角:若
px ,则计算到圆心 <code>(x0 + r, y0 + r)距离平方 ≤r * r - 右上角:若
px >= x0 + w - r && py ,圆心 <code>(x0 + w - r, y0 + r) - 左下角:若
px = y0 + h - r,圆心(x0 + r, y0 + h - r) - 右下角:若
px >= x0 + w - r && py >= y0 + h - r,圆心(x0 + w - r, y0 + h - r)
- 左上角:若
注意:所有比较用 和 <code>>=,边界点算“内部”。避免浮点误差时,可对 r 做微小补偿(如 +1e-9),但整数坐标下通常不需要。
用 OpenCV 的 cv::Point + 自定义函数更简洁
如果你项目已用 OpenCV,不必重复造轮子。OpenCV 没有现成的 isInRoundedRect(),但可基于 cv::Rect 和 cv::Point2f 快速封装:
bool isInRoundedRect(const cv::Point2f& pt, const cv::Rect& rect, float radius) {
float x = pt.x, y = pt.y;
float x0 = rect.x, y0 = rect.y;
float w = rect.width, h = rect.height;
if (x x0 + w || y y0 + h) return false;
if (x >= x0 + radius && x = y0 + radius && y = x0 + w - radius && y = y0 + h - radius) { // 左下
dx = x - (x0 + radius); dy = y - (y0 + h - radius);
} else if (x >= x0 + w - radius && y >= y0 + h - radius) { // 右下
dx = x - (x0 + w - radius); dy = y - (y0 + h - radius);
} else return false; // 落在侧边条带(已隐含在前两步中,此处防漏)
return (dx*dx + dy*dy) <p>这个函数支持浮点坐标,<code>radius</code> 超限时(比如大于半宽/半高)行为未定义,调用前应校验。</p><h3>性能与易错点:半径越界、坐标系方向、整数溢出</h3><p>最容易忽略的是 <code>radius</code> 合理性检查:若 <code>radius > w/2 || radius > h/2</code>,四个圆角会重叠甚至反向,此时逻辑失效。应在函数入口加断言或提前 clamp:</p>
radius = std::min(radius, std::min(w, h) * 0.5f);- 注意图形 API 常用 y 轴向下(如 OpenCV、SDL),而数学坐标系 y 向上——若你的坐标系是 OpenGL 风格,需翻转
y再判断 - 整数运算下,
r * r可能溢出(尤其int16_t坐标 + 大圆角),建议统一转long long或float计算距离平方 - 如果矩形是中心锚定(而非左上锚定),需先将点平移到局部坐标系:减去中心点,再按 ±
w/2、±h/2和圆角逻辑判断
圆角判断本身不重,但频繁调用时,把重复计算(如圆心坐标)提到外层预计算,比每次现场算快一点;不过多数场景下,分支预测和内存访问模式的影响远大于这点计算开销。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











