题意判断一个点a以一个速度发射,遇到圆会反弹,问给定点b是否在点a路径上
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
#define double long double
using namespace std;
const int maxn = 1e5 + 10;
const double EPS = 1e-6;
int T, Case;
double rx, ry, r;
double sx, sy, vx, vy, tx, ty;
struct node{
double x_1, y_1, x_2, y_2;
};
double dist(double x_1, double y_1, double x_2, double y_2){
return sqrt((x_1-x_2)*(x_1-x_2)+(y_1-y_2)*(y_1-y_2));
}
node banana_cunzai(double c, double d, double r, double k, double b){//(x+c)^2+(x+d)^2=r^2
double x_1 = -(sqrt((k*k+1)*r*r-c*c*k*k+(2*c*d+2*b*c)*k-d*d-2*b*d-b*b) + (d+b)*k+c)/(k*k+1);
double y_1 = -(k*(sqrt(k*k*r*r+r*r-c*c*k*k+2*c*d*k+2*b*c*k-d*d-2*b*d-b*b)+c)+d*k*k-b)/(k*k+1);
double x_2 = (sqrt((k*k+1)*r*r-c*c*k*k+(2*c*d+2*b*c)*k-d*d-2*b*d-b*b) + (-d-b)*k-c)/(k*k+1);
double y_2 = -(k*(c-sqrt(k*k*r*r+r*r-c*c*k*k+2*c*d*k+2*b*c*k-d*d-2*b*d-b*b))+d*k*k-b)/(k*k+1);
double d1 = dist(sx, sy, x_1, y_1);
double d2 = dist(sx, sy, x_2, y_2);
if(d1 > d2) swap(x_1, x_2), swap(y_1, y_2);
return node{x_1,y_1,x_2,y_2};
}
node banana_bucun(double rx, double ry, double r, double sx){
double x_1 = sx;
double x_2 = sx;
double y_1 = ry+sqrt(r*r-(sx-rx)*(sx-rx));
double y_2 = ry-sqrt(r*r-(sx-rx)*(sx-rx));
double d1 = dist(sx, sy, x_1, y_1);
double d2 = dist(sx, sy, x_2, y_2);
if(d1 > d2) swap(x_1, x_2), swap(y_1, y_2);
return node{x_1,y_1,x_2,y_2};
}
bool check_dir(double x_1, double y_1, double x_2, double y_2){
if(fabs(x_1*y_2 - x_2*y_1) < EPS && x_1*x_2 >= 0 && y_1*y_2 >= 0) return true;
else return false;
}
double cosin(double x_1, double y_1, double x_2, double y_2){
return (x_1*x_2+y_1*y_2) / (sqrt(x_1*x_1+y_1*y_1)*sqrt(x_2*x_2+y_2*y_2));
}
bool check_tan(double s_x, double s_y, double t_x, double t_y, double r_x, double r_y){\
double x_1 = r_x - rx, y_1 = r_y - ry;
if(fabs(cosin(x_1,y_1,tx-r_x,ty-r_y) - cosin(x_1,y_1,sx-r_x,sy-r_y)) < EPS && !check_dir(r_x-sx,r_y-sy,tx-sx,ty-sy)) return true;
else return false;
}
double p_to_l(double x, double y, double v_x, double v_y, double s_x, double s_y){
double A = v_y / v_x, B = -1; double C = s_y - A * sx;
return fabs(A * x + B * y + C) / sqrt(A * A + B * B);
}
int main()
{
scanf("%d", &T);
while(T --){
cin >> rx >> ry >> r >> sx >> sy >> vx >> vy >> tx >> ty;
printf("Case #%d: ", ++Case);
if(vx == 0){
if(fabs(sx-rx) < r){ //与圆香蕉
node temp = banana_bucun(rx, ry, r, sx);
if(dist(sx,sy,temp.x_1,temp.y_1) - dist(sx,sy,tx,ty) > -EPS //指向⚪但是未香蕉
&& check_dir(temp.x_1-sx,temp.y_1-sy,vx,vy) && check_dir(vx,vy,tx-sx,ty-sy)
) cout << "Yes" << endl;
else if(check_dir(-temp.x_1+sx,-temp.y_1+sy,vx,vy)) cout << "Yes" << endl;
else if(check_tan(sx, sy, tx, ty, temp.x_1, temp.y_1)) cout << "Yes" << endl;
else cout << "No" << endl;
}
else{
double t_x = tx - sx, t_y = ty - sy;
if(t_y * vy >= 0 && t_x == 0) cout << "Yes" << endl;
else cout << "No" << endl;
}
}
else{
if(p_to_l(rx, ry, vx, vy, sx, sy) >= r){//不相交
if(check_dir(tx-sx,ty-sy,vx,vy)) cout << "Yes" << endl;
else cout << "No" << endl;
}
else{
double k = vy / vx; double b = sy - k * sx;
node temp = banana_cunzai(-rx, -ry, r, k, b);//(x+c)^2+(x+d)^2=r^2
if(dist(sx,sy,temp.x_1,temp.y_1) - dist(sx,sy,tx,ty) > -EPS //指向⚪但是未香蕉
&& check_dir(temp.x_1-sx,temp.y_1-sy,vx,vy) && check_dir(vx,vy,tx-sx,ty-sy)
) cout << "Yes" << endl;
else if(check_dir(-temp.x_1+sx,-temp.y_1+sy,vx,vy)) cout << "Yes" << endl;
else if(check_tan(sx, sy, tx, ty, temp.x_1, temp.y_1)) cout << "Yes" << endl;
else cout << "No" << endl;
}
}
}
return 0;
}