point GetLineRoot(point p,point A,point B)//p在直线AB上的投影 { point v = B - a;//方向向量v return A + v * (Dot(P-A,v) / Dot(v,v)); }
点在直线的那一边
假设直线上一点 P 方向向量为 v ,则 Q 在直线的那一边可以用 PQ x v 来判断。叉积为负,Q 在直线上方,
叉积为零,在直线上,叉积为正,Q 在直线下方。
点关于直线对称
1 2 3 4
point Symmetry_PL(point p,point A,point B)//p关于直线AB的对称点 { return p + (GetLineRoot(p,A,B)-p) * 2;//把Q延长两倍 }
直线相交平行
1 2 3 4 5 6
point jiao_LL(point A,point B,point C,point D)//直线AB和直线CD的交点 { point v = B - A, w = D - C, PQ = A - C;//直接套用公式就ok了 double t = Cro(PQ,w) / Cro(w,v); return A + t * v; }//用的时候记得要特判一下两直线是否平行(v,w是否共线)
点在多边形内
1 2 3 4 5 6 7 8 9 10 11 12
point p[1005]; int n; boolInPloygon(point A)//精度损失会比较大一些 { double alpha = 0; for(int i = 1; i <= n; i++) { if(i == n) alpha += fabs(Angle(p[i]-A,p[1]-A)); else alpha += fabs(Angle(p[i]-A,p[i+1]-A)); } returndcmp(alpha-2 * pai) == 0; }
点在凸多边形内
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
intInPolygn(point p,point *a) { if(Cro(p-a[1],a[2]-a[1]) < 0 || Cro(p-a[1],a[n]-a[1]) > 0) return0;//在边界外 if(pd_PS(p,a[1],a[2]) || pd_PS(p,a[n],a[1])) return2;//在边界上 int l = 2, r = n; while(r - l > 1) { int mid = (l + r)>>1; if(Cro(p-a[1],a[mid]-a[1]) < 0) l = mid; else r = mid; } if(Cro(p-a[l],a[r]-a[l]) > 0) return0;//在边界外 if(pd_PS(p,a[l],a[r])) return2;//在边界上 return1; }