【模板】計算幾何--線段相交問題

  在幾何問題中,運用向量的內積和外積進行計算是很是方便的。對於二維向量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之間。spa

  要判斷兩條線段是否有交點,能夠先求出兩條線段所在直線的交點,再判斷交點是否在兩條線段上。(這裏要注意考慮兩條線段平行的狀況,這種狀況下不能直接求兩條直線的交點,只要直接判斷兩條線段是否可能在端點處相交便可)。code

 

 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 }
相關文章
相關標籤/搜索