import static java.lang.Math.*; import static java.util.Arrays.*; import java.util.*; public class Main { double EPS = 1e-10; Scanner sc = new Scanner(System.in); int n, sx, sy, r; P[] ps; void run() { while (sc.hasNext()) { n = sc.nextInt(); sx = sc.nextInt(); sy = sc.nextInt(); r = sc.nextInt(); if ((n|sx|sy|r) == 0) return; ps = new P[n]; for (int i = 0; i < n; i++) ps[i] = new P(sc.nextDouble(), sc.nextDouble()); P init = new P(sx, sy); State s = null; double minD = Double.POSITIVE_INFINITY; for (int i = 0; i < n; i++) { P a = ps[i], b = ps[(i + 1) % n]; P p = proj(a, b, init); if (onSeg(a, b, p) && minD > p.sub(init).abs2()) { minD = p.sub(init).abs2(); s = new State(i, p.add(init.sub(p).norm().mul(r)), false); } if (minD > a.sub(init).abs2()) { minD = a.sub(init).abs2(); s = new State(i, a.add(init.sub(a).norm().mul(r)), true); } } double res = 0; State crt = s; for (boolean moved = false; !moved || crt.id != s.id; ) { State next = crt.next(); if (crt.id != next.id) moved = true; P p = crt.corner ? crt.wall() : proj(ps[crt.id], ps[(crt.id + 1) % n], next.p); P a = p.sub(next.p), b = next.wall().sub(next.p); res += (crt.wall().det(p) + p.det(next.wall()) + r * r * rad(a, b) - a.det(b)) / 2; crt = next; } res += crt.wall().det(s.wall()) / 2; System.out.printf("%.10f%n", res); } } class State { int id; P p; boolean corner; State(int id, P p, boolean corner) { this.id = id; this.p = p; this.corner = corner; } P wall() { if (corner) return ps[id]; return proj(ps[id], ps[(id + 1) % n], p); } State next() { P a = ps[id], b = ps[(id + 1) % n], add1 = b.sub(a).nrr(); if (corner) { State next = new State(id, a.add(add1), false); for (int i = 0; i < n; i++) if (i != id && (i + 1) % n != id) { P c = ps[i], d = ps[(i + 1) % n], add2 = d.sub(c).nrr(); for (P q : isCL(a, r, d.add(add2), c.add(add2))) { if (onSeg(c, d, proj(c, d, q))) { double rad = rad(q.sub(a), p.sub(a)); if (rad < rad(next.p.sub(a), p.sub(a))) { next = new State(i, q, false); } } } for (P q : isCC(ps[i], r, a, r)) { double rad = rad(q.sub(a), p.sub(a)); if (rad < rad(next.p.sub(a), p.sub(a))) { next = new State(i, q, true); } } } return next; } else { State next = new State((id + 1) % n, b.add(add1), true); for (int i = 0; i < n; i++) if (i != id) { P c = ps[i], d = ps[(i + 1) % n], add2 = d.sub(c).nrr(); if (b.sub(a).dot(add2) < -EPS) { P q = isLL(a.add(add1), b.add(add1), c.add(add2), d.add(add2)); if (q != null) { if (onSeg(c, d, proj(c, d, q))) { double dist = q.sub(p).dot(b.sub(a)); if (-EPS < dist && dist < next.p.sub(p).dot(b.sub(a))) { next = new State(i, q, false); } } } } for (P q : isCL(c, r, a.add(add1), b.add(add1))) { double dist = q.sub(p).dot(b.sub(a)); if (-EPS < dist && dist < next.p.sub(p).dot(b.sub(a))) { next = new State(i, q, true); } } } return next; } } } class P { double x, y; P(double x, double y) { this.x = x; this.y = y; } P add(P p) { return new P(x + p.x, y + p.y); } P sub(P p) { return new P(x - p.x, y - p.y); } P mul(double d) { return new P(x * d, y * d); } P div(double d) { return new P(x / d, y / d); } double dot(P p) { return x * p.x + y * p.y; } double det(P p) { return x * p.y - y * p.x; } double abs() { return sqrt(abs2()); } double abs2() { return x * x + y * y; } P norm() { return div(abs()); } P rot90() { return new P(-y, x); } P nrr() { return mul(r / abs()).rot90(); } public String toString() { return String.format("(%.2f, %.2f)", x, y); } } double rad(P u, P v) { double rad = atan2(u.det(v), u.dot(v)); if (rad < -EPS) rad += 2 * PI; return rad; } P proj(P p1, P p2, P q) { return p1.add(p2.sub(p1).mul(p2.sub(p1).dot(q.sub(p1)) / p2.sub(p1).abs2())); } P isLL(P p1, P p2, P q1, P q2) { double d = q2.sub(q1).det(p2.sub(p1)); if (abs(d) < EPS) return null; return p1.add(p2.sub(p1).mul(q2.sub(q1).det(q1.sub(p1)) / d)); } P[] isCL(P c, double r, P p1, P p2) { P v = p2.sub(p1); P q1 = p1.add(v.mul(v.dot(c.sub(p1)) / v.abs2())); double d = r * r - q1.sub(c).abs2(); if (d < -EPS) return new P[0]; P q2 = v.mul(sqrt(max(0, d / v.abs2()))); return new P[] {q1.sub(q2)}; } P[] isCC(P c1, double r1, P c2, double r2) { P v = c2.sub(c1); double d = v.abs(); if (d < EPS) return new P[0]; double x = (r1 * r1 - r2 * r2 + d * d) / (2 * d); if (r1 * r1 - x * x < -EPS) return new P[0]; P q1 = c1.add(v.mul(x / d)); P q2 = v.rot90().mul(sqrt(max(0, r1 * r1 - x * x)) / d); return new P[] {q1.sub(q2)}; } boolean onSeg(P a, P b, P p) { return p.sub(a).dot(p.sub(b)) < EPS; } public static void main(String[] args) { new Main().run(); } }