//#include<bits/stdc++.h> //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<iostream> #include<math.h> #include<set> #include<map> #include<vector> #include<iomanip> using namespace std; const double pi=acos(-1.0); #define ll long long #define pb push_back const double eps=1e-6; int sgn(double x){ if(fabs(x)<eps)return 0; if(x<0)return -1; else return 1; } struct Point{ double x,y; Point(){} Point(double _x,double _y){x=_x;y=_y;} double distance(Point p){ return hypot(x-p.x,y-p.y); } Point operator +(const Point &b)const{ return Point(x+b.x,y+b.y); } Point operator -(const Point &b)const{ return Point(x-b.x,y-b.y); } double operator *(const Point &b)const{ return x*b.x+y*b.y; } Point operator *(const double &k)const{ return Point(x*k,y*k); } Point operator /(const double &k)const{ return Point(x/k,y/k); } double operator^(const Point &b)const{ return x*b.y-y*b.x; } double len(){return hypot(x,y);} double len2(){ return x*x+y*y; } Point trunc(double r){ double l=len(); if(!sgn(l))return *this; r/=l; return Point(x*r,y*r); } }; struct Line{ Point s,e; Line(){} Line (Point _s,Point _e){ s=_s;e=_e; } Line(Point p,double angle){//与x轴夹角 s=p; if(sgn(angle-pi/2)==0)e=(s+Point(0,1)); else e=(s+Point(1,tan(angle))); } double length(){return s.distance(e);} double dispointtoline(Point p){ return fabs((p-s)^(e-s))/length(); } double dispointtoseg(Point p){ if(sgn((p-s)*(e-s))<0 || sgn((p-e)*(s-e))<0) return min(p.distance(s),p.distance(e)); return dispointtoline(p); } Point lineprog(Point p){ return s+( ((e-s)*((e-s)*(p-s)))/((e-s).len2()) ); } }; struct circle{ Point p; double r; circle(Point _p,double _r){ p=_p;r=_r; } int relationline(Line v){ double dst=v.dispointtoline(p); if(sgn(dst-r)<0)return 2; else if(sgn(dst-r)==0)return 1; return 0; } int relationseg(Line v){ double dst=v.dispointtoseg(p); if(sgn(dst-r)<0)return 2; else if(sgn(dst-r)==0)return 1; return 0; } int pointcrossline(Line v,Point &p1,Point &p2){ if(!(*this).relationline(v))return 0; Point a=v.lineprog(p); double d=v.dispointtoline(p); d=sqrt(r*r-d*d); if(sgn(d)==0){ p1=a;p2=a;return 1; } p1=a+(v.e-v.s).trunc(d); p2=a-(v.e-v.s).trunc(d); return 2; } }; int check(Point A,Point B,Point C){ if(B.x==C.x){ if((B.y-C.y)*(A.y-C.y)<0)return 1; return 0; }else if(B.y==C.y){ if( (B.x-C.x)*(A.x-C.x)<0)return 1; return 0; } if( (B.x-C.x)*(A.x-C.x)<0 )return 1; return 0; } int main(){ int T; scanf("%d",&T); int kase=0; while(T--){ double x,y,r; scanf("%lf%lf%lf",&x,&y,&r); Point yuanxin=Point(x,y); circle yuan=circle(yuanxin,r); //圆柱 yuan Point A; scanf("%lf%lf",&x,&y);A=Point(x,y); //源点 A double vx,vy;scanf("%lf%lf",&vx,&vy); Line l1; Point to;to=Point(vx+x,vy+y); l1=Line(A,to); //初始直线 l1 double bx,by;scanf("%lf%lf",&bx,&by); Point B=Point(bx,by); //终端 B Point p1,p2; int xiangjiao=0; xiangjiao=yuan.pointcrossline(l1,p1,p2); printf("Case #%d: ",++kase); if(!xiangjiao){ if(fabs(l1.dispointtoline(B))<eps){ if(int(B.x-A.x)*int(vy)==int(B.y-A.y)*int(vx)){ printf("Yes "); }else{ printf("No "); } continue; }else printf("No "); }else{ //路径直线香蕉 //p1,p2是两个直线与圆的交点 //要靠近A的交点 Point bounce; double dis1=(A.x-p1.x)*(A.x-p1.x)+(A.y-p1.y)*(A.y-p1.y); double dis2=(A.x-p2.x)*(A.x-p2.x)+(A.y-p2.y)*(A.y-p2.y); if(dis1<dis2)bounce=p1;else bounce=p2; Point C=bounce; int way=1;//速度指向圆 if(vx==0){ if( (C.y-A.y)*vy<0 )way=0; }else if(vy==0){ if( (C.x-A.x)*vx<0)way=0; }else{ if( (C.x-A.x)*vx<0 || (C.y-A.y)*vy<0)way=0; } // cout<<way<<endl; if(way==1){ //会反弹 Line l2=Line(B,bounce); if(fabs(l1.dispointtoline(B))<eps){ if(check(A,B,C)){ printf("No "); continue; }else{ printf("Yes "); continue; } }else{ if(yuan.relationseg(l2)>=2){ printf("No "); continue; } double d1=l1.dispointtoline(yuanxin); double d2=l2.dispointtoline(yuanxin); if(fabs(d1-d2)<eps){ //两个直线镜面 printf("Yes "); }else printf("No "); } }else{ if(fabs(l1.dispointtoline(B))<eps){ if(int(B.x-A.x)*int(vy)==int(B.y-A.y)*int(vx)){ printf("Yes "); }else{ printf("No "); } continue; }else printf("No "); } } } }
QAQ !
第一发计算几何题,WA5小时才过去
自己的几何能力还是过得去的,很快想出了最复杂情况的做法
(敲的时候把脑内秒过的简单情况给忘了QAQ
不过因为第一次用模板,接口不熟,把自己坑爆了
刚几何!