//#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\n");
}else{
printf("No\n");
}
continue;
}else printf("No\n");
}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\n");
continue;
}else{
printf("Yes\n");
continue;
}
}else{
if(yuan.relationseg(l2)>=2){
printf("No\n");
continue;
}
double d1=l1.dispointtoline(yuanxin);
double d2=l2.dispointtoline(yuanxin);
if(fabs(d1-d2)<eps){ //两个直线镜面
printf("Yes\n");
}else printf("No\n");
}
}else{
if(fabs(l1.dispointtoline(B))<eps){
if(int(B.x-A.x)*int(vy)==int(B.y-A.y)*int(vx)){
printf("Yes\n");
}else{
printf("No\n");
}
continue;
}else printf("No\n");
}
}
}
}
QAQ !
第一发计算几何题,WA5小时才过去
自己的几何能力还是过得去的,很快想出了最复杂情况的做法
(敲的时候把脑内秒过的简单情况给忘了QAQ
不过因为第一次用模板,接口不熟,把自己坑爆了
刚几何!