圆角矩形由四条直边和四个四分之一圆弧构成,点在其中需分区域判断:角区用圆心距判定,边区用线性约束;半径超限时须截断为宽高最小值的一半,否则导致退化或逻辑错误。

圆角矩形的数学定义决定了不能只靠简单边界比较
带圆角的矩形本质是四个直边 + 四个四分之一圆弧拼接而成。直接用 x >= left && x = top && y 会把圆角区域误判为内部,或把靠近圆角的合法点拒之门外。关键在于:先判断点是否落在“主矩形”内(即去掉圆角后的矩形),再对落在四个角附近的点单独做圆距离判定。
分区域判断:主矩形区、角区、边缘区
把整个区域划分为 9 个逻辑子区域(类似井字格),但实际只需关注 5 类:
- 若
point.x在[left + radius, right - radius]且point.y在[top + radius, bottom - radius]→ 点在中心矩形区,直接返回true - 若
point.x 且 <code>point.y → 左上角区:检查 <code>(point.x - (left + radius))² + (point.y - (top + radius))² - 若
point.x > right - radius且point.y → 右上角区:用 <code>(point.x - (right - radius))² + (point.y - (top + radius))² - 若
point.x 且 <code>point.y > bottom - radius→ 左下角区 - 若
point.x > right - radius且point.y > bottom - radius→ 右下角区 - 其余情况(如左/右/上/下边缘但非角)→ 对应边界的线性约束即可,例如左边缘:只要
point.x >= left且point.y在[top + radius, bottom - radius]内就成立
注意 radius 超出矩形尺寸时的退化情况
当圆角半径 radius 大于矩形宽高一半时,圆角会重叠,图形不再是标准圆角矩形——它会变成椭圆或胶囊形甚至圆形。代码里必须提前校验:if (radius > std::min(width, height) / 2.0) radius = std::min(width, height) / 2.0;,否则角区判定会出现负坐标或逻辑矛盾。很多库(如 Qt 的 QRectF.contains())内部也做此截断,但自己实现时容易漏掉。
C++ 实现示例(仅核心逻辑)
bool isPointInRoundedRect(double px, double py,
double left, double top,
double width, double height,
double radius) {
const double right = left + width;
const double bottom = top + height;
// 截断 radius 防止退化
radius = std::min(radius, std::min(width, height) / 2.0);
if (radius // 中心矩形区
if (px >= left + radius && px = top + radius && py = right - radius && py = bottom - radius) { // 左下
double dx = px - (left + radius);
double dy = py - (bottom - radius);
return dx * dx + dy * dy = right - radius && py >= bottom - radius) { // 右下
double dx = px - (right - radius);
double dy = py - (bottom - radius);
return dx * dx + dy * dy = left && px = top + radius && py = top && py = left + radius && px <p>}</p>
这个函数没做输入合法性检查(如 width ),真实项目中建议加 guard;另外浮点比较未引入 epsilon,对高精度场景需替换为 <code>std::abs(a - b) 。最易忽略的是:圆角矩形通常以左上为原点定义,但某些图形 API(如 Skia)用中心点,坐标系 y 轴方向也可能相反——传参前务必确认坐标系约定。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











