【poj 1263】球面反射

题目链接:https://vjudge.net/problem/POJ-1263

给你一个球的起始点和方向,球在圆面反射来反射去。

这题也是很少人过。基本上就是用到那几个常用函数:求点关于直线的对称点,求直线与圆的交点,向量旋转。。瞎搞搞。。。

  1 /*************************************************************************
  2     > File Name: poj1263.cpp
  3 # File Name: poj1263.cpp
  4 # Author : xiaobuxie
  5 # QQ : 760427180
  6 # Email:[email protected]
  7 # Created Time: 2019年10月26日 星期六 16时35分55秒
  8  ************************************************************************/
  9 
 10 #include<iostream>
 11 #include<cstdio>
 12 #include<map>
 13 #include<cmath>
 14 #include<cstring>
 15 #include<set>
 16 #include<queue>
 17 #include<vector>
 18 #include<algorithm>
 19 using namespace std;
 20 typedef long long ll;
 21 #define inf 0x3f3f3f3f
 22 #define eps 1e-8
 23 int sgn(double x){
 24     if(fabs(x) < eps) return 0;
 25     if(x<0) return -1;
 26     return 1;
 27 }
 28 const int N = 40;
 29 const double pi = acos(-1.0);
 30 struct Line{
 31     double a,b,c;
 32 };
 33 struct Point{
 34     double x,y;
 35     Point(){x=y=0;}
 36 
 37     Point(double a,double b){x=a,y=b;}
 38 
 39     Point operator - (const Point& b)const
 40     {return Point(x-b.x,y-b.y);}
 41 
 42     Point operator + (const Point& b)const
 43     {return Point(x+b.x,y+b.y);}
 44 
 45     Point operator * (const double& b)const
 46     {return Point(x*b,y*b);}
 47 
 48     Point rotate(const double& b)const
 49     {return Point( x*cos(b) - y*sin(b) , x*sin(b) + y*cos(b) );}
 50 
 51     Point corPoint(Line l)const{
 52         Point p2;
 53         double d = l.a*l.a + l.b*l.b;
 54         p2.x = ( (l.b*l.b - l.a*l.a)*x - 2 * l.a * l.b * y - 2*l.a*l.c) /d;
 55         p2.y = ( (l.a*l.a - l.b*l.b)*y - 2 * l.a * l.b * x - 2*l.b*l.c) /d;
 56         return p2;
 57     }
 58 
 59     double dot (const Point& b)const
 60     {return x*b.x+y*b.y;}
 61 
 62     double cross (const Point& b,const Point& c)const
 63     {return (b.x - x)*(c.y - y) - (c.x - x)*(b.y - y);}
 64 
 65     double ToPdis (const Point& b)const
 66     {return sqrt( (x-b.x)*(x-b.x) + (y-b.y)*(y-b.y) );}
 67 
 68     double ToLdis (Line l)const{
 69         return fabs(l.a * x + l.b * y + l.c) / sqrt(l.a*l.a + l.b*l.b);
 70     }
 71 
 72     bool OnLine (const Point& st,Point& ed)const
 73     {return !sgn(cross(st,ed));}
 74 
 75     bool OnSeg (const Point& st,Point& ed)const
 76     {return OnLine(st,ed) && (*this - ed).dot(*this - st) < eps;}
 77 };
 78 struct Circle{
 79     Point c;
 80     double r;
 81 }cir[N];
 82 
 83 Line twoPoLine(Point p1,Point p2){
 84     Line l;
 85     l.a = p2.y - p1.y;
 86     l.b = p1.x - p2.x;
 87     l.c = p2.x * p1.y - p1.x * p2.y;
 88     return l;
 89 }
 90 
 91 Point LineCross(Point a,Point b,Point c,Point d){
 92     double u = a.cross(b,c), v = b.cross(a,d);
 93     return Point( (c.x*v + d.x*u)/(u+v) , (c.y*v + d.y*u)/(u+v) );
 94 }
 95 
 96 double LineCrossCircle(Point a,Point b,Point o,double r,Point& p1,Point& p2){
 97     Point fp = LineCross(o,Point(o.x + a.y - b.y,o.y + b.x - a.x),a,b);
 98     double atob = a.ToPdis(b);
 99     double otol = o.ToPdis(fp);
100     double fptoe = sqrt( r*r - otol*otol ) / atob;
101     if( otol > r - eps) return otol;
102     p1 = fp + (a-b)*fptoe;
103     p2 = fp + (b-a)*fptoe;
104     return otol;
105 }
106 Point now,dir;
107 int n;
108 int find(){
109     int id = -1;
110     Point tp;
111     for(int i = 1;i<=n;++i){
112         Point p1,p2;
113         double dis = LineCrossCircle(now,dir,cir[i].c,cir[i].r,p1,p2);
114         if(dis - cir[i].r > -eps) continue;
115         if(sgn((dir - now).dot(p1 - now)) <  0) continue;
116         //cerr<<'p'<<p1.x<<' '<<p1.y<<endl;
117         //cerr<<i<<'a'<<now.cross(p1,dir)<<' '<<now.x<<' '<<now.y<<' '<<dir.x<<' '<<dir.y<<endl;
118         if( id == -1 || p1.ToPdis(now) < tp.ToPdis(now) ){
119             tp = p1;
120             id = i;
121         }
122         if( id == -1 || p2.ToPdis(now) < tp.ToPdis(now) ){
123             tp = p2;
124             id = i;
125         }
126     }
127     if(id == -1) return id;
128     Point tem = cir[id].c - tp;
129     tem = tem.rotate(pi/2.0);
130     tem = tem + tp;
131     Line l = twoPoLine(tem,tp);
132     Point tt = now.corPoint(l);
133     tem = tp - tt;
134     now = tp;
135     dir = tem + now;
136     return id;
137 }
138 int main(){
139     int cas = 0;
140     while(~scanf("%d",&n) && n){
141         printf("Scene %d\n",++cas);
142         for(int i = 1;i<=n;++i) scanf("%lf %lf %lf",&cir[i].c.x,&cir[i].c.y,&cir[i].r);
143         scanf("%lf %lf %lf %lf",&now.x,&now.y,&dir.x,&dir.y);
144         dir = now + dir;
145         int sum = 0;
146         int id=1;
147         while(1){
148             int id = find();
149             if(id == -1) break;
150             ++sum;
151             if(sum > 10) break;
152             printf("%d ",id);
153         }
154         if(sum <= 10) printf("inf\n\n");
155         else printf("...\n\n");
156     }
157     return 0;
View Code

猜你喜欢

转载自www.cnblogs.com/xiaobuxie/p/11754488.html
POJ