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

本文介绍了一种通过模拟车辆三角形模型及其线性运动来预测潜在碰撞的技术。利用相对速度概念,将问题简化为一个静止目标与另一个移动目标之间的碰撞预测。通过计算射线与线段的交点来判断是否可能发生碰撞。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


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;
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值