算法竞赛入门经典训练指南-4.1.2学习笔记

来源:互联网 发布:多目标人工蜂群算法 编辑:程序博客网 时间:2024/05/18 11:27

直线的参数表示,直线可以用直线上一点P0和方向向量v表示。

直线上所有点P满足P=P0+tv,其中t称为参数。如果已知直线上的

两个不同点A和B,则方向向量为B-A。所以参数方程为A+(B-A)t

参数方程设定范围即可表示线段和射线。

Point GetLineInstersection(Point P, Vector v, Point Q, Vector w){Vector u = P - Q;double t = Cross(w, u) / Cross(v, w);return P + v*t;}double Distance(Point P, Point A, Point B){Vector v1 = B - A, v2 = p - A;return fabs(Cross(v1, v2)  / Length(v1));//不取绝对值,得到的是有向距离}

点到先端的距离,点到线段的距离有两种可能。

投影点为Q,如果Q在线段AB上,则所求距离就是P点到直线AB的距离。

Q在射线BA上,则所求距离为QA的距离

否则为QB的距离,判断Q的位置可以用点积进行。

double DistanceToSegment(Point P, Point A, Point B){if(A == B) return Length(P -A);vector v1 = B - A, v2 = P - A, v3 = P - B;if(dcmp(Dot(v1, v2)) < 0) return Length(v2);else if(dcmp(Dot(v1, v3)) > 0) return Length(v3);else return fabs(Cross(v1, v2)) / Length(v1);}

点在直线上的投影。把直线AB写成参数式A+tv,并且设Q的参数为t0,那么Q=A+t0*v。

根据PQ垂直于AB,两个向量的点积应该为0,因此Dot(v,P-(A+t0v))=0.

根据分配率,有Dot(v,P-A)-t0*Dot(v,v)=0,这样就可以解出t0,从而得到Q点。

Point GetLineProjection(Point P, Point A, Point B){Vector v = B - A;return A + v*(Dot(v, P-A) / Dot(v, v));}

线段相交判定充要条件,每条线段的两个端点都在另一条线段的两侧。

bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2){double c1 = Cross(a2-a1, b1-a1), c2 = Cross(a2-a1, b2-a1),c3 = Cross(b2-b1, a1-b1), c4 = Cross(b2-b1, a2-b1);return dcmp(c1)*dcmp(c2) < 0 && dcmp(c3)*dcmp(c4)<0;}

如果c1,c2都是0,表示两线段共线,这时可能会有部分重叠的情况。都不是0,只有一种

判断方式,就是判断一个点shifou在一条线段上。

bool OnSegment(Point p, Point a1, Point a2){return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p))<0;}



0 0
原创粉丝点击