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++
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;
|
|
} |