2017 ACM-ICPC乌鲁木齐网络赛 B. Out-out-control cars(计算几何 直线相交)

题目描述

Two out-of-control cars crashed within about a half-hour Wednesday afternoon on Deer Park Avenue. This accident alarmed the district government.
It jumpstarted a vibrant new technology to predict potential car accidents.
Engineers depicted a moving vehicle as a triangle with directional movement.
Three two dimeniaonal points (x1,y1),(x2,y2) and (x3,y3) restrict the span of a vehicle.
Its moverment is a uniform linear motion described by a vector (dx,dy).
That is say that after one second,the i-th endpoint of the emulational vehicle,the triangle,should be at (xi+dx,yi+dy).
The core function of this technology is simple.
For two given triangles,corresponding to two vehicles,predict that if they would collide in the near future.
Two triangles are considered collided,if they touched in some points or their intersection is not empty.
The first line of the input contains an integer tt specifying the number of test cases.
Each test case is consist of two lines and each line contains eight integers x1,y1,x2 ,y2,x3,y3 and dx,dy,to describe a vehicle and its movement.
The absolute value of each input number should be less than or equal to 10^9.
For each test case output the case number first. Then output YES if they would collide in the near future,or NO if they would never touch each other.

输入

 

输出

 

样例输入

3

0 1 2 1 1 3 1 0
9 2 10 4 8 4 -1 0

0 1 2 1 1 3 2 0
9 2 10 4 8 4 3 0

0 1 2 1 1 3 0 0
0 4 1 6 -1 6 1 -2

样例输出

Case #1: YES
Case #2: NO
Case #3: YES

题意:给你两个三角形,这两个三角形分别有x轴,y轴方向的速度,问你这两个三角形可不可能相撞(某一时刻两个三角形面积的交不为空)
思路:我们先固定一个三角形,将两个速度合成一个合速度,然后看动的那个三角形的三个定点发出的以合速度为方向的射线与定三角形的三条边有无交点
trick就是需要分别固定两个三角形.
我们将问题转化为了射线与线段相交.这个与两直线相交有什么区别呢?
1.交点应该在那个线段中间,我们用线段的两端点的坐标与交点坐标比较大小即可
2.交点应该在那个射线的一侧,我们用t来判断下射线的正方向
代码如下:
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 struct Point{double x,y;} ;//// 直线交点函数
 4 int LineIntersect(Point A,Point B,Point C,Point D,double &x,double &y)
 5 {
 6     double a1,a2,b1,b2,c1,c2;
 7     double Delta , Delta_x , Delta_y;
 8     a1 = B.x - A.x; b1 = C.x - D.x;  c1 = C.x - A.x;
 9     a2 = B.y - A.y; b2 = C.y - D.y;  c2 = C.y - A.y;
10     Delta=a1*b2-a2*b1; Delta_x=c1*b2-c2*b1;Delta_y=a1*c2-a2*c1;
11     if(Delta){
12         x = A.x+a1*(Delta_x/Delta);
13         y = A.y+a2*(Delta_x/Delta);
14         return 1; //返回1:    表示两条直线相交,且交点是(x , y)
15     }
16     else
17     {
18         if(!Delta_x && !Delta_y) return -1; //返回是-1: 表示两条直线是重合关系
19         else return 0; //返回0:表示两条直线是平行不相交关系
20     }
21 }
22 bool judge (Point a[],Point b[],double dx,double dy,int i,int j)
23 {
24     Point cc;
25     cc.x=b[j].x+dx;cc.y=b[j].y+dy;
26     double xx,yy;
27     double maxx,maxy,minx,miny;
28     int ins = LineIntersect(a[i],a[(i+1)%3],b[j],cc,xx,yy);
29     maxx = max(a[i].x,a[(i+1)%3].x);
30     maxy = max(a[i].y,a[(i+1)%3].y);
31     minx = min(a[i].x,a[(i+1)%3].x);
32     miny = min(a[i].y,a[(i+1)%3].y);
33     double t = (xx-b[j].x)/dx;
34     if (ins==1&&t>0&&(minx<=xx&&xx<=maxx)&&(miny<=yy&&yy<=maxy))
35         return true;
36     else
37         return false;
38 }
39 Point a[3],b[3];
40 double dx1,dy1,dx2,dy2;
41 int main()
42 {
43     int casee = 0;
44     int T;
45     scanf("%d",&T);
46     while (T--){
47         for (int i=0;i<3;++i) scanf("%lf%lf",&a[i].x,&a[i].y);
48         scanf("%lf%lf",&dx1,&dy1);
49         for (int i=0;i<3;++i) scanf("%lf%lf",&b[i].x,&b[i].y);
50         scanf("%lf%lf",&dx2,&dy2);
51         dx2-=dx1;
52         dy2-=dy1;
53         bool f = false;
54         for (int i=0;i<3;++i){
55             for (int j=0;j<3;++j){
56                 if (judge(a,b,dx2,dy2,i,j))
57                     f = true;
58                 if (judge(b,a,-dx2,-dy2,i,j))
59                     f = true;
60             }
61         }
62         if (f)
63             printf("Case #%d: YES
",++casee);
64         else
65             printf("Case #%d: NO
",++casee);
66     }
67     return 0;
68 }
 
原文地址:https://www.cnblogs.com/agenthtb/p/7522945.html