计算几何之线段性质(二):求线段交点

来源:互联网 发布:python发邮件带附件 编辑:程序博客网 时间:2024/06/11 05:53

求线段的交点即求线段交点的坐标。若已确定两线段相交,可以通过解析几何中的直线方程来求解交点,这里介绍另外的一种方法。叉积multi(p1,p2,p0)可以看做是由点P1,P2,P0和P1+P2,这四个点围成的平行四边形的面积(如下图所示),及三角形P0P1P2的面积S=1/2 multi(P1,P2,P0)


在下图中,线段AB和CD相交于点P。



我们分别从D点和C点做AB的垂线DD1和CC1,由于△DD1P∽△CC1P,因此我们有|DD1| / |CC1|=|DP| / |CP|。又因为S△ABD=DD1*AB/2,S△ABC=CC1*AB/2,所以:

|DP| / |CP|=S△ABD/S△ABC=|AD × AB| / |AC × AB|=|multi(D,B,A)| / |multi(C,B,A)|

又因为|DP| / |CP|=(XD-XP)/(XP-XC)=(YD-YP)/(YP-YC)

所以有:

XP=(S△ABD * XC + S△ABC * XD)/(S△ABD + S△ABC)

    =(multi(D,B,A)* XC - multi(C,B,A)* XD)/(multi(D,B,A)- multi(C,B,A))

YP=(S△ABD * YC + S△ABC * YD)/(S△ABD + S△ABC)

    =(multi(D,B,A)* YC - multi(C,B,A)* YD)/(multi(D,B,A)- multi(C,B,A))

由此得出计算线段u和v交点的算法,参考代码如下:

#include <cstdio>using namespace std;typedef struct node{    double x,y;}point;typedef struct line{    point start,end;}segment;double multi(point p1,point p2,point p0){    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}point intersection(segment u,segment v){    point p;    p.x=(multi(v.end,u.end,u.start)*v.start.x-multi(v.start,u.end,u.start)*v.end.x)/(multi(v.end,u.end,u.start)-multi(v.start,u.end,u.start));    p.y=(multi(v.end,u.end,u.start)*v.start.y-multi(v.start,u.end,u.start)*v.end.y)/(multi(v.end,u.end,u.start)-multi(v.start,u.end,u.start));    return p;}int main(){    segment u,v;    scanf("%lf%lf%lf%lf",&u.start.x,&u.start.y,&u.end.x,&u.end.y);    scanf("%lf%lf%lf%lf",&v.start.x,&v.start.y,&v.end.x,&v.end.y);    point p=intersection(u,v);    printf("%lf  %lf\n",p.x,p.y);    return 0;}


1 0
原创粉丝点击