HDU ACM 1086 You can Solve a Geometry Problem too->判断两线段是否相交

来源:互联网 发布:所有云计算上市公司 编辑:程序博客网 时间:2024/05/18 09:05


#include<iostream>using namespace std;struct point{double x,y;};double dir(const point& p1,const point& p2,const point& p)  //二维向量叉乘{return (p1.x-p.x)*(p2.y-p.y)-(p2.x-p.x)*(p1.y-p.y);}bool on_segment(const point& p1,const point& p2,const point& p) //判断点是否在线段上,结合segments_intersect函数{double max,min;max=p1.x>p2.x?p1.x:p2.x;min=p1.x<p2.x?p1.x:p2.x;if(p.x>=min && p.x<=max)return true;elsereturn false;}bool segments_intersect(const point& p1,const point& p2,const point& p3,const point& p4)//判断两线段是否相交{double d1,d2,d3,d4;d1=dir(p1,p2,p3);d2=dir(p1,p2,p4);d3=dir(p3,p4,p1);d4=dir(p3,p4,p2);if(d1*d2<0 && d3*d4<0)         //两种情况都需要满足return true;if(d1==0 && on_segment(p1,p2,p3))   //四种情况判断两条线段共线情况return true;if(d2==0 && on_segment(p1,p2,p4))return true;if(d3==0 && on_segment(p3,p4,p1))return true;if(d4==0 && on_segment(p3,p4,p2))return true;return false;}int main()      {int n,i,j,ans;point p[105][2];while(scanf("%d",&n) && n){ans=0;for(i=0;i<n;i++)scanf("%lf%lf%lf%lf",&p[i][0].x,&p[i][0].y,&p[i][1].x,&p[i][1].y);for(i=0;i<n;i++)for(j=i+1;j<n;j++)ans+=segments_intersect(p[i][0],p[i][1],p[j][0],p[j][1]);printf("%d\n",ans);}    return 0;      }
分析:

若是判断直线和线段是否有交点,把on_segment去掉就可以了

判断两线段是否相交:
我们分两步确定两条线段是否相交:

  (1)快速排斥试验

    设以线段 P1P2 为对角线的矩形为R, 设以线段 Q1Q2 为对角线的矩形为T,如果R和T不相交,显然两线段不会相交。

  (2)跨立试验

    如果两线段相交,则两线段必然相互跨立对方。若P1P2跨立Q1Q2 ,则矢量 ( P1 - Q1 ) 和( P2 - Q1 )位于矢量( Q2 - Q1 ) 的两侧,即( P1 - Q1 ) × ( Q2 - Q1 ) * ( P2 - Q1 ) × ( Q2 - Q1 ) < 0。上式可改写成( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) > 0。当 ( P1 - Q1 ) × ( Q2 - Q1 ) = 0 时,说明 ( P1 - Q1 ) 和 ( Q2 - Q1 )共线,但是因为已经通过快速排斥试验,所以 P1 一定在线段 Q1Q2上;同理,( Q2 - Q1 ) ×(P2 - Q1 ) = 0 说明 P2 一定在线段 Q1Q2上。所以判断P1P2跨立Q1Q2的依据是:( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) >= 0。同理判断Q1Q2跨立P1P2的依据是:( Q1 - P1 ) × ( P2 - P1 ) * ( P2 - P1 ) × ( Q2 - P1 ) >= 0。具体情况如下图所示:

    

  在相同的原理下,对此算法的具体的实现细节可能会与此有所不同,除了这种过程外,大家也可以参考《算法导论》上的实现。

关于计算几何算法概述网站 http://dev.gameres.com/Program/Abstract/Geometry.htm 一个挺好的网站

参考自:http://www.cnblogs.com/dxp498688071/archive/2011/03/02/1969337.html

0 0