uva191 Intersection
来源:互联网 发布:c语言中=是什么意思 编辑:程序博客网 时间:2024/04/30 09:09
题意:给出线段的端点和矩形对角线的两个点,要判断线段和矩形是否相交
解题:Computational Geometry(计算几何);如果线段在矩形内部算是相交的,如果不是,就判断线段和矩形四条边是否有交点,所以重点就是如何判断两条线段相交
如图一:若(p1,p2)和(p3,p4)相交,他们相互跨越,那么p1,p2和(p3,p4)必然在(p3,p4)[或(p1,p2) 的两侧;就可以用向量来解决,(p1,p3)在(p1,p2)的逆时针方向,(p1,p4)在(p1,p2)的顺时针方向;就可以用叉积来解决,如图三,叉积是(0,0),a1,a2,a3(=a1+a2) 构成的平行四边形的有向面积,或者是a1*a2 = x1y2-x2y1;若a1*a2 >0 则则表示a1在a2的顺时针方向,否则是逆时针方向;
综上所述:判断两线段相交,1.看叉积,两个叉积不同号 2.如果叉积等于0,表示共线,但是由于是线段,所以在判断点是否在线段上。
代码:在图下面
//uva191 Intersection//AC By Warteac//Runtime:0.012s//2013-5-3#include<iostream>#include<cstdio> using namespace std; struct point{ int x,y; point(int x1 = 0, int y1 = 0){x = x1; y = y1;} void print(){cout << "x= " << x << " y= " << y << endl;} };//定义点结构体//求向量的叉积,p1*p2 > 0 => p1 在 p2的顺时针方向,< 0 逆时针 int direction(point pi,point pj,point pk){ return ((pj.x - pi.x)*(pk.y - pi.y)-(pk.x - pi.x)*(pj.y - pi.y)); } //向量共线的前提下,判断是点pk是否在线段(pi,pj)上 bool onSegment(point pi,point pj,point pk){ if((min(pi.x,pj.x) <= pk.x && pk.x <= max(pi.x,pj.x)) && (min(pi.y,pj.y) <= pk.y && pk.y <= max(pi.y,pj.y))){ return true; }else{ return false; } } //线段(p1,p2)和线段(p3,p4)是否相交 bool segmentsIntersect(point p1,point p2,point p3, point p4){ int d1,d2,d3,d4; d1 = direction(p3,p4,p1); d2 = direction(p3,p4,p2); d3 = direction(p1,p2,p3); d4 = direction(p1,p2,p4); //cout << d1 << " " << d2 <<" " << d3 << " " << d4 << endl; if(((d1 > 0 && d2 < 0) || (d1 < 0 && d2 >0)) && ((d3 > 0 && d4 < 0)||(d3 < 0 && d4 > 0))) return true; else if((d1 == 0)&&(onSegment(p3,p4,p1))) return true;else if((d2 == 0)&&(onSegment(p3,p4,p2)))return true;else if((d3 == 0)&&(onSegment(p1,p2,p3)))return true;else if((d4 == 0)&&(onSegment(p1,p2,p4)))return true;else return false; } //线段(pa,pb)在矩形的内部 bool segmentInRectangle(point p1,point p3,point pa,point pb){ if( (min(p1.x,p3.x) <= pa.x && pa.x <= max(p1.x,p3.x)) && (min(p1.y,p3.y) <= pa.y && pa.y <= max(p1.y,p3.y)) && (min(p1.x,p3.x) <= pb.x && pb.x <= max(p1.x,p3.x)) && (min(p1.y,p3.y) <= pb.y && pb.y <= max(p1.y,p3.y)) ) return true; else return false; } int main(){ point p1,p2,p3,p4;//矩形的四个顶点 point pa,pb;//线段的端点 int caseNum; cin >> caseNum; int x1,y1,x2,y2,x3,y3,x4,y4; while(caseNum--){ cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3 >> x4 >> y4; pa = point(x1,y1); pb = point(x2,y2); p1 = point(x3,y3); p3 = point(x4,y4); p2 = point(x3,y4); p4 = point(x4,y3); if(segmentInRectangle(p1,p3,pa,pb) == true){//线段在矩形内部 cout << "T" << endl; }else if( (segmentsIntersect(p1,p2,pa,pb))|| (segmentsIntersect(p1,p4,pa,pb))|| (segmentsIntersect(p3,p2,pa,pb))|| (segmentsIntersect(p3,p4,pa,pb)) ) cout << "T" << endl;//线段在外部,但是和矩形有交点 else cout << "F" << endl; } }
- uva191 Intersection
- uva191 Intersection
- uva191 Intersection(线段之间相交)
- Intersection
- Intersection
- Intersection
- Intersection
- Intersection graph & Intersection number
- poj1410 - Intersection
- 18:Intersection
- POJ1410 Intersection
- poj1410 Intersection
- 1879: Intersection
- poj1410 Intersection
- intersection set
- poj1410 Intersection
- ZOJ3862:Intersection
- HDU_5120 Intersection
- C语言中 restrict 关键字学习
- 揭开Linux操作系统的Swap交换区之谜
- 线性判别分析(LDA), 主成分分析(PCA)
- binder驱动-交互时的传输实现
- IE8 indexOf
- uva191 Intersection
- 使用nid命令修改 db name 及 dbid
- JSch - Java实现的SFTP
- Android积累之《文件的读取与保存》
- 谈谈Runtime类中的freeMemory,totalMemory,maxMemory几个方法
- 代码的坏味道之十八 :Alternative Classes with Different Interfaces(异曲同工的类)
- 学习使用<c:choose><c:when>,<c:otherwise>标签
- 正则表达式基础
- 如何合理设置Linux的swap分区