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