我正在尝试找到一种算法,该算法针对查找(无限)线和线段之间是否存在交叉点进行了优化。
在 SO 和其他网站上,我看到了许多线段 - 线段相交和线 - 线相交算法,但找到了一个“更简单?” 一条无限线(从一个方向的一点)和一条线段的版本非常难。
我目前有类似(线段 - 线段交点):
bool lineSegmentsIntersect(float pX, float pY, float p2X, float p2Y, float qX, float qY, float q2X, float q2Y)
{
// p and p2 define the first line segment
Point2D p(pX, pY);
Point2D p2(p2X, p2Y);
// q and q2 define the second line segment
Point2D q(qX, qY);
Point2D q2(q2X, q2Y);
Point2D r = p2 - p;
Point2D s = q2 - q;
float uNumerator = (q-p)*r;
float denominator = r*s;
if (uNumerator == 0 && denominator == 0) {
// co-linear, so do they overlap?
return ((q.x - p.x < 0) != (q.x - p2.x < 0) != (q2.x - p.x < 0) != (q2.x - p2.x < 0)) ||
((q.y - p.y < 0) != (q.y - p2.y < 0) != (q2.y - p.y < 0) != (q2.y - p2.y < 0));
}
if (denominator == 0) {
// lines are parallel
return false;
}
float u = uNumerator / denominator;
float t = ((q-p)*s) / denominator;
return (t >= 0) && (t <= 1) && (u >= 0) && (u <= 1);
}
其中 * 运算符定义为:
float Point2D::operator*(const Point2D &rhs)
{
return x*rhs.y - y*rhs.x;
}
虽然我正在寻找更简单/更快的东西。我正在尝试检查一个点是否在一个封闭的形状内(该形状由一些点和它们之间的(线性插值)直线定义。)
从这一点开始,我向预定义的方向射出一条射线。
最好是 [1, 0] 或 [0, 1] (这可以用作给定的常数),如果这使我认为可能的数学更容易。
然后我检查光线是否与每个线段相交,如果是奇数,则它在形状内。
我在想的一些事情:
如果我们决定总是向上射出一条射线,那么如果线段的两个点都低于我们已经知道它不相交的点。