杭电 1086 You can Solve a Geometry Problem too 判断线段是否相交.
来源:互联网 发布:个股评测软件 编辑:程序博客网 时间:2024/05/18 13:29
判断两线段是否相交 有一个比较容易理解的快速排斥试验.
首先我们获得两条线段 我们首先需要把两个线段都自行扩张成为一个矩形 如下图:
根据观察就能知道 如果两个矩形不相交的话 两条线段是一定不会相交的.
所以通过快速排斥试验我们就能直接pass掉很多情况.
如果给出四个点(两条线段)我们可以通过以下代码实现判断快速排斥:
if(!(min(a.x,b.x)<=max(c.x,d.x) && min(c.y,d.y)<=max(a.y,b.y)&& min(c.x,d.x)<=max(a.x,b.x) && min(a.y,b.y)<=max(c.y,d.y)))
以下是跨立试验的过程:
判断线段是否相交问题.要用到叉乘向量的知识 这里贴上向量叉乘的函数:
struct point{ double x,y;};void chacheng(point a,point b,point c){ return (c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y);}
在线段判断是否相交的函数中用处:
判断向量bc在向量ab的顺时针方向还是逆时针方向.
下边图是我盗来的图~对应理解一下吧0.0
现在请读者在纸上画出两个图 一个是线段ab和cd相交的图 一个是不相交的图
然后对应如下代码体会其作用:
u=(c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y);//c.b.a//u的正负表示bc在ab的顺时针方向还是逆时针方向. v=(d.x-a.x)*(b.y-a.y)-(b.x-a.x)*(d.y-a.y);//d.b.a//同理
u。v只考虑其大于0小于0还是为0(只考虑其实正数 负数还是0)
表示两条线段的所处几何方向
这时候你画的图就有用了~
如果ab和cd相交的情况下 向量bc是在ab的顺时针方向,并且向量bd是在ab的逆时针方向.是不是有点柳暗花明的感觉了~?
别着急 .我们继续看.如果确实有以上结论了是否就能判断ab和cd一定相交了呢?
这里上个图:
图片转载声明:http://blog.csdn.net/lishuhuakai/article/details/8263160
对应理解一下 只有一组满足是不够的~~~~~
所以这里还需要再填上另外一组 :
w=(a.x-c.x)*(d.y-c.y)-(d.x-c.x)*(a.y-c.y);//a.d.c z=(b.x-c.x)*(d.y-c.y)-(d.x-c.x)*(b.y-c.y);//b.d.c
所以如果有了
u*v<=0.00000001 && w*z<=0.00000001
我们就能判断出两线段是一定相交的了~
下边给上AC完整代码:
#include<stdio.h>#include<string.h>#include<iostream>using namespace std;struct dian{ double x,y;};struct xian{ dian a;dian b;};//判断两条线段是否相交 首先一定要通过快速排斥试验之后 再通过跨立试验之后就能判断了这两线段相交.bool judge(dian a,dian b,dian c,dian d){ //快速排斥 if(!(min(a.x,b.x)<=max(c.x,d.x) && min(c.y,d.y)<=max(a.y,b.y)&& min(c.x,d.x)<=max(a.x,b.x) && min(a.y,b.y)<=max(c.y,d.y))) //判断两条线段组成的矩形是否相交 如果不相交 那么这两条线是不会相交的. //特别要注意一个矩形含于另一个矩形之内的情况 return false; double u,v,w,z; //定a定c. //c.d在ab两端 a.b在cd两端.就能判断相交. u=(c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y);//c.b.a//u的正负表示bc在ab的顺时针方向还是逆时针方向. v=(d.x-a.x)*(b.y-a.y)-(b.x-a.x)*(d.y-a.y);//d.b.a//同理 w=(a.x-c.x)*(d.y-c.y)-(d.x-c.x)*(a.y-c.y);//a.d.c z=(b.x-c.x)*(d.y-c.y)-(d.x-c.x)*(b.y-c.y);//b.d.c return (u*v<=0.00000001 && w*z<=0.00000001);}int main(){int n; xian str[101]; while(cin>>n && n!=0) { int count=0; for(int i=0;i<n;i++) { cin>>str[i].a.x>>str[i].a.y>>str[i].b.x>>str[i].b.y; } for(int i=0;i<n;i++)//遍历所有点什么的还是比较容易理解的~. for(int j=i+1;j<n;j++) if(judge(str[i].a,str[i].b,str[j].a,str[j].b)) count++; cout<<count<<endl; } return 0;}
0 0
- 杭电 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 ACM 1086 You can Solve a Geometry Problem too->判断两线段是否相交
- hdoj-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----判断两线段是否相交
- 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 (计算几何 判断线段相交)
- HDU 1086 You can Solve a Geometry Problem too(判断两条直线是否相交)
- You can Solve a Geometry Problem too(线段相交问题)
- hdoj1086You can Solve a Geometry Problem too【线段相交判断】
- 异步block网络请求
- 在虚拟机中安装CentOS却无法上网的解决方法
- CF 335 div.2-B/606B Testing Robots(读不懂题系列)
- this指针的含义
- 10G(82599EB) 网卡测试优化(other)
- 杭电 1086 You can Solve a Geometry Problem too 判断线段是否相交.
- 堆栈、栈帧与函数调用过程分析
- 10G(82599EB) 网卡测试优化(中断处理)
- leetcode -- Best Time to Buy and Sell Stock II -- 重点注意思路
- java设计模式(五)—命令模式
- 10G(82599EB) 网卡测试优化(ethtool)
- Mac下,MySQL数据库中文乱码的解决方法
- Java线程2-1 线程池知识学习
- 10G(82599EB) 网卡测试优化(jumbo frame, tcp win scaling)