一道基本的计算几何题

题目大意:

两个人在坐标系内,可以通过镜子的反射来看到对方,但是会有一堵墙阻挡,问两个人能否看到对方

若两个人与镜子共线,则镜子不会阻挡两个人的视线。而给出的镜子和墙不会相交

思路:

看到只有两种情况

第一种 两个人直接看到

第二种 两个人直接通过镜子看到

对于这种情况,我们直接判断他们是否在镜子一侧,他们与对方对称点连成的线段与镜子相交且不与墙相交,这五个东西即可

一道基本的计算几何题_第1张图片

但是这种情况看上去不符合第二种的判断但其实是可以看到的,但是如果这种情况就直接看到了,哪还需要什么镜子。。。

TAT跪了两个点不知道为什么 本蒟蒻很无奈

 1 #include
 2 #include
 3 #include
 4 #include
 5 #include
 6 #include
 7 #include
 8 #include
 9 #include
10 #include<set>
11 #include
12 #define inf 2147483611
13 #define ll long long
14 #define MAXN 101010
15 using namespace std;
16 inline int read()
17 {
18     int x=0,f=1;
19     char ch;ch=getchar();
20     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
21     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
22     return x*f;
23 }
24 struct node
25 {
26     double x,y;
27 }a,b,vb,va,m1,m2,w1,w2;
28 double mult(node a,node b,node c)//叉积 
29 {  
30     return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);  
31 }
32 bool intct(node a,node b,node c,node d)//判两线段是否相交 
33 {  
34     if(max(a.x,b.x)return false;
35     if(max(a.y,b.y)return false;
36     if(max(c.x,d.x)return false;
37     if(max(c.y,d.y)return false;
38     if(mult(c,b,a)*mult(b,d,a)<0) return false;
39     if(mult(a,d,c)*mult(d,b,c)<0) return false;
40     return true;  
41 }
42 int main()
43 {
44     scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);
45     scanf("%lf%lf%lf%lf",&w1.x,&w1.y,&w2.x,&w2.y);
46     scanf("%lf%lf%lf%lf",&m1.x,&m1.y,&m2.x,&m2.y);
47     bool inw=intct(a,b,w1,w2),inm=intct(a,b,m1,m2);//是否与墙交,是否与镜子交 
48     if(!inw&&!inm) {printf("YES");return 0;}//是否能直接看到 
49     double A=m2.y-m1.y,B=m1.x-m2.x,C=m2.x*m1.y-m1.x*m2.y;//求镜子所在直线 
50     if(A*a.x+B*a.y+C==0&&A*b.x+B*b.y+C==0&&!inw) {printf("YES");return 0;}//判断镜子与两个人是否共线 
51     vb.x=b.x-2*A*(A*b.x+B*b.y+C)/(A*A+B*B);//求两个人的翻折点坐标 
52     vb.y=b.y-2*B*(A*b.x+B*b.y+C)/(A*A+B*B);
53     va.x=a.x-2*A*(A*a.x+B*a.y+C)/(A*A+B*B);
54     va.y=a.y-2*B*(A*a.x+B*a.y+C)/(A*A+B*B);
55     node minf1,minf2;minf1.x=-10101.0,minf2.x=10101.0;
56     minf1.y=(C-A*minf1.x)/B,minf2.y=(C-A*minf2.x)/B;
57     if(!intct(a,b,minf1,minf2)&&intct(a,vb,m1,m2)&&intct(b,va,m1,m2)&&!intct(a,vb,w1,w2)&&!intct(va,b,w1,w2)) {printf("YES");return 0;}
58     // 是否在镜子同侧             点与另一个人的翻折点是否会穿过镜子    两个人的光路是否会穿过墙 
59     printf("NO");
60 }
View Code

转载于:https://www.cnblogs.com/yyc-jack-0920/p/7623853.html

你可能感兴趣的:(一道基本的计算几何题)