Hide-and-Seek
Description
Victor and Peter are playing hide-and-seek. Peter has hidden, and Victor is to find him. In the room where they are playing, there is only one non-transparent wall and one double-sided mirror. Victor and Peter are points with coordinates (xv, yv) and (xp, yp) respectively. The wall is a segment joining points with coordinates (xw, 1, yw, 1) and (xw, 2, yw, 2), the mirror — a segment joining points (xm, 1, ym, 1) and (xm, 2, ym, 2).
If an obstacle has a common point with a line of vision, it’s considered, that the boys can’t see each other with this line of vision. If the mirror has a common point with the line of vision, it’s considered, that the boys can see each other in the mirror, i.e. reflection takes place. The reflection process is governed by laws of physics — the angle of incidence is equal to the angle of reflection. The incident ray is in the same half-plane as the reflected ray, relative to the mirror. I.e. to see each other Victor and Peter should be to the same side of the line, containing the mirror (see example 1). If the line of vision is parallel to the mirror, reflection doesn’t take place, and the mirror isn’t regarded as an obstacle (see example 4).
Victor got interested if he can see Peter, while standing at the same spot. Help him solve this problem.
Input
The first line contains two numbers xv and yv — coordinates of Victor.
The second line contains two numbers xp and yp — coordinates of Peter.
The third line contains 4 numbers xw, 1, yw, 1, xw, 2, yw, 2 — coordinates of the wall.
The forth line contains 4 numbers xm, 1, ym, 1, xm, 2, ym, 2 — coordinates of the mirror.
All the coordinates are integer numbers, and don’t exceed 104 in absolute value. It’s guaranteed, that the segments don’t have common points, Victor and Peter are not on any of the segments, coordinates of Victor and Peter aren’t the same, the segments don’t degenerate into points.
Output
Output YES, if Victor can see Peter without leaving the initial spot. Otherwise output NO.
Sample Input
Input
-1 3
1 3
0 2 0 4
0 0 0 1
Output
NO
Input
0 0
1 1
0 1 1 0
-100 -100 -101 -101
Output
NO
Input
0 0
1 1
0 1 1 0
-1 1 1 3
Output
YES
Input
0 0
10 0
100 100 101 101
1 0 3 0
Output
YES
题意:给出二维坐标系中两人坐标,双面镜线段和非透明的墙线段,镜子的反射遵循物理规律,问两人是否能相互看到
线段交判断人与镜子和墙的关系,取对称时需要注意两个对称情况是否都没有被墙挡住
代码中符点关于直线对称点代码模板
#include<cstring>
#include<string>
#include<iostream>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstdlib>
#include<cmath>
#include<vector>
//#pragma comment(linker, "/STACK:1024000000,1024000000");
using namespace std;
#define INF 0x3f3f3f3f
struct Point
{
double x,y;
int kind;
int id;
Point() {}
Point(double _x,double _y)
{
x = _x;
y = _y;
}
Point operator -(const Point &b)const
{
return Point(x - b.x,y - b.y);
}
//叉积
double operator ^(const Point &b)const
{
return x*b.y - y*b.x;
}
//点积
double operator *(const Point &b)const
{
return x*b.x + y*b.y;
}
//绕原点旋转角度B(弧度值),后x,y的变化
void transXY(double B)
{
double tx = x,ty = y;
x = tx*cos(B) - ty*sin(B);
y = tx*sin(B) + ty*cos(B);
}
} V,P,W[2],M[2];
const double eps = 1e-8;
const double PI = acos(-1.0);
int sgn(double x)
{
if(fabs(x) < eps)return 0;
if(x < 0)return -1;
else return 1;
}
struct Line
{
Point s,e;
Line() {}
Line(Point _s,Point _e)
{
s = _s;
e = _e;
}
//两直线相交求交点
//第一个值为0表示直线重合,为1表示平行,为0表示相交,为2是相交
//只有第一个值为2时,交点才有意义
pair<int,Point> operator &(const Line &b)const
{
Point res = s;
if(sgn((s-e)^(b.s-b.e)) == 0)
{
if(sgn((s-b.e)^(b.s-b.e)) == 0)
return make_pair(0,res);//重合
else return make_pair(1,res);//平行
}
double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
res.x += (e.x-s.x)*t;
res.y += (e.y-s.y)*t;
return make_pair(2,res);
}
};
bool inter(Line l1,Line l2)
{
return
max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&
max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&
max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&
max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&
sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0 &&
sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) <= 0;
}
void Sp(Point &A,Line X)
{
double a=X.e.y-X.s.y;
double b=X.s.x-X.e.x;
double c=X.s.y*(X.e.x-X.s.x)-X.s.x*(X.e.y-X.s.y);
double x = ((b*b - a*a) * A.x - 2 * a * b * A.y - 2 * a * c) / (a*a + b*b);
double y = ((a*a - b*b) * A.y - 2 * a * b * A.x - 2 * b * c) / (a*a + b*b);
A.x=x;
A.y=y;
}
int main()
{
scanf("%lf%lf%lf%lf",&V.x,&V.y,&P.x,&P.y);
scanf("%lf%lf%lf%lf",&W[0].x,&W[0].y,&W[1].x,&W[1].y);
scanf("%lf%lf%lf%lf",&M[0].x,&M[0].y,&M[1].x,&M[1].y);
Line VP(V,P),WALL(W[0],W[1]),MIRROR(M[0],M[1]);
if(!inter(VP,WALL)&&((M[0]-V)^(P-V))==0&&((M[1]-V)^(P-V))==0)
{
printf("YES\n");
}
else if(inter(VP,MIRROR))
{
printf("NO\n");
}
else if(!inter(VP,WALL))
{
printf("YES\n");
}
else
{
Point temp=V;
Sp(temp,MIRROR);
Line VP1(temp,P);
temp=P;
Sp(temp,MIRROR);
Line VP2(temp,V);
if(inter(VP1,MIRROR)&&!inter(VP1,WALL)&&!inter(VP2,WALL))
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
return 0;
}