#include <cmath>
#include <algorithm>
#include <vector>
#include <iostream>
#include <complex>
using namespace std;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define ALL(container) (container).begin(), (container).end()
#define mp(a,b) make_pair(a, b)

namespace geom{
#define X real()
#define Y imag()
#define at(i) ((*this)[i])
#define SELF (*this)
	enum {TRUE = 1, FALSE = 0, BORDER = -1};
	typedef int BOOL;
	typedef long double R;
	const R INF = 1e10;
	R EPS = 1e-10;
	const R PI = 3.1415926535897932384626;
	inline int sig(const R &x) { return (abs(x) < EPS ? 0 : x > 0 ? 1 : -1); }
	typedef complex<R> P;
	inline R norm(const P &p){return p.X*p.X+p.Y*p.Y;}
	inline R inp(const P& a, const P& b){return (conj(a)*b).X;}
	inline R outp(const P& a, const P& b){return (conj(a)*b).Y;}
	inline P unit(const P& p){return p/abs(p);}
	inline P proj(const P &s, const P &t){return t*inp(s, t)/norm(t);}
	struct L : public vector<P>{	// line
		L(const P &p1, const P &p2){this->push_back(p1);this->push_back(p2);}
		L(){}
		P dir()const {return at(1) - at(0);}
	};
	struct S : public L{	// segment
		S(const P &p1, const P &p2):L(p1, p2){}
		S(){}
		BOOL online(const P &p)const {
			if(!sig(norm(p - at(0))) || !sig(norm(p - at(1)))) return BORDER;
			return !sig(abs(at(0)-p) + abs(at(1) - p) - abs(at(0) - at(1)));
		}
	};
	struct C : public P{
		C(){}
		C(const P& p, const R r):P(p), r(r){}
		R r;
	};
	struct G : public vector<P>{
		G(size_type size=0):vector(size){}
		S edge(int i)const {return S(at(i), at(i+1 == size() ? 0 : i+1));}
		R area()const {
			R sum = 0;
			REP(i, size()) sum += outp(at(i), at((i+1)%size()));
			return abs(sum / 2.);
		}
	};
	inline P proj(const P &s, const L &t){return t[0] + proj(s-t[0], t[1]-t[0]);}
#undef SELF
#undef at
}

using namespace geom;

namespace std{
	bool operator<(const P &a, const P &b){return sig(a.X-b.X) ? a.X < b.X : a.Y+EPS < b.Y;}
	bool operator==(const P &a, const P &b){return abs(a-b) < EPS;}
	istream& operator>>(istream &is, P &p){R x,y;is>>x>>y;p=P(x, y);return is;}
	istream& operator>>(istream &is, C &c){return is >> (P &)c >> c.r;}
}

int n;

C icpc;
G g;

pair<P, R> getType(const P &p){
	REP(i, n){
		const S s = g.edge(i);
		if(s.online(p) == TRUE) return mp(s.dir(), abs(s[1] - p));
	}
	REP(i, n){
		const P q = g[i];
		if(!sig(abs(q - p))){
			P tar = q + unit(g.edge(i).dir())*P(0, 1)*icpc.r;
			if(!sig(abs(icpc - tar))) return mp(g.edge(i).dir(), abs(g.edge(i).dir()));
			return mp(tar, arg((tar - p)/(icpc - p)));
		}
	}
}

P getNavigator(){
	vector<pair<R, P>> isc;
	REP(i, n){
		const S s = g.edge(i);
		P q = proj(icpc, s);
		if(s.online(q) == TRUE && !sig(abs(q - icpc) - icpc.r))
			isc.emplace_back(arg(q - icpc), q);
	}
	REP(i, n){
		const P q = g[i];
		if(!sig(abs(q - icpc) - icpc.r)) isc.emplace_back(arg(q - icpc), q);
	}
	sort(ALL(isc));
	pair<R, P> pp(.0, P(0, 0));
	REP(i, isc.size()){
		const auto cur = isc[i];
		const auto nxt = isc[(i+1)%isc.size()];
		R nxtarg = i+1 == isc.size() ? nxt.first + 2*PI : nxt.first;
		pp = max(pp, mp(nxtarg - cur.first, cur.second));
	}
	
	return pp.second;
}

R straight(P dir, R d = INF){
	REP(i, n){
		const S s = g.edge(i);
		if(sig(arg(dir*P(0, 1)/s.dir())) || inp(proj(icpc, s) - icpc, dir) < EPS || s.online(proj(icpc, s)) != TRUE) continue;
		d = min(d, abs(proj(icpc, s) - icpc) - icpc.r);
	}
	REP(i, n){
		const P q = g[i];
		R r = abs(q - proj(q, L(icpc, icpc+dir)));
		if(r + EPS > icpc.r || inp(q - icpc, dir) < EPS) continue;
		d = min(d, abs(proj(q, L(icpc, icpc+dir)) - icpc) - sqrt(icpc.r*icpc.r-r*r));
	}
	return d;
}

R rot(P nav, R r){
	REP(i, n){
		const S s = g.edge(i);
		if(abs(proj(nav, s) - nav) < EPS) continue;
		R t = arg((proj(nav, s) - nav)/(icpc - nav));
		if(t > 0 && t < PI) continue;
		R d = abs(proj(nav, s) - nav);
		if(d > 2*icpc.r - EPS) continue;
		R x = arg(s.dir()) - asin((d-icpc.r) / icpc.r) - arg(icpc-nav);
		if(d-icpc.r < 0) x = arg(s.dir()) - arg(icpc-nav)  + asin((icpc.r-d) / icpc.r);
		if(x < -PI) x += 2*PI;
		if(x > PI)  x -= 2*PI;
		if(x < -EPS) r = max(r, x);
	}
	REP(i, n){
		const P q = g[i];
		R d = abs(q-nav);
		if(d > 2*icpc.r - EPS || d < EPS) continue;
		P med = (nav + q) * (R).5;
		R d2 = sqrt(max((R).0, icpc.r*icpc.r - d*d*(R).25));
		P p1 = med + unit(med - nav)*P(0, 1)*d2;
		P p2 = med + unit(med - nav)*P(0, -1)*d2;

		if(arg((p1 - nav)/(icpc-nav)) < -EPS) r = max(r, arg((p1 - nav)/(icpc-nav)));
		if(arg((p2 - nav)/(icpc-nav)) < -EPS) r = max(r, arg((p2 - nav)/(icpc-nav)));
	}
	return r;
}
int main(){
	ios::sync_with_stdio(false);
	while(cin >> n >> icpc, n){
		g.resize(n);
		REP(i, n) cin >> g[i];
		R d = straight(P(1, 0));
		icpc += P(1, 0)*d;
		R ans = 0;
		G root;
		P prev = getNavigator();
		P start = icpc;
		while(1){
			P nav = getNavigator();
			if(sig(abs(prev-nav))){
				root.push_back(prev);
				root.push_back(icpc);
				ans += icpc.r * icpc.r * arg((nav-icpc)/(prev-icpc)) * .5;
			}
			if(!sig(abs(icpc-start)) && sig(root.area())) break;
			root.push_back(nav);
			prev = nav;
			auto t = getType(nav);
			if(t.second > 0){
				P picpc = icpc;
				prev += unit(t.first) * straight(t.first, t.second);
				icpc += unit(t.first) * straight(t.first, t.second);
				if(S(picpc, icpc).online(start) == TRUE && sig(root.area())) break;
			}else{
				(P &)icpc = nav + (icpc - nav)*polar((R)1., rot(nav, t.second));
				if(sig(abs(icpc-start)) && !sig(abs(start - nav) - icpc.r) && sig(root.area())) break;
			}
		}
		printf("%.10f\n", (double)(ans + root.area()));
	}
	return 0;
}

Measured memory_bytes: 1316