Out-out-control cars

新疆网络赛的几何题,当时没做出来,分别将两个三角形看成不动,只有一个三角形在动,那么问题就转变为求一个射线与线段是否有交点,我们可以在求两条直线交点的基础上再做处理:
1.要求交点在线段范围内(横纵坐标满足)
2.要求交点与射线的向量同向

#include<bits/stdc++.h>
using namespace std;
const double eps=1e-9;
 int sgn(double x) {
 if( x < -eps ) return -1;
 if( x > eps ) return 1;
 return 0;
 }


struct vec {
     double x,y;
     vec(){x=y=0;}
     vec(double _x,double _y){x=_x,y=_y;}

     vec operator + (vec v) {return vec(x+v.x,y+v.y);}
     vec operator - (vec v) {return vec(x-v.x,y-v.y);}
     vec operator * (double v) {return vec(x*v,y*v);}
     vec operator / (double v) {return vec(x/v,y/v);}

     double operator * (vec v) {return x*v.x + y*v.y;}

     double len() {return hypot(x,y); }
     double len_sqr() {return x*x + y*y; }

     //逆时针旋转
     vec rotate(double c) {return vec(x*cos(c)-y*sin(c),x*sin(c)+y*cos(c));}
     vec trunc (double l) {return (*this) * l / len();}
     vec rot90 () {return vec(-y,x);}
}v[20][32];


double cross(vec a,vec b) {return a.x*b.y - a.y*b.x;}


 //直线求交点,需保证p!=q,a!=b
int line_intersection(vec A,vec B,vec C,vec D,vec &o) {
      // cout<<A.x<<' '<<A.y<<endl;
       double a1,a2,b1,b2,c1,c2;
      double Delta , Delta_x , Delta_y;
      a1 = B.x - A.x; b1 = C.x - D.x;  c1 = C.x - A.x;
      a2 = B.y - A.y; b2 = C.y - D.y;  c2 = C.y - A.y;
     Delta=a1*b2-a2*b1; Delta_x=c1*b2-c2*b1;Delta_y=a1*c2-a2*c1;
     if(Delta){
         o.x = A.x+a1*(Delta_x/Delta);
         o.y = A.y+a2*(Delta_x/Delta);
         return 1; //返回1:    表示两条直线相交,且交点是(x , y)
     }
     else
     {
         if(!Delta_x && !Delta_y) return -1; //返回是-1: 表示两条直线是重合关系
         else return 0; //返回0:表示两条直线是平行不相交关系
     }
}

bool judge(vec a,vec b,vec p,vec q,double dx) //a,b三角形的点
{
   // cout<<"dx="<<dx<<endl;
    vec o;
    double t;
    int res=line_intersection(a,b,p,q,o);
    t=(o.x-p.x)/dx;
  //  cout<<"t="<<t<<endl;
  //  cout<<o.x<<' '<<o.y<<endl;
    if(t>0&&res==1&&o.x>=min(a.x,b.x)&&o.x<=max(a.x,b.x)&&o.y>=min(a.y,b.y)&&o.y<=max(a.y,b.y)) {
        return true;
    }
    return false;
}


int main()
{
    int t;
    cin>>t;
    int ti=0;
    while(t--)
    {
        for(int i=0;i<2;i++)
        for(int j=0;j<4;j++)
        {
            scanf("%lf%lf",&v[i][j].x,&v[i][j].y);
        }
        bool flag=false;
        double dx=v[1][3].x-v[0][3].x;
        double dy=v[1][3].y-v[0][3].y;
        for(int i=0;i<3;i++)
        {
            for(int j=0;j<3;j++) {
             vec vv(v[1][j].x+dx,v[1][j].y+dy);
             vec vvv(v[0][j].x-dx,v[0][j].y-dy);
             if(judge(v[0][i],v[0][(i+1)%2],v[1][j],vv,dx))
                flag=true;

             if(judge(v[1][i],v[1][(i+1)%2],v[0][j],vvv,-dx))
                flag=true;
            }
        }
        if (flag)
             printf("Case #%d: YES\n",++ti);
         else
             printf("Case #%d: NO\n",++ti);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值