线段判交模板


struct Point { double x, y;
    Point(){}
    Point(double a, double b): x(a), y(b){}
};

typedef Point Vector;
Vector operator + (Vector a, Vector b) { return Vector( a.x + b.x, a.y + b.y ); }
Vector operator - (Vector a, Vector b) { return Vector( a.x - b.x, a.y - b.y ); }
Vector operator * (Vector a, double p) { return Vector( a.x * p, a.y * p); }
Vector operator / (Vector a, double p) { return Vector( a.x / p, a.y / p); }

int dcmp(double x) { if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; } // 精准判断正负号

// 点积,模长,两向量夹角, 向量角度,叉积,三角形面积,极角,逆时针旋转
double Dot(Vector a, Vector b) { return a.x * b.x + a.y * b.y; }
double Length(Vector a) { return sqrt( Dot(a, a) ); }
double Angle(Vector a, Vector b) { return acos(Dot(a, b) / Length(a) / Length(b)); }
double Angle(Vector a) { return atan2(a.y, a.x);}
double Cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; } // 大于0时,b在a的逆时针方向
double Area(Point A, Point B, Point C) { return Cross(B - A, C - A) / 2; } // 三角形面积叉乘公式
double PolarAngle(Vector a) { return atan2(a.y, a.x); }
Vector Rotate (Vector a, double rad) { return Vector( a.x*cos(rad) - a.y*sin(rad), a.x*sin(rad) + a.y*cos(rad) ); }

bool operator < (Vector a, Vector b) {
    if(dcmp(PolarAngle(a) - PolarAngle(b)) == 0)
        return dcmp(a.x - b.x) == 0 ? dcmp(a.y - b.y) < 0 : dcmp(a.x - b.x) < 0;
    return dcmp(PolarAngle(a) - PolarAngle(b)) < 0;
} //优先级:极角 > x > y
bool operator == (Vector a, Vector b) { return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0; }


struct Line{ // 有向直线
    Point A, B;
    Line(){};
    Line(Point P, Point Q) : A(P), B(Q) {}
};

// 判断线段AB是否跨立MN
bool straddle (Point A, Point B, Point M, Point N) {
    Vector p0 = { N.x - M.x , N.y - M.y }; // 向量 MN
    Vector p1 = { A.x - M.x , A.y - M.y }; // 向量 MA
    Vector p2 = { B.x - M.x , B.y - M.y }; // 向量 MB
    return Cross(p1, p0) * Cross(p2, p0) <= 0;
}

// 判断 线段AB为对角线构成的矩形 和 MN线段为对角线构成的矩形 是否存在重叠
bool overlap (Point A, Point B, Point M, Point N){
    Point P = { max(min(A.x, B.x), min(M.x, N.x)), max(min(A.y, B.y), min(M.y, N.y))};
    Point Q = { min(max(A.x, B.x), max(M.x, N.x)), min(max(A.y, B.y), max(M.y, N.y))};
    return P.x <= Q.x && P.y <= Q.y;
}

// 判断线段AB和MN是否相交
bool intersect (Point A, Point B, Point M, Point N) {
    return straddle(A, B, M, N) && straddle(M, N, A, B) && overlap(A, B, M, N);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值