1288: 计算几何练习题——线段相交
2014-04-27 11:35
323 查看
描述
线段相交测试在计算几何中是经常用到的,给定线段P1P2(P1和P2是线段的两端点,且不重合)、P3P4(P3和P4是线段的两端点,且不重合),判断P1P2和P3P4是否相交。P1P2和P3P4不重合,即指只存在一个点P,它既落在P1P2上又落在P3P4上(含线段的端点)。
输入
输入数据有多组,第一行为测试数据的组数N,下面包括2N行,每组测试数据含2行,第一行为P1P2的坐标值,第二行为P3P4的坐标值,比如下面的数据
1
0 0 1 1
2 2 3 3
表示P1、P2、P3、P4的坐标分别为:P1(0,0),P2(1,1),P3(2,2),P4(3,3)
输出
判断每组数据中的线段P1P2和P3P4是否相交,如果相交输出YES,否则输出NO。每组数据输出占一行。
样例输入
样例输出
题目来源
http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1288
判断两条线段是否相交首先要满足两个条件:
1.快速排斥实验,即以两条线段为对角线的矩形不相交
2.跨立实验,即任意线段的两个端点在另一条线段的不同侧,
不过满足上面两条件后还要注意一点,就是两条线段可能有重合部分,这也要加以判断.
线段相交测试在计算几何中是经常用到的,给定线段P1P2(P1和P2是线段的两端点,且不重合)、P3P4(P3和P4是线段的两端点,且不重合),判断P1P2和P3P4是否相交。P1P2和P3P4不重合,即指只存在一个点P,它既落在P1P2上又落在P3P4上(含线段的端点)。
输入
输入数据有多组,第一行为测试数据的组数N,下面包括2N行,每组测试数据含2行,第一行为P1P2的坐标值,第二行为P3P4的坐标值,比如下面的数据
1
0 0 1 1
2 2 3 3
表示P1、P2、P3、P4的坐标分别为:P1(0,0),P2(1,1),P3(2,2),P4(3,3)
输出
判断每组数据中的线段P1P2和P3P4是否相交,如果相交输出YES,否则输出NO。每组数据输出占一行。
样例输入
1 0 0 1 1 2 2 3 3
样例输出
NO
题目来源
http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1288
判断两条线段是否相交首先要满足两个条件:
1.快速排斥实验,即以两条线段为对角线的矩形不相交
2.跨立实验,即任意线段的两个端点在另一条线段的不同侧,
不过满足上面两条件后还要注意一点,就是两条线段可能有重合部分,这也要加以判断.
#include <iostream> #include <cmath> using namespace std; struct Node { double x,y; }; double cross(double x1,double y1,double x2,double y2)//计算叉乘 { return x1*y2-x2*y1; } bool kspc(Node a,Node b,Node c,Node d)//快速排斥 { if(min(a.x,b.x)>max(c.x,d.x) || min(a.y,b.y)>max(c.y,d.y) || max(a.x,b.x)<min(c.x,d.x) || max(a.y,b.y)<min(c.y,d.y)) return false; return true; } bool klsy(Node a,Node b,Node c,Node d)//跨立实验 { if(cross(c.x-a.x,c.y-a.y,c.x-d.x,c.y-d.y)*cross(c.x-b.x,c.y-b.y,c.x-d.x,c.y-d.y)<=0 && cross(a.x-c.x,a.y-c.y,a.x-b.x,a.y-b.y)*cross(a.x-d.x,a.y-d.y,a.x-b.x,a.y-b.y)<=0) return true; return false; } bool deng_node(Node a,Node b)//判断两点是否相等 { if(a.x==b.x && a.y==b.y) return true; return false; } int main() { int n; Node d1[2],d2[2]; cin>>n; while(n--) { cin>>d1[0].x>>d1[0].y>>d1[1].x>>d1[1].y; cin>>d2[0].x>>d2[0].y>>d2[1].x>>d2[1].y; if(kspc(d1[0],d1[1],d2[0],d2[1]) && klsy(d1[0],d1[1],d2[0],d2[1]))//同时满足快速排斥和跨立实验 { if(fabs(cross(d2[0].x-d1[0].x,d2[0].y-d1[0].y,d2[0].x-d2[1].x,d2[0].y-d2[1].y))<0.000001 && fabs(cross(d2[0].x-d1[1].x,d2[0].y-d1[1].y,d2[0].x-d2[1].x,d2[0].y-d2[1].y))<0.000001)//如果两条线段有重合 { if((deng_node(d1[0],d2[0])&&!deng_node(d1[1],d2[1])) || (deng_node(d1[0],d2[1])&&!deng_node(d1[1],d2[0])) || (deng_node(d1[1],d2[0])&&!deng_node(d1[0],d2[1])) || (deng_node(d1[1],d2[1])&&!deng_node(d1[0],d2[0])) )//如果重合的只是一个端点 cout<<"YES"<<endl; else cout<<"NO"<<endl; } else cout<<"YES"<<endl; } else cout<<"NO"<<endl; } return 0; }
相关文章推荐
- 隐藏tabelView多余的cell
- js实现页面跳转的几种方式
- mysql的test 库的相关特性
- 垃圾回收机制与变量周期,不成熟见解。
- Java4Android(第46~49集)eclipse工具及使用
- 用链表写的学生管理系统 成绩的录入与查询都已经是实现了
- C++ Primer笔记(十八)优化内存分配
- wpf图片定点缩放
- 浅谈C++多态性
- 8192EU无线网卡在ubuntu14.04下驱动编译错误解决
- itext in action英文版教程demo中关于Hsqldb的设置
- android添加自定义LOG函数。
- 一个win32窗口创建示例
- nyoj-830-旋转坐标系
- UVA 1529 - Clock(数论)
- Java计算同一格式文本文件行数
- C++中属于整个类的的常量
- Passive-interface(被动接口)及单播更新
- 正反斜杠 点 在传参过程中
- SQL Server优化50法