D. Gears
time limit per test
memory limit per test
input
output
A and B. Polygon A rotates around point P, and polygon B rotates around point Q. Each polygon rotates with the constant rotational speed in the clockwise direction around its point, the rotational speed values of the polygons' rotation are equal.
collision between polygons. A collision
0 the polygons A and B
Note that:
- the polygons are not necessarily convex;
- PandQ
Input
P.
n (3 ≤ n ≤ 1000) — the number of vertices of polygon A.
n lines contains two space-separated integers — the coordinates of the corresponding vertex of polygon A.
The next line is empty.
Q.
m (3 ≤ m ≤ 1000) — the number of vertices of polygon B. Next m lines contain the coordinates of the vertices of the polygon B.
104.
Output
YES", if the collision takes place and "NO" otherwise (don't print the quotes).
Sample test(s)
input
1 0 4 0 0 1 0 1 5 0 5 9 0 4 9 0 9 -5 10 -5 10 0
output
YES
input
0 0 3 1 0 2 -1 2 1 0 0 3 -1 0 -2 1 -2 -1
output
NO
Note
polygon
Picture to the first sample:
假定P和多边形A不动,则Q点绕P逆时针转动,
设Q为多边形B上一点,若B不绕Q转,则B绕P逆时针转,
但B绕Q顺时针转,
设B‘为Q上一点,向量QB’绕P逆时针转,
额外加上B‘绕Q顺时针转,则向量QB’不变,Q,B‘相对静止 =》Q,B相对静止
此时Q的运动轨迹为圆,B’的运动轨迹为圆加上一个定值向量,位移了的圆
而B可能出现的位置就是圆心加上一个定值向量的圆的集合,即圆心可以在某个多边形上移动,半径恒=|PQ| 的圆(镂空)扫过的面积
另一点:2个之前不相交的多边形相撞,必有某一时刻一个多边形的端点和另一个多边形的线段(含端点)重合
所有只要判断P交Q和Q交P的情况就行了
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define MAXN (1000+10)
#define eps (1e-5)
long long mul(long long a,long long b){return (a*b)%F;}
long long add(long long a,long long b){return (a+b)%F;}
long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
typedef long long ll;
int n,m;
struct P
{
int x,y;
P(){}
P(int _x,int _y):x(_x),y(_y){}
P(P A,P B):x(B.x-A.x),y(B.y-A.y){}
friend P operator+(P A,P B){return P(A.x+B.x,A.y+B.y);}
friend double operator*(P A,P B){return A.x*B.x+A.y*B.y;}
void print(){cout<<x<<' '<<y<<endl; }
}p,q,a[MAXN],b[MAXN];
double sqr(double x){return x*x;}
double dis(P A,P B)
{
return sqrt(sqr(A.x-B.x)+sqr(A.y-B.y));
}
struct S
{
P A,B;
S(){}
S(P _A,P _B):A(_A),B(_B){}
};
struct C
{
P O;
double r;
C(){}
C(P _O,double _r):O(_O),r(_r){}
bool is_cross(S p)
{
double dis1=dis(p.A,O),dis2=dis(p.B,O);
if (max(dis1,dis2)<r-eps) return 0; //端点在园内
// cout<<dis1<<' '<<dis2<<' '<<r<<endl;
if (abs(dis1-r)<eps||abs(dis2-r)<eps||(dis1-r)*(dis2-r)<0) return 1; //有端点在圆上||端点一里一外
P A=p.A,B=p.B;
if (abs((B.y-A.y)*O.x-(B.x-A.x)*O.y+A.y*B.x-A.x*B.y)<=r*dis(A,B)+eps) //端点在园外
{
// cout<<abs((B.y-A.y)*O.x-(B.x-A.x)*O.y+A.y*B.x-A.x*B.y)/dis(A,B)<<endl;
// O.print();A.print();B.print();cout<<r<<endl;
// cout<<P(B,A)*P(B,O)<<' '<<P(A,B)*P(A,O)<<endl;
if (P(B,A)*P(B,O)>=0&&P(A,B)*P(A,O)>=0) //线段的距离=直线的距离,等价于△OAB是锐角△
return 1;
}
return 0;
}
};
bool side_to_dot(P p,P a[],int n,P q,P b[],int m) //side_to_dot
{
double r=dis(p,q);
For(i,m)
{
C c=C(p+P(q,b[i]),r);
For(j,n)
{
if (c.is_cross(S(a[j],a[j+1])))
return 1;
}
}
return 0;
}
int main()
{
// freopen("CF497D.in","r",stdin);
// freopen(".out","w",stdout);
scanf("%d%d",&p.x,&p.y);
scanf("%d",&n);
For(i,n)
scanf("%d%d",&a[i].x,&a[i].y); a[n+1]=a[1];
scanf("%d%d",&q.x,&q.y);
scanf("%d",&m);
For(i,m)
scanf("%d%d",&b[i].x,&b[i].y); b[m+1]=b[1];
if (side_to_dot(p,a,n,q,b,m)||side_to_dot(q,b,m,p,a,n))
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
return 0;
}