int sgn(double x){ if(abs(x)<eps) return 0; if(x<0) return -1; return 1; } struct Point{ double x,y; Point(){} Point(double xx,double yy):x(xx),y(yy){} Point operator + (const Point& b){ return Point(x+b.x,y+b.y); } Point operator - (const Point& b){ return Point(x-b.x,y-b.y); } double operator * (const Point& b){ return x*b.x+y*b.y; } double operator ^ (const Point& b){ return x*b.y-b.x*y; } }; struct Line{ Point s,e; Line(){} Line(Point ss,Point ee){ s=ss,e=ee; } }line[maxn];
以上是点和线的基本定义,函数sgn用来判断double型变量x的符号。
1 . 叉积判断直线和线段相交:
double xmult(Point p0,Point p1,Point p2){ //p0p1 ^ p0p2 return (p1-p0)^(p2-p0); } bool seg_inter_line(Line l1,Line l2){ //判断直线l1和线段l2是否相交 return sgn(xmult(l2.s,l1.s,l1.e))*sgn(xmult(l2.e,l1.s,l1.e))<=0; }
2. 叉积判断线段相交(证明见https://blog.csdn.net/wordsin/article/details/79215342):
bool inter(Line l1,Line l2){ //判断线段l1和l2是否相交 return max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x)&& max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x)&& max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y)&& max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y)&& sgn((l1.s-l2.s)^(l2.e-l2.s))*sgn((l1.e-l2.s)^(l2.e-l2.s))<=0&& sgn((l2.s-l1.s)^(l1.e-l1.s))*sgn((l2.e-l1.s)^(l1.e-l1.s))<=0; }
3. 叉积判断直线相交,并相交时求交点(证明见https://www.cnblogs.com/jklover/p/10484313.html):
void solve(){ //判断ab和cd直线的关系 Point a=Point(x1,yy1); Point b=Point(x2,yy2); Point c=Point(x3,yy3); Point d=Point(x4,yy4); if(sgn((b-a)^(d-c))==0){ if(sgn((c-a)^(d-a))==0) flag=0; //重合 else flag=1; //平行 return; } flag=2; //相交 double t=((a-c)^(c-d))/((a-b)^(c-d)); ans=Point(a.x+(b.x-a.x)*t,a.y+(b.y-a.y)*t); //交点 }