计算几何_线段交点的快速排斥_跨立实验

附上题的地址

https://vjudge.net/problem/HDU-1086#

// 点是否在矩形
// 矩形点是 st 和 ed 
bool IsPointInRectangle(Point jpt, Point st, Point ed) 
{
    if (min(st.x, ed.x) <= jpt.x &&
        max(st.x, ed.x) >= jpt.x &&
        min(st.y, ed.y) <= jpt.y &&
        max(st.y, ed.y) >= jpt.y)
        return true;
    return false;
}

/*
两线段相交分为"规范相交"和"非规范相交"。 
"规范相交"指的是两条线段恰有唯一一个不是端点的公共点;
而如果一条线段的一个端点在另一条线段上,或者两条线段部分重合,则视为“非规范相交”,
*/ 
bool IsSegmentIntersect(Point A, Point B, Point C, Point D) {
    // 快速排斥
/*    
    //  快速排斥 好理解版本  判断在不在矩形内.  
    if (IsPointInRectangle(C, A, B) && IsPointInRectangle(D, A, B)) return false;
    if (GetCross(A, C, B) * GetCross(A, D, B) <= 0.0 &&
        GetCross(C, A, D) * GetCross(C, B, D) <= 0.0)  
        return true;
    return false;*/
    
    // 前3句是快速排斥 
    // 后2句是跨立实验  <= 表示允许重叠 端点在另一线段上 < 则不允许 
    if (max(A.x, B.x) >= min(C.x, D.x) &&
        min(A.x, B.x) <= max(C.x, D.x) &&
        max(A.y, B.y) >= min(C.y, D.y) &&
        GetCross(A, C, B) * GetCross(A, D, B) <= 0.0 &&
        GetCross(C, A, D) * GetCross(C, B, D) <= 0.0 )
        return true;
    return false;
} 

线段封装

struct Segment {
    Point st;
    Point ed;
    void Read() {
        scanf("%lf%lf%lf%lf", &st.x, &st.y, &ed.x, &ed.y);
    } 
}Sg[128];

bool IsSegmentIntersect(Segment A, Segment B) {
    return IsSegmentIntersect(A.st, A.ed, B.st, B.ed);
}
原文地址:https://www.cnblogs.com/cgjh/p/9412887.html