圆角矩形由中心矩形与四个象限圆弧组成,关键参数为left、top、right、bottom及radius(需满足r≤min((right−left)/2,(bottom−top)/2));判断点(x,y)是否在内,先验其是否在外包围矩形内,再按所在象限计算平移后坐标(dx,dy),通过dx²+dy²≤r²判定是否落入对应圆角区,radius=0时退化为普通矩形判断。

圆角矩形的数学定义和关键参数
圆角矩形不是标准几何图元,它由一个中心矩形 + 四个象限圆弧组成。判断点 (x, y) 是否在其内部,核心是:先判断是否落在外包围矩形内,再根据所在象限处理圆角裁剪逻辑。
你需要明确四个参数:left、top、right、bottom(矩形边界),以及圆角半径 radius。注意:radius 不能超过矩形宽高的一半,否则实际生效半径应为 min(radius, (right - left) / 2, (bottom - top) / 2) —— 这是容易被忽略的边界条件。
分区域判断:用相对坐标简化计算
把点映射到以左上角为原点的局部坐标系,再按象限分类处理。关键不是写一堆 if-else,而是把点“归入”四类区域之一:
- 若
x 且 <code>y → 左上角圆角区:检查 <code>(x - (left + radius))² + (y - (top + radius))² - 若
x > right - radius且y → 右上角圆角区:检查 <code>(x - (right - radius))² + (y - (top + radius))² - 若
x > right - radius且y > bottom - radius→ 右下角圆角区:同理平移后算距离平方 - 若
x 且 <code>y > bottom - radius→ 左下角圆角区 - 其余情况:只要
x ∈ [left, right]且y ∈ [top, bottom]就在内部(中间矩形区)
避免浮点误差和性能陷阱
不要用 sqrt 计算欧氏距离——直接比较平方值,既快又避开了浮点精度问题。同时注意:如果 radius == 0,整个逻辑可退化为普通矩形判断,建议提前分支处理,避免无谓的四次圆心距计算。
示例片段(C++17):
bool pointInRoundedRect(double x, double y,
double left, double top,
double right, double bottom,
double radius) {
if (radius = left && x = top && y right || y bottom) return false;
<pre class="brush:php;toolbar:false;">// 归一化到最近圆心的偏移
double dx = 0, dy = 0;
if (x right - r) dx = x - (right - r);
if (y bottom - r) dy = y - (bottom - r);
return dx * dx + dy * dy <p>}</p>SVG 或 UI 框架中坐标的常见偏差
很多 UI 系统(如 Qt、Skia、Canvas API)的圆角矩形使用 rx/ry 分离控制水平/垂直半径,而上述算法假设 rx == ry。若你面对的是非等角圆角(即椭圆弧),就不能简单套用圆心距公式,必须改用椭圆方程:((dx / rx)² + (dy / ry)²) —— 这里 <code>dx、dy 要相对于对应象限的椭圆中心,且需确保 rx、ry 已按实际尺寸 clamped。
真正麻烦的不是公式本身,而是不同库对“圆角矩形”的定义差异:有的以 border 中线为基准,有的以 content box 为基准,还有的默认裁剪行为会影响有效 left/top 值。动手前务必确认你拿到的四个边界值是否已包含圆角偏移。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











