椭圆内点判别法:先平移旋转至标准位,再代入标准方程判断;结果>0在内部,=0在边上,<0在外部。

椭圆标准方程判别法(中心在原点)
最直接的方式是代入椭圆标准方程:若点 (x, y) 满足 (x*x)/(a*a) + (y*y)/(b*b) ,则在内部;等于 1 在边界;大于 1 在外部。这里 <code>a 和 b 是半长轴、半短轴长度,必须为正数。
注意:这个公式只适用于椭圆中心在原点、主轴与坐标轴对齐的情况。实际代码中要防止除零——a 或 b 为 0 时无意义,应提前校验:
-
a > 0 && b > 0必须成立,否则不是合法椭圆 - 浮点比较建议用
abs(... - 1.0) 判断边界,而非直接 <code>== - 若
x或y极大,先做范围粗筛(比如abs(x) >= a可直接返回 false)能避免溢出或无谓计算
任意位置+旋转椭圆的通用判断(使用矩阵变换)
当椭圆中心在 (cx, cy)、长轴方向与 x 轴夹角为 theta(弧度)时,不能直接套用标准方程。正确做法是把点平移并旋转回标准位,再用上一节方法判断。
核心步骤是构造逆变换:先平移 (x - cx, y - cy),再绕原点逆时针旋转 -theta,得到新坐标 (x', y'),然后代入 (x'*x')/(a*a) + (y'*y')/(b*b) 。
旋转部分可展开为:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
double cos_t = cos(-theta), sin_t = sin(-theta); double x_prime = (x - cx) * cos_t - (y - cy) * sin_t; double y_prime = (x - cx) * sin_t + (y - cy) * cos_t;
常见错误:
- 混淆旋转方向:要用
-theta实现“把点转回标准位”,而不是+theta - 误用角度制:C++ 的
cos/sin接收弧度,传入theta前确认单位(如用了deg2rad) - 未处理数值误差:旋转后若
a或b很小,x_prime或y_prime略微超限可能误判,建议加eps = 1e-9容差
用 OpenCV 的 pointPolygonTest 近似判断(仅限离散化场景)
OpenCV 没有原生椭圆包含判断函数,但可通过采样生成多边形逼近椭圆,再调用 pointPolygonTest。这适合对精度要求不高、且已引入 OpenCV 的项目。
关键限制:
-
pointPolygonTest对闭合曲线要求顶点数足够(一般 ≥ 32),太少会导致漏判或误判 - 返回值 > 0 表示内部,= 0 表示边上,
- 性能比解析法差一个数量级,每帧判断上千点时不推荐
- 需手动构建椭圆轮廓:
ellipse2Poly(center, axes, angle, 0, 360, 10)生成点集,再转成Mat或vector<point></point>
为什么不用射线交点法?
理论上可用“从点向右发射水平射线,统计与椭圆交点个数是否为奇数”来判断,但实际不实用:
- 求解椭圆与直线交点需解二次方程,判别式、根区间判断逻辑复杂,易出错
- 边界情况多:射线过焦点、相切、与顶点重合等,需大量特判
- 浮点误差放大明显,尤其在椭圆极扁(
b )时,交点计算不稳定 - 相比坐标变换法,它没有明显优势,反而增加维护成本
真正需要鲁棒性时,优先选解析变换法;若椭圆参数动态变化频繁,建议封装成类,缓存 cos(-theta)、sin(-theta) 等中间量,避免重复三角计算。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










