线段相交(仅交叉,不接触)
Line Segment Intersection (Crossing only, no touching)
我试图找到 "Line Segment Crossings"。所以我希望下面的函数 return 只有当两条线真的相互交叉时才为真,而不是如果它们 start/end 在相同的点上。从我读到的内容来看,似乎有一个 "trivial" 数学解决方案,但无论在哪里提到它,都没有以我能理解的方式真正解释。
下面是一个正确检测线段交点的函数,包括"touching"个点。有没有一种简单的方法可以根据我的需要对其进行修改?
非常感谢您的帮助!
inline double Dot(sf::Vector2f a, sf::Vector2f b) { return (a.x*b.x) + (a.y*b.y); }
inline double PerpDot(sf::Vector2f a, sf::Vector2f b) { return (a.y*b.x) - (a.x*b.y); }
static bool LineCollision(const sf::Vector2f A1, const sf::Vector2f A2,
const sf::Vector2f B1, const sf::Vector2f B2,
double* out = 0)
{
sf::Vector2f a(A2 - A1);
sf::Vector2f b(B2 - B1);
double f = PerpDot(a, b);
if (!f) // lines are parallel
return false;
sf::Vector2f c(B2 - A2);
double aa = PerpDot(a, c);
double bb = PerpDot(b, c);
if (f < 0)
{
if (aa > 0) return false;
if (bb > 0) return false;
if (aa < f) return false;
if (bb < f) return false;
}
else
{
if (aa < 0) return false;
if (bb < 0) return false;
if (aa > f) return false;
if (bb > f) return false;
}
if (out)
*out = 1.0 - (aa / f);
return true;
}
要排除段结束,将所有内部 if's
中的严格比较 <
和 >
更改为 <=
和 >=
,如下所示:
if (aa >= 0) return false;
我试图找到 "Line Segment Crossings"。所以我希望下面的函数 return 只有当两条线真的相互交叉时才为真,而不是如果它们 start/end 在相同的点上。从我读到的内容来看,似乎有一个 "trivial" 数学解决方案,但无论在哪里提到它,都没有以我能理解的方式真正解释。
下面是一个正确检测线段交点的函数,包括"touching"个点。有没有一种简单的方法可以根据我的需要对其进行修改?
非常感谢您的帮助!
inline double Dot(sf::Vector2f a, sf::Vector2f b) { return (a.x*b.x) + (a.y*b.y); }
inline double PerpDot(sf::Vector2f a, sf::Vector2f b) { return (a.y*b.x) - (a.x*b.y); }
static bool LineCollision(const sf::Vector2f A1, const sf::Vector2f A2,
const sf::Vector2f B1, const sf::Vector2f B2,
double* out = 0)
{
sf::Vector2f a(A2 - A1);
sf::Vector2f b(B2 - B1);
double f = PerpDot(a, b);
if (!f) // lines are parallel
return false;
sf::Vector2f c(B2 - A2);
double aa = PerpDot(a, c);
double bb = PerpDot(b, c);
if (f < 0)
{
if (aa > 0) return false;
if (bb > 0) return false;
if (aa < f) return false;
if (bb < f) return false;
}
else
{
if (aa < 0) return false;
if (bb < 0) return false;
if (aa > f) return false;
if (bb > f) return false;
}
if (out)
*out = 1.0 - (aa / f);
return true;
}
要排除段结束,将所有内部 if's
中的严格比较 <
和 >
更改为 <=
和 >=
,如下所示:
if (aa >= 0) return false;