#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <limits>
#include <vector>
namespace lc {
static const double EPS = 1e-9;
inline double abs(double x){ return std::abs(x); }
inline bool tolerant_eq(double a, double b){ return abs(a - b) < EPS; }
}
namespace lc {
struct Point {
	double x;
	double y;
	explicit Point(const double &x = 0.0, const double &y = 0.0) :
		x(x), y(y)
	{ }
	Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
	Point &operator+=(const Point &p){ return *this = *this + p; }
	Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
	Point operator*(double s) const { return Point(x * s, y * s); }
	Point operator/(double s) const { return Point(x / s, y / s); }
	double abs() const { return sqrt(x * x + y * y); }
	double norm() const { return x * x + y * y; }
	Point unit() const { return *this / abs(); }
	Point ortho() const { return Point(-y, x); }
	double arg() const { return atan2(y, x); }
};
inline Point operator*(double s, const Point &p){ return p * s; }
inline bool tolerant_eq(const Point &a, const Point &b){
	return tolerant_eq(a.x, b.x) && tolerant_eq(a.y, b.y);
}
inline double cross(const Point &a, const Point &b){
	return a.x * b.y - a.y * b.x;
}
inline double dot(const Point &a, const Point &b){
	return a.x * b.x + a.y * b.y;
}
inline int ccw(const Point &a, const Point &b, const Point &c){
	Point d = b - a, e = c - a;
	if(cross(d, e) > 0.0){ return 1; }
	if(cross(d, e) < 0.0){ return -1; }
	if(dot(d, e) < 0.0){ return 2; }
	if(d.abs() < e.abs()){ return -2; }
	return 0;
}
}
namespace lc {
struct Line {
	Point a;
	Point b;
	explicit Line(const Point &a = Point(), const Point &b = Point()) :
		a(a), b(b)
	{ }
	Point projection(const Point &p) const {
		double t = dot(p - a, b - a) / (b - a).norm();
		return a + t * (b - a);
	}
	Point direction() const {
		return (b - a).unit();
	}
};
inline bool tolerant_eq(const Line &a, const Line &b){
	const double x = abs(cross(a.b - a.a, b.b - b.a));
	const double y = abs(cross(a.b - a.a, a.b - b.a));
	return x < EPS && y < EPS;
}
}
namespace lc {
struct Circle {
	Point c;
	double r;
	explicit Circle(const Point &c = Point(), double r = 0.0) :
		c(c), r(r)
	{ }
};
}
namespace lc {
struct Segment {
	Point a;
	Point b;
	explicit Segment(const Point &a = Point(), const Point &b = Point()) :
		a(a), b(b)
	{ }
	Line to_line() const { return Line(a, b); }
};
}
namespace lc {
class Polygon {
private:
	std::vector<Point> m_points;
public:
	Polygon() : m_points() { }
	explicit Polygon(size_t s, const Point &p = Point())
		: m_points(s, p)
	{ }
	template <typename Iterator>
	explicit Polygon(Iterator begin, Iterator end)
		: m_points(begin, end)
	{ }
	explicit Polygon(std::initializer_list<Point> init)
		: m_points(init)
	{ }
	const Point &operator[](int i) const { return m_points[i]; }
	Point &operator[](int i){ return m_points[i]; }
	Segment side(int i) const {
		return Segment(m_points[i], m_points[(i + 1) % m_points.size()]);
	}
	int size() const { return static_cast<int>(m_points.size()); }
	double area() const {
		double s = 0.0;
		for(int i = 0; i < size(); ++i){
			s += cross(m_points[i], m_points[(i + 1) % size()]);
		}
		return s * 0.5;
	}
};
}
namespace lc {
inline bool intersect(const Point &a, const Segment &b){
	return (b.a - a).abs() + (b.b - a).abs() - (b.b - b.a).abs() < EPS;
}
inline bool intersect(const Segment &a, const Point &b){
	return intersect(b, a);
}
inline bool intersect(const Line &a, const Segment &b){
	return cross(a.b - a.a, b.a - a.a) * cross(a.b - a.a, b.b - a.a) < EPS;
}
inline bool intersect(const Segment &a, const Line &b){
	return intersect(b, a);
}
}
namespace lc {
inline double distance(const Point &a, const Line &b){
	const Point p = b.projection(a);
	return (a - p).abs();
}
inline double distance(const Point &a, const Segment &b){
	const Point p = b.to_line().projection(a);
	if(intersect(b, p)){ return (a - p).abs(); }
	return std::min((b.a - a).abs(), (b.b - a).abs());
}
}
namespace lc {
inline std::vector<Point> crossing_points(const Line &a, const Line &b){
	std::vector<Point> ret;
	if(lc::tolerant_eq(a, b)){
		ret.push_back(a.a);
		ret.push_back(a.b);
	}else{
		const double x = cross(a.b - a.a, b.b - b.a);
		const double y = cross(a.b - a.a, a.b - b.a);
		if(abs(x) >= EPS){ ret.push_back(b.a + y / x * (b.b - b.a)); }
	}
	return ret;
}
inline std::vector<Point> crossing_points(const Line &l, const Circle &c){
	const Point &p = l.projection(c.c);
	const double t = (p - c.c).abs();
	if(t > c.r + EPS){ return std::vector<Point>(); }
	if(t > c.r - EPS){ return std::vector<Point>(1, p); }
	const Point v = l.direction();
	const double d = sqrt(c.r * c.r - t * t);
	return std::vector<Point>({ p + d * v, p - d * v });
}
inline std::vector<Point> crossing_points(const Segment &s, const Circle &c){
	const std::vector<Point> cps(crossing_points(s.to_line(), c));
	std::vector<Point> result;
	for(const auto &p : cps){
		if(intersect(s, p)){ result.push_back(p); }
	}
	return result;
}
}
namespace lc {
double straight_move(const Circle &c, Point dir, const Point &obstacle){
	const double inf = std::numeric_limits<double>::infinity();
	dir = dir.unit();
	if(ccw(c.c, c.c + dir.ortho(), obstacle) != -1){ return inf; }
	const Line dir_line(c.c, c.c + dir);
	const Point proj = dir_line.projection(obstacle);
	const double a = (obstacle - proj).abs();
	if(a >= c.r){ return inf; }
	const double b = sqrt(c.r * c.r - a * a);
	return ((proj - b * dir) - c.c).abs();
}
double straight_move(const Circle &c, Point dir, const Segment &obstacle){
	dir = dir.unit();
	const Line dir_line(c.c, c.c + dir);
	const Point delta = (obstacle.b - obstacle.a).unit().ortho();
	double answer = std::min(
		straight_move(c, dir, obstacle.a), straight_move(c, dir, obstacle.b));
	for(int i = -1; i <= 1; i += 2){
		const Point d(i * c.r * delta);
		const Segment s(obstacle.a + d, obstacle.b + d);
		if(!intersect(s, dir_line)){ continue; }
		const auto cps = crossing_points(dir_line, s.to_line());
		if(cps.size() != 1){ continue; }
		if(ccw(c.c, c.c + dir.ortho(), cps[0] - d) != -1){ continue; }
		answer = std::min(answer, (cps[0] - c.c).abs());
	}
	return answer;
}
}
using namespace std;
static const double INF = 1e10;
double rotate_move(
	const lc::Point &p, double start, double r, const lc::Point &obstacle)
{
	const lc::Point cc = p + r * lc::Point(cos(start), sin(start));
	const lc::Point dv = obstacle - p;
	const double d = dv.abs();
	if(d >= 2.0 * r){ return start - M_PI; }
	if(lc::tolerant_eq((cc - obstacle).abs(), r)){
		if(lc::ccw(p, cc, obstacle) == -1){
			return start;
		}else{
			return start - M_PI;
		}
	}
	const lc::Point c =
		p + dv * 0.5 + dv.unit().ortho() * sqrt(r * r - d * d * 0.25);
	double answer = (c - p).arg() + 2.0 * M_PI;
	while(answer >= start - lc::EPS){ answer -= 2.0 * M_PI; }
	return max(answer, start - M_PI);
}
double rotate_move(
	const lc::Point &p, double start, double r, const lc::Segment &obstacle)
{
	if(lc::tolerant_eq(p, obstacle.b)){ return start - M_PI; }
	double answer = -2.0 * M_PI;
	if(lc::tolerant_eq(p, obstacle.a)){
		answer = (obstacle.b - obstacle.a).unit().ortho().arg();
		while(answer > start + lc::EPS){ answer -= 2.0 * M_PI; }
		return answer;
	}else{
		answer = max(
			rotate_move(p, start, r, obstacle.a),
			rotate_move(p, start, r, obstacle.b));
	}
	const lc::Point shift = (obstacle.b - obstacle.a).unit().ortho();
	const lc::Segment shifted_obstacle(
		obstacle.a + shift * r, obstacle.b + shift * r);
	const lc::Circle cpath(p, r);
	const auto cps = lc::crossing_points(shifted_obstacle, cpath);
	if(cps.empty()){
		return answer;
	}
	const lc::Point cc = p + r * lc::Point(cos(start), sin(start));
	if(lc::tolerant_eq(lc::distance(cc, obstacle), r)){
		const auto touch = lc::crossing_points(obstacle, lc::Circle(cc, r));
		if(!lc::tolerant_eq(p, touch[0]) && lc::ccw(p, cc, touch[0]) == -1){
			return start;
		}
	}
	double srot = (cps[0] - p).arg() + 2.0 * M_PI;
	while(srot >= start - lc::EPS){ srot -= 2.0 * M_PI; }
	answer = max(answer, srot);
	return max(answer, start - M_PI);
}
int main(){
	ios_base::sync_with_stdio(false);
	cout << setiosflags(ios::fixed) << setprecision(10);
	while(true){
		int n;
		double sx, sy, r;
		cin >> n >> sx >> sy >> r;
		if(n == 0 && sx == 0.0 && sy == 0.0 && r == 0){ break; }
		lc::Polygon poly(n);
		for(int i = 0; i < n; ++i){
			double x, y;
			cin >> x >> y;
			poly[i] = lc::Point(x - sx, y - sy);
		}
		lc::Circle cur(lc::Point(0.0, 0.0), r);
		double init_x = INF;
		for(int i = 0; i < n; ++i){
			const auto s = poly.side(i);
			init_x = min(
				init_x, lc::straight_move(cur, lc::Point(1.0, 0.0), s));
		}
		cur.c.x = init_x;
		lc::Point prev;
		for(int i = 0; i < n; ++i){
			if(!lc::tolerant_eq((cur.c - poly[i]).abs(), cur.r)){ continue; }
			const double start = (cur.c - poly[i]).arg();
			double goal = start - M_PI;
			for(int j = 0; j < n; ++j){
				goal = max(goal, rotate_move(poly[i], start, cur.r, poly.side(j)));
			}
			cur.c = poly[i] + cur.r * lc::Point(cos(goal), sin(goal));
			prev = poly[i];
			break;
		}
		int start_point = -1;
		for(int i = 0; i < n; ++i){
			const lc::Segment &side = poly.side(i);
			const lc::Line &line = side.to_line();
			if(!lc::tolerant_eq(lc::distance(cur.c, side), cur.r)){ continue; }
			if(!lc::tolerant_eq(lc::distance(cur.c, line), cur.r)){ continue; }
			const lc::Point dir = (side.b - side.a).unit();
			double move = (side.b - line.projection(cur.c)).abs();
			for(int j = 0; j < n; ++j){
				move = min(move, lc::straight_move(
					lc::Circle(cur.c, cur.r - lc::EPS),
					dir, poly.side(j)) - lc::EPS);
			}
			cur.c += dir * move;
			prev = line.projection(cur.c);
			start_point = (i + 1) % n;
			break;
		}
		for(int i = 0; start_point < 0 && i < n; ++i){
			if(!lc::tolerant_eq((cur.c - poly[i]).abs(), cur.r)){ continue; }
			prev = poly[i];
			start_point = i;
		}
		vector<lc::Point> trace;
		for(int i = 0, end = 3 * n; i < end; ++i){
			const int j = (i + start_point) % n;
			const lc::Segment &side = poly.side(j);
			const lc::Line &line = side.to_line();
			bool move_flag = false;
			if(lc::tolerant_eq(lc::distance(cur.c, line), cur.r) &&
			   lc::tolerant_eq(lc::distance(cur.c, side), cur.r))
			{
				trace.push_back(cur.c);
				trace.push_back(line.projection(cur.c));
				const lc::Point dir = (side.b - side.a).unit();
				double move = (side.b - line.projection(cur.c)).abs();
				for(int k = 0; k < n; ++k){
					move = min(move, lc::straight_move(
						lc::Circle(cur.c, cur.r - lc::EPS),
						dir, poly.side(k)) - lc::EPS);
				}
				cur.c += dir * move;
				prev = line.projection(cur.c);
				trace.push_back(prev);
				move_flag = true;
			}
			if((cur.c - side.b).abs() < cur.r + lc::EPS){
				trace.push_back(cur.c);
				trace.push_back(side.b);
				const double start = (cur.c - side.b).arg();
				double goal = start - M_PI;
				for(int k = 0; k < n; ++k){
					goal = max(goal, rotate_move(
						side.b, start, cur.r, poly.side(k)));
				}
				if(lc::ccw(side.a, side.b, poly[(j + 2) % n]) == -2){
					goal = start;
				}
				cur.c = side.b + cur.r * lc::Point(cos(goal), sin(goal));
				trace.push_back(cur.c);
				prev = side.b;
				move_flag = true;
			}
			if(end >= 3 * n && move_flag){
				const auto t = trace.back();
				trace.assign(1, t);
				end = i + n + 1;
			}
		}
		std::vector<lc::Point> uniq_trace;
		for(const auto &p : trace){
			if(uniq_trace.empty() || !lc::tolerant_eq(uniq_trace.back(), p)){
				uniq_trace.push_back(p);
			}
		}
		while(lc::tolerant_eq(uniq_trace[0], uniq_trace.back())){
			uniq_trace.pop_back();
		}
		const lc::Polygon trace_poly(uniq_trace.begin(), uniq_trace.end());
		double answer = trace_poly.area();
		const int m = trace_poly.size();
		for(int i = 0; i < m; ++i){
			const lc::Point a(trace_poly[i]);
			const lc::Point b(trace_poly[(i + 1) % m]);
			const lc::Point c(trace_poly[(i + 2) % m]);
			if(lc::ccw(a, b, c) == -1){
				double ta = (a - b).arg(), tc = (c - b).arg();
				while(tc < ta){ tc += 2.0 * M_PI; }
				answer += r * r * (tc - ta) * 0.5;
			}
		}
		cout << answer << endl;
	}
	return 0;
}

Measured memory_bytes: 1400