博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 1410 Intersection(计算几何---线段相交--跨立试验)
阅读量:5325 次
发布时间:2019-06-14

本文共 4188 字,大约阅读时间需要 13 分钟。

Intersection

Time Limit: 1000MS

 

Memory Limit: 10000K

Total Submissions: 7609

 

Accepted: 1989

Description

You are to write a program that has to decide whether a given line segment intersects a given rectangle. 

An example: 
line: start point: (4,9) 
end point: (11,2) 
rectangle: left-top: (1,5) 
right-bottom: (7,1) 

Figure 1: Line segment does not intersect rectangle 
The line is said to intersect the rectangle if the line and the rectangle have at least one point in common. The rectangle consists of four straight lines and the area in between. Although all input values are integer numbers, valid intersection points do not have to lay on the integer grid. 

Input

The input consists of n test cases. The first line of the input file contains the number n. Each following line contains one test case of the format: 

xstart ystart xend yend xleft ytop xright ybottom 
where (xstart, ystart) is the start and (xend, yend) the end point of the line and (xleft, ytop) the top left and (xright, ybottom) the bottom right corner of the rectangle. The eight numbers are separated by a blank. The terms top left and bottom right do not imply any ordering of coordinates.

Output

For each test case in the input file, the output file should contain a line consisting either of the letter "T" if the line segment intersects the rectangle or the letter "F" if the line segment does not intersect the rectangle.

Sample Input

1

4 9 11 2 1 5 7 1

Sample Output

F

Source

 解题报告:这道题就是判断线段是否和矩形相交(含顶点),利用跨立试验判断,其中跨立试验的基本思想如下(网上摘得)跨立试验 :如果两线段相交,则两线段必然相互跨立对方。若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。 

代码如下:

#include 
#include
#include
#include
#include
#define Max(x, y)(x > y ? x : y)#define Min(x, y)(x < y ? x : y)using namespace std;int n;bool flag;//标志变量struct Point{ double x; double y;}rec[4], seg[2];//rec数组存储矩形的坐标,seg数组存储线段两点的坐标double Multi(Point p1, Point p2, Point p3)//叉乘判断点与线的位置关系{ return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);}//跨立试验,判断两线段是否相交bool Isintersect(Point a1, Point a2, Point b1, Point b2)//判断两条线段是否相交(含顶点){ if (Min(a1.x, a2.x) <= Max(b1.x, b2.x) && Min(a1.y, a2.y) <= Max(b1.y, b2.y) && Min(b1.x, b2.x) <= Max(a1.x, a2.x) && Min(b1.y, b2.y) <= Max(a1.y, a2.y) && Multi(a1, a2, b1) * Multi(a1, a2, b2) <= 0 && Multi(b1, b2, a1) * Multi(b1, b2, a2) <= 0 ) return true;//说明两线段之间相交 return false;}bool Inrectangle(int i)//判断点是否在矩形的内部{ if (seg[i].x > Max(rec[1].x, rec[3].x)) return false; if (seg[i].y > Max(rec[1].y, rec[3].y)) return false; if (seg[i].x < Min(rec[1].x, rec[3].x)) return false; if (seg[i].y < Min(rec[1].y, rec[3].y)) return false; //如果满足上面的,说明线段在矩形的内部并且没有和矩形没有交点(含线段的顶点) return true;}int main(){ int i; scanf("%d", &n); while (n --) { scanf("%lf%lf%lf%lf", &seg[0].x, &seg[0].y, &seg[1].x, &seg[1].y); scanf("%lf%lf%lf%lf", &rec[1].x, &rec[1].y, &rec[3].x, &rec[3].y); rec[0].x = rec[1].x; rec[0].y = rec[3].y; rec[2].x = rec[3].x; rec[2].y = rec[1].y; flag = false;//假设线段和矩形没有相交 if (Inrectangle(0) || Inrectangle(1)) { flag = true; } else { for (i = 0; i < 4; ++i) { if (Isintersect(rec[i], rec[(i + 1) % 4], seg[0], seg[1])) { flag = true;//两线段已经相交了直接退出即可 break; } } } if (flag)//线段和矩形相交 { printf("T\n"); } else { printf("F\n"); } } return 0;}

转载于:https://www.cnblogs.com/lidaojian/archive/2012/05/06/2486600.html

你可能感兴趣的文章
bzoj2257
查看>>
http://www.bootcss.com/
查看>>
20145308 《网络对抗》 注入shellcode+Return-to-libc攻击 学习总结
查看>>
python tkinter GUI绘制,以及点击更新显示图片
查看>>
C语言栈的实现
查看>>
SRM 628 DIV2
查看>>
2018-2019-2 20165314『网络对抗技术』Exp5:MSF基础应用
查看>>
SecureCRT的使用方法和技巧(详细使用教程)
查看>>
自建数据源(RSO2)、及数据源增强
查看>>
2018icpc徐州OnlineA Hard to prepare
查看>>
使用命令创建数据库和表
查看>>
【转】redo与undo
查看>>
安卓当中的线程和每秒刷一次
查看>>
wpf样式绑定 行为绑定 事件关联 路由事件实例
查看>>
TCL:表格(xls)中写入数据
查看>>
Oracle事务
查看>>
String类中的equals方法总结(转载)
查看>>
标识符
查看>>
内存地址对齐
查看>>
创新课程管理系统数据库设计心得
查看>>