You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
2.5 KiB
C++

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps = 1e-8;
int cmp(double x)
{
if (x > eps)
return 1;
if (x < -eps)
return -1;
return 0;
}
typedef struct
{
double x, y;
} Base2D, Point, Vector;
typedef const Point &CBase2DRef;
typedef const Point &CPointRef;
typedef const Vector &CVectorRef;
inline Base2D operator+(CBase2DRef l, CBase2DRef r) { return {l.x + r.x, l.y + r.y}; }
inline Base2D operator-(CBase2DRef l, CBase2DRef r) { return {l.x - r.x, l.y - r.y}; }
inline Base2D operator*(CBase2DRef l, double r) { return {l.x * r, l.y * r}; }
inline double cross(CVectorRef l, CVectorRef r) { return l.x * r.y - l.y * r.x; }
inline double square(double x) { return x * x; }
inline double dis2(CPointRef l, CPointRef r) { return square(r.x - l.x) + square(r.y - l.y); }
int main()
{
int T;
scanf("%d", &T);
for (int t = 1; t <= T; t++)
{
double ox, oy, r, ax, ay, vx, vy, bx, by;
scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf", &ox, &oy, &r, &ax, &ay, &vx, &vy, &bx, &by);
Vector dir = {vx, vy};
Point o = {ox, oy}, a = {ax, ay}, b = {bx, by};
bool flag = false;
Vector oa = a - o, ba = a - b, bo = o - b;
double fx = (bx - ax) / vx, fy = (by - ay) / vy;
if (cmp(fx) == 1 && cmp(fx - fy) == 0) // Hit
{
if (cross(oa, dir) == 1 || cmp(cross(ba, bo)) <= 0 || abs(cross(oa, bo) / sqrt(dis2(ba, {0, 0}))) >= r)
flag = true;
}
else
{
double dis = abs(cross(oa, oa + dir) / sqrt(dis2(dir, {0, 0})));
if (dis <= r)
{
// get first intersect
double disInCircle = sqrt(r * r - dis * dis);
double disOutCircle = sqrt(dis2(oa, {0, 0}) - dis * dis) - disInCircle;
double scale = disOutCircle / sqrt(dis2(dir, {0, 0}));
Point intersect = a + dir * scale;
// mirror the line
double A = intersect.y - o.y, B = o.x - intersect.x, C = intersect.x * o.y - o.x * intersect.y;
double k = -2 * (A * a.x + B * a.y + C) / (A * A + B * B);
Point am = {a.x + k * A, a.y + k * B};
Vector dir2 = am - intersect;
fx = (b.x - intersect.x) / dir2.x, fy = (b.y - intersect.y) / dir2.y;
if (cmp(fx) == 1 && cmp(fx - fy) == 0)
flag = true;
}
}
printf("Case #%d: %s\n", t, flag ? "Yes" : "No");
}
return 0;
}