这个题直接自闭到结尾
定义p1_1(为p1的方向点)首先判断p1_1与p1的直线与圆的交点如果交点个数小于等于2个只要判断p2点与p1到p1_1的方向向量同向(判断方法为叉积为0说明平行点积大于0说明同向)
当直线与圆交点的个数为2时,这时候情况比较特殊,p3_1为与圆的交点离p1最近的点,情况1:p1的方向刚好是往圆那个方向上走去,并且p2点刚好在p1与p3_1这条线段上这时候肯定能碰到!!,
情况2:p3_1与p1与p2三点共线,这时候分类讨论,如果p1的方向是离开圆的而p2的点比p1的点距离圆更近这时候也不可能碰见,否则是一定可以碰见的因为如果p1往圆上走会反弹回来
情况3:过p3_1与圆心o的直线做p1的对称点判断对称点与p2是否共线
#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef double ld;
const ld eps=1e-8;
const ld pi=acos(-1.0);
int sgn(ld x)
{
if(fabs(x)<eps) return 0;
if(x<0) return -1;
else return 1;
}
struct Point{
ld x,y;
Point(){}
Point(ld _x,ld _y)
{
x=_x;
y=_y;
}
Point operator - (const Point &b)const{
return Point(x - b.x,y - b.y);
}
ld operator ^(const Point &b)const{
return x*b.y - y*b.x;
}
ld distance(Point p){
return hypot(x - p.x,y - p.y);
}
ld operator *(const Point &b)const{
return x*b.x + y*b.y;
}
ld len(){
return hypot(x,y);//库函数
}
ld len2(){
return x*x + y*y;
}
Point operator *(const ld &k)const{
return Point(x*k,y*k);
}
Point trunc(ld r){
ld l = len();
if(!sgn(l))return *this;
r /= l;
return Point(x*r,y*r);
}
Point operator +(const Point &b)const{
return Point(x+b.x,y+b.y);
}
Point operator /(const ld &k)const{
return Point(x/k,y/k);
}
};
struct Line{
Point s,e;
Line(){}
Line(Point _s,Point _e)
{
s=_s;
e=_e;
}
ld length(){
return s.distance(e);
}
ld dispointtoline(Point p){
return fabs((p - s)^(e - s))/length();
}
Point lineprog(Point p){
return s + ( ((e - s)*((e - s)*(p - s)))/((e - s).len2()) );
}
int relation(Point p){
int c = sgn((p - s)^(e - s));
if(c < 0)return 1;
else if(c > 0)return 2;
else return 3;
}
Point symmetrypoint(Point p){
Point q = lineprog(p);
return Point(2*q.x - p.x,2*q.y - p.y);
}
bool pointonseg(Point p){
return sgn((p-s)^(e-s)) == 0 && sgn((p-s)*(p-e)) <= 0;
}
};
struct circle{
Point p;
ld r;
circle(){}
circle(Point _p,ld _r)
{
p=_p;
r=_r;
}
int relationline(Line v){
ld dst = v.dispointtoline(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);
ld 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 main()
{
int t;
cin>>t;
int kace=1;
while(t--)
{
ld ox,oy,r,ax,ay,vx,vy,bx,by;
cin>>ox>>oy>>r;
cin>>ax>>ay>>vx>>vy;
cin>>bx>>by;
Point p1=Point(ax,ay);
Point p2=Point(bx,by);
Point o=Point(ox,oy);
Point p1_1=Point((ax+vx),(ay+vy));
Line line1=Line(p1,p1_1);
circle cir=circle(o,r);
Point p3_1,p3_2;
int k=cir.pointcrossline(line1,p3_1,p3_2);
if(k<=1)
{
if(line1.relation(p2)==3)
{
ld cc1=(p1_1-p1)*(p2-p1);
if(sgn(cc1)>0)
printf("Case #%d: Yes\n",kace++);
else
printf("Case #%d: No\n",kace++);
}
else printf("Case #%d: No\n",kace++);
}
else
{
ld a1=p1.distance(p3_1);
ld a2=p1.distance(p3_2);
if(a1>a2)
swap(p3_1,p3_2);
Line line2=Line(p3_1,o);
Point pp1=line2.symmetrypoint(p1);
ld ans=(pp1-p3_1)^(p2-p3_1);
Line op1=Line(o,p3_1);
Line ap1=Line(p1,p3_1);
if(ap1.pointonseg(p2)&&sgn((p2-p1)*(p3_1-p1))>0)
{
printf("Case #%d: Yes\n",kace++);
continue;
}
Line line3=Line(p3_1,pp1);
if(line3.relation(p2)==3)
{
if(((p1-o)^(p2-o))==0)
{
ld att2=(o-p1)*(p1_1-p1);
if(sgn(att2)<0)
{
if(sgn(p2.distance(o)-p1.distance(o))<0)
printf("Case #%d: No\n",kace++);
else
printf("Case #%d: Yes\n",kace++);
}
else
printf("Case #%d: Yes\n",kace++);
}
else
printf("Case #%d: Yes\n",kace++);
}
else printf("Case #%d: No\n",kace++);
}
}
return 0;
}