【模板】计算几何--线段相交问题

  在几何问题中,运用向量的内积和外积进行计算是非常方便的。对于二维向量p1=(x1,y1)和p2=(x2,y2),我们定义内积p1·p2=x1*x2+y1*y2,外积p1×p2=x1*y2-y1*x2。

  要判断点q是否在线段p1-p2上,只要先用外积跟据是否有(p1-q)×(p2-q)=0来判断点q是否在直线p1-p2上,再利用内积根据是否有(p1-q)·(p2-q)≤0来判断点q是否落在p1-p2之间。

  要判断两条线段是否有交点,可以先求出两条线段所在直线的交点,再判断交点是否在两条线段上。(这里要注意考虑两条线段平行的情况,这种情况下不能直接求两条直线的交点,只要直接判断两条线段是否可能在端点处相交即可)。

 

 1 #include<algorithm>
 2 #include<cmath>
 3 
 4 const double EPS=1e-10;
 5 
 6 //考虑误差的加法运算
 7 double add(double a,double b)
 8 {
 9     if(fabs(a+b)<EPS*(fabs(a)+fabs(b)))
10         return 0;
11     return a+b;
12 }
13 
14 //二维向量结构体
15 struct P
16 {
17     double x,y;
18 
19     //构造函数
20     P(){}
21     P(double x,double y):x(x),y(y){}
22 
23     //重载加法运算
24     P operator + (P p)
25     {
26         return P(add(x,p.x),add(y,p.y));
27     }
28 
29     //重载减法运算
30     P operator - (P p)
31     {
32         return P(add(x,-p.x),add(y,-p.y));
33     }
34 
35     //重载乘法运算
36     P operator * (double d)
37     {
38         return P(x*d,y*d);
39     }
40 
41     //向量内积
42     double dot(P p)
43     {
44         return add(x*p.x,y*p.y);
45     }
46 
47     //向量外积
48     double det(P p)
49     {
50         return add(x*p.y,-y*p.x);
51     }
52 };
53 
54 //判断点q是否在线段p1-p2上
55 bool on_seg(P p1,P p2,P q)
56 {
57     return (p1-q).det(p2-q)==0&&(p1-q).dot(p2-q)<=0;
58 }
59 
60 //计算直线p1-p2与直线q1-q2的交点,使用前需判断两条直线是否平行((p1-q1).det(p2-q2)==0表示两条直线平行)
61 P intersection(P p1,P p2,P q1,P q2)
62 {
63     return p1+(p2-p1)*((q2-q1).det(q1-p1)/(q2-q1).det(p2-p1));
64 }

 

posted @ 2014-02-28 21:52  ~~Snail~~  阅读(734)  评论(0编辑  收藏  举报