线段相交(仅交叉,不接触)

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;