判断线段相交--模板
题目:Area,
规范相交:两条线段恰有一个不是端点的公共点。
即如果一条线段的一个端点恰在另一条线段上则不视为相交;如果两条线段部分重合,也不视为相交。
非规范相交:两条线段存在公共部分。(上述两种情况都可视为非规范相交)
其中a~f是非规范相交; g,h是不相交; a~c有唯一的交点;d~f有无数个交点。
判断线段是否相交,如果是规范相交则求出交点坐标p并返回1,如果是非规范相交则直接返回2,否则返回0;
代码:
int segcross(Point a, Point b, Point c, Point d, Point &p) // 判断线段相交 { double s1, s2, s3,s4; int d1, d2, d3, d4; d1 = dblcmp(s1 = xmult(a,b,c)); d2 = dblcmp(s2 = xmult(a,b,d)); d3 = dblcmp(s3 = xmult(c,d,a)); d4 = dblcmp(s4 = xmult(c,d,b)); // 若规范相交则求交点的代码 // d1^d2==-2相当于d1*d2<0; // 跨立实验 if ((d1 ^ d2) ==- 2 && (d3 ^ d4) ==- 2 ) // "(d1^d2)"这个小括号是必须的,否则会错 { p.x = (c.x * s2 - d.x * s1) / (s2 - s1); p.y = (c.y * s2 - d.y * s1) / (s2 - s1); return 1 ; } // 判断非规范相交 // d1==0, 则证明a,b,c三点共线; // 如果dblcmp(dmult(c,a,b))<0, 则说明点c在点a,b的中间; // 如果dblcmp(dmult(c,a,b))==0,则说明点c与线段ab的端点a,或者b重合。 // 如果dblcmp(dmult(c,a,b))==0,则说明点c在线段ab的外面。 if (d1 == 0 && dblcmp(dmult(c,a,b)) <= 0 || d2 == 0 && dblcmp(dmult(d,a,b)) <= 0 || d3 == 0 && dblcmp(dmult(a,c,d)) <= 0 || d4 == 0 && dblcmp(dmult(b,c,d)) <= 0 ) { return 2 ; } return 0 ; }