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
- HDU ACM 1086 You can Solve a Geometry Problem too->判断两线段是否相交
- HDU 1086 You can Solve a Geometry Problem too 判断任意两线段是否相交
- HDU 1086 You can Solve a Geometry Problem too(判断线段是否相交,非规范相交)
- HDU 1086 You can Solve a Geometry Problem too(判断两线段是否相交)跨立实验
- HDU 1086 You can Solve a Geometry Problem too(判断两条直线是否相交)
- hdu1086 You can Solve a Geometry Problem too (判断两线段是否相交)
- You can Solve a Geometry Problem too----判断两线段是否相交
- [ACM] hdu You can Solve a Geometry Problem too (线段是否相交及交点个数)
- hdu You can Solve a Geometry Problem too(判断两条线段相交)
- hdoj-1086-You can Solve a Geometry Problem too 判断线段是否相交
- 杭电 1086 You can Solve a Geometry Problem too 判断线段是否相交.
- HDU 1086 You can Solve a Geometry Problem too 两线段相交模板
- 线段是否相交问题 HDU 1086 You can Solve a Geometry Problem too
- hdu-1086 You can Solve a Geometry Problem too(线段是否相交)
- Hdu 1086 You can Solve a Geometry Problem too[判断线段相交,完整版]
- HDU 1086 You can Solve a Geometry Problem too(判断线段相交)
- HDU 1086You can Solve a Geometry Problem too(判断线段相交模板题)
- HDU 1086 You can Solve a Geometry Problem too (计算几何 判断线段相交)
- ‘东方之星’之倾覆的原因分析(仅供参考)
- Java NIO 系列教程
- 6.3日日志记录
- cocos2dx 3.6 mac os 环境配置
- bzoj 2243 树链剖分 染色
- HDU ACM 1086 You can Solve a Geometry Problem too->判断两线段是否相交
- 使用Unity3D编写ARPG游戏——角色属性的定义与实现(一)
- NGS项目一:RNA-Seq数据的Workflow
- 赵匡胤为何不把皇位传给儿子却传弟弟赵光义
- java继承和接口的区别
- 深度学习的资源
- Android中android:id="@id/变量名"和android:id="@+id/变量名"的区别
- C/C++语言统计文件中单词出现个数
- Ogre Moc笔记