1 /* 2 部分重合,端点重合,点边重合都会返回true 3 */ 4 struct PT{ 5 double x,y;//点的坐标 6 PT(double x = 0, double y = 0) : x(x), y(y){} 7 //bool operator 8 };//线段的2个端点,MAX表示线段条数的上限 9 10 double Min(double a,double b){ 11 return a<b?a:b; 12 } 13 14 double Max(double a,double b){ 15 return a>b?a:b; 16 } 17 18 double Dir(PT p1,PT p2,PT p0){//判断线段p0p2相对于线段p0p1的位置 19 //向量p0p1叉乘向量p0p2,转化为行列式进行计算 20 //结果若大于0,则p0p2沿顺时钟方向旋转可得到与p0p1同方向的向量 21 //结果若小于0,则p0p2沿逆时钟方向旋转可得到与p0p1同方向的向量 22 //结果若等于0,则p0p2与p0p1共线 23 return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); 24 } 25 26 int OnSgm(PT p1,PT p2,PT p0){ 27 double minx,maxx,miny,maxy; 28 minx=Min(p1.x,p2.x); 29 maxx=Max(p1.x,p2.x); 30 miny=Min(p1.y,p2.y); 31 maxy=Max(p1.y,p2.y); 32 return minx<=p0.x&&p0.x<=maxx&&miny<=p0.y&&p0.y<=maxy; 33 } 34 35 bool Intersect(PT p1,PT p2,PT p3,PT p4){//两线段相交有两种情况 36 double d1,d2,d3,d4; 37 d1=Dir(p4,p1,p3); 38 d2=Dir(p4,p2,p3); 39 d3=Dir(p2,p3,p1); 40 d4=Dir(p2,p4,p1); 41 if(d1*d2<0&&d3*d4<0)//两线段互相跨过 42 return 1; 43 //一条直线有一个端点在另外一条直线上 44 if(d1==0&&OnSgm(p3,p4,p1)) 45 return 1; 46 if(d2==0&&OnSgm(p3,p4,p2)) 47 return 1; 48 if(d3==0&&OnSgm(p1,p2,p3)) 49 return 1; 50 if(d4==0&&OnSgm(p1,p2,p4)) 51 return 1; 52 return 0;//两线段不相交返回false 53 }