2017 ACM-ICPC乌鲁木齐网络赛 B. Out-out-control cars【计算几何||判断射线与线段是否相交】

来源:互联网 发布:网络事件 2017 编辑:程序博客网 时间:2024/05/16 16:18


Out-out-control cars

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit:131072/131072 K (Java/Others)


Problem Description


Twoout-of-control cars crashedwithin about a half-hour Wednesday afternoon on Deer

ParkAvenue. This accident alarmedthe district government.

Itjumpstarted a vibrant newtechnology to predict potential car accidents.

Engineersdepicted a moving vehicleas a triangle with directional movement.

Three twodimeniaonal points(x​1​​,y​1​​),(x2,y2) and(x​3​​,y​3​​) restrict the span of avehicle.

Itsmoverment is a uniform linearmotion described by a vector(d​x​​,d​y​​).

That issay that after one second,the i-th endpoint of the emulational vehicle, thetriangle, should be at (xi+dx,yi+dy)(x_i+d_x,y_i+d_y)(x​i​​+d​x​​,y​i​​+d​y​​).

The corefunction of this technologyis simple.

For twogiven triangles,corresponding to two vehicles, predict that if they wouldcollide in the nearfuture.

Twotriangles are consideredcollided, if they touched in some points or theirintersection is not empty.

The firstline of the input containsan integertttspecifying the number of test cases.

Each testcase is consist of twolines and each line contains eight integersx1​​,y1,x2​​,y2,x3,y3​​ and dx ​​,dy ​​, to describe a vehicle and its movement.

The absolutevalue of each inputnumber should be less than or equal to10^9.

For eachtest case output the casenumber first. Then output YES if they would collide inthe near future, or NOif they would never touch each other.

 

 

 

Sample Input

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

 

 

Sample Output

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


【题意】


给出两个三角形的坐标以及它们运动的速度,问是否存在一个时刻两个三角形有公共部分(点重合也可)


【思路】


由于两个三角形都有速度,这样比较难判断。于是我们考虑把问题简化。


我们可以算出第一个三角形相对于第二个三角形的速度,那么就转化成了第一个三角形有一相对速度,第二个三角形不动了。


从第一个三角形的三个顶点发出三条与速度平行射线,只要一一判断射线是否会和第二个三角形的三条边相交即可。


那么如何判断射线是否与线段相交呢?首先如果直线与射线有交点,先算出交点与线段一端点的距离,如果这个距离小于线段长度的话,即两者比率k在范围[0,1]内的话,说明跟线段有交点。


从直线转化为直线只要再加一个条件:交点在射线指向的那一侧,即k>=0,画个图就比较清楚了。


#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;#define mst(a,b) memset((a),(b),sizeof(a))#define rush() int T;scanf("%d",&T);while(T--)typedef long long ll;const int maxn = 10005;const ll mod = 1e9+7;const int INF = 0x3f3f3f3f;const double eps = 1e-9;struct node{    double x,y;    node(double x=0,double y=0):x(x),y(y) {}    int read()    {        return scanf("%lf%lf",&x,&y);    }};typedef node Vector;Vector operator -(node A,node B){    return Vector(A.x-B.x,A.y-B.y);}double cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;}   //叉积double LineInter(node P,Vector v,node Q,Vector w)          //求两直线相交交点(这里只求系数k){    Vector temp=P-Q;    double k=cross(w,temp)/cross(v,w);    return k;    /*temp.x=P.x+v.x*k,temp.y=P.y+v.y*k;    return temp;*/}struct Line{    node p;    Vector v;    Line(node p,Vector v):p(p),v(v) {}};bool judge(Line L,node a,node b){    if(cross(L.v,b-a)!=0)                     //两直线平行一定没有交点    {        double temp1=LineInter(L.p,L.v,a,b-a);        double temp2=LineInter(a,b-a,L.p,L.v);        if(temp1>=0&&temp2>=0&&temp2<=1) return true; //第二个参数应该在范围[0,1]内    }    return false;}int main(){    int cas=1;    node a,b,c,d,e,f,A,B;    rush()    {        a.read(),b.read(),c.read(),A.read();        d.read(),e.read(),f.read(),B.read();        Line L1=Line(a,A-B),L2=Line(b,A-B),L3=Line(c,A-B); //A-B即为第一个三角形相对于第二个三角形的速度        int flag=0;        if(judge(L1,d,e)) flag=1;        if(judge(L1,d,f)) flag=1;        if(judge(L1,f,e)) flag=1;        if(judge(L2,d,e)) flag=1;        if(judge(L2,d,f)) flag=1;        if(judge(L2,f,e)) flag=1;        if(judge(L3,d,e)) flag=1;        if(judge(L3,d,f)) flag=1;        if(judge(L3,f,e)) flag=1;        printf("Case #%d: ",cas++);        if(flag) puts("YES");        else puts("NO");    }    return 0;}







阅读全文
0 0