新疆网络赛的几何题,当时没做出来,分别将两个三角形看成不动,只有一个三角形在动,那么问题就转变为求一个射线与线段是否有交点,我们可以在求两条直线交点的基础上再做处理:
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);
}
}