傻逼模板题
using namespace std;
const double eps = 1e-8;
const double pi = acos(-1);
int dcmp(double x) {
if (fabs(x) <eps) return 0;
return x < 0 ? -1 : 1;
}
struct point {
double x, y;
point (double x = 0, double y = 0) :x(x), y(y) {}
void input() {
scanf("%lf%lf", &x, &y);
}
void output() {
printf("x = %f y = %f\n", x, y);
}
point operator + (const point &rhs) const {
return point(x + rhs.x, y + rhs.y);
}
point operator - (const point &rhs) const {
return point(x - rhs.x, y - rhs.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 len2() {
return x * x + y * y;
}
point change_len(double r) {
double l = sqrt(len2());
if (dcmp(l) == 0) return *this;
r /= l;
return point(x * r, y * r);
}
};
double cross(point a, point b) {
return a.x * b.y - a.y * b.x;
}
double dot(point a, point b) {
return a.x * b.x + a.y * b.y;
}
double dis(point a, point b) {
return sqrt(dot(a - b, a - b));
}
double rad(point a, point b) {
return fabs(atan2(fabs(cross(a, b)), dot(a, b)));
}
struct circle {
point p;
double r;
circle() {}
circle(point p, double r) :p(p), r(r) {}
double area() {
return pi * r * r;
}
};
struct line {
point s, e;
double length() {
return dis(s, e);
}
line() {}
line(point s, point e) :s(s), e(e) {}
};
double point_to_line(point p, line a) {
return fabs(cross(p - a.s, a.e - a.s) / a.length());
}
point projection(point p, line a) {
return a.s + (((a.e - a.s) * dot(a.e - a.s, p - a.s)) / (a.e - a.s).len2());
}
int relation(line a, circle b) {
double p = point_to_line(b.p, a);
if (dcmp(p - b.r) == 0) return 1;
return dcmp(p - b.r) < 0 ? 2 : 0;
}
int relation(point p, circle a) {
double d = dis(p, a.p);
if (dcmp(d - a.r) == 0) return 1;
return dcmp(d - a.r) < 0 ? 2 : 0;
}
int line_circle_intersection(line v, circle u, point &p1, point &p2) {
if (!relation(v, u)) return 0;
point a = projection(u.p, v);
double d = point_to_line(u.p, v);
d = sqrt(u.r * u.r - d * d);
if (dcmp(d) == 0) {
p1 = p2 = a;
return 1;
}
p1 = a + (v.e - v.s).change_len(d);
p2 = a - (v.e - v.s).change_len(d);
return 2;
}
double cir_tra_area(point a, point b, circle c) {
point p = c.p; double r = c.r;
if (dcmp(cross(p - a, p - b)) == 0) return 0;
point q[5];
int len = 0;
q[len++] = a;
line l(a, b);
point p1, p2;
if (line_circle_intersection(l, c, q[1], q[2]) == 2) {
if (dcmp(dot(a - q[1], b - q[1])) < 0) q[len++] = q[1];
if (dcmp(dot(a - q[2], b - q[2])) < 0) q[len++] = q[2];
}
q[len++] = b;
if (len == 4 && dcmp(dot(q[0] - q[1], q[2] - q[1])) > 0) swap(q[1], q[2]);
double res = 0;
for (int i = 0; i < len - 1; i++) {
if (relation(q[i], c) == 0 || relation(q[i + 1], c) == 0) {
double ang = rad(q[i] - p, q[i + 1] - p);
res += r * r * ang / 2.0;
}
else {
res += fabs(cross(q[i] - p, q[i + 1] - p)) / 2;
}
}
return res;
}
double area_poly_cir(circle c, point *p, int n) {
double ans = 0;
for (int i = 0; i < n; i++) {
int j = (i + 1) % n;
if (dcmp(cross(p[j] - c.p, p[i] - c.p)) >= 0) ans += cir_tra_area(p[i], p[j], c);
else ans -= cir_tra_area(p[i], p[j], c);
}
return fabs(ans);
}
double poly_area(point *p, int n) {
double area = 0;
for (int i = 1; i < n - 1; i++) {
area += cross(p[i] - p[0], p[i + 1] - p[0]);
}
return fabs(area / 2);
}
point poly[222];
int n, p, q, m;
circle cc;
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i++) poly[i].input();
long double s = poly_area(poly, n);
scanf("%d", &m);
while (m--) {
cc.p.input();
scanf("%d%d", &p, &q);
p = q - p;
long double l = 0, r = 1e4;
for (int i = 0; i < 100; i++) {
long double mid = (l + r) / 2;
cc.r = mid;
long double tmp = area_poly_cir(cc, poly, n);
if (tmp * q < s * p) l = mid;
else r = mid;
}
double ans = (l + r) / 2;
printf("%.12f\n", ans);
}
}