#include<bits/stdc++.h>

#define EQ(a,b) (abs((a)-(b)) < EPS)
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define all(a) (a).begin(),(a).end()
#define fs first
#define sc second
#define pb push_back
#define sz size()

using namespace std;
typedef long double D;
typedef complex<D> P;
typedef pair<P,P> L;
typedef vector<P> Poly;
typedef pair<P,D> C;

const D EPS = 1e-9;
const D PI = acos(-1);

inline P unit(P p){return p/abs(p);}
inline pair<P,P> norm(P p){return make_pair(p*P(0,1),p*P(0,-1));}

inline D dot(P x, P y){return real(conj(x)*y);}
inline D cross(P x, P y){return imag(conj(x)*y);}

//rotate a point counter-clockwise on the origin
inline P rotate(P v, D s){
  return P(real(v)*cos(s) - imag(v)*sin(s), real(v)*sin(s) + imag(v)*cos(s) );
}

inline D arg(P a,P b,P c){
  if(EQ(b,c))return 0;
  return acos(dot(b-a,c-a)/(abs(b-a)*abs(c-a)));
}
inline D arg(D a,D b,D c){
  if(EQ(b,0) || EQ(c,0))return 0;
  return acos( (b*b+c*c-a*a)/(2*b*c) );
}

inline int ccw(P a,P b,P c){
  b -= a;c -= a;
  if (cross(b,c)>EPS) return 1;       //counter clockwise
  if (cross(b,c)<-EPS) return -1;     //clockwise
  if (dot(b, c)<-EPS) return 2;       //c--a--b on line
  if (abs(b)+EPS<abs(c)) return -2;   //a--b--c on line
  return 0;                           //on segment
}

inline P line_cp(L a,L b){
  return a.fs+(a.sc-a.fs)*cross(b.sc-b.fs,b.fs-a.fs)/cross(b.sc-b.fs,a.sc-a.fs);
}

inline bool in_cir(C c,P x){return (abs(x-c.fs) +EPS < c.sc);}
inline bool on_cir(C c,P x){return EQ(abs(x-c.fs),c.sc);}

inline vector<P> cp_cir_to_line(C a, L l){
  vector<P> v;
  P n = norm(l.fs-l.sc).fs;
  P p = line_cp(l,L(a.fs,a.fs+n));

  if(on_cir(a,p))v.pb(p);
  else if(in_cir(a,p)){
    D d = abs(a.fs-p);
    D len = sqrt(a.sc*a.sc - d*d);
    P cp_vec = len * unit(l.fs-l.sc);
    v.pb(p + cp_vec);
    v.pb(p - cp_vec);
  }
  return v;
}

inline vector<P> cp_cir_to_seg(C a, L l){
  vector<P> v,tmp = cp_cir_to_line(a,l);
  rep(i,tmp.sz)if(!ccw(l.fs,l.sc,tmp[i]))v.pb(tmp[i]);
  return v;
}

//straight move
inline P straight_move(const C &c, const Poly &p , const int &dir, const P &origin){
  int n = p.sz;

  D x = (dir&1)?1e9:0, y = (dir&1)?0:1e9;
  rep(i,n){
    if((dir&1)==0){
      if(abs(c.fs.real()-p[i].real())+EPS < c.sc){
	if( (dir == 0 && c.fs.imag()+EPS < p[i].imag() )
	    || (dir == 2 && p[i].imag()+EPS < c.fs.imag()) ){ 
	  D difx = c.fs.real() - p[i].real();
	  D dy = sqrt(c.sc*c.sc - difx*difx);
	  D dify = abs(p[i].imag() - c.fs.imag()) - dy; 
	  if(y > dify+EPS)y = dify;
	}
      }
      
      L l = L(p[i],p[(i+1)%n]);
      if(ccw(l.fs,l.sc,origin) == 0){
	if(EQ(l.fs.imag(),l.sc.imag()))continue;
	D dify = abs(l.sc.imag()-c.fs.imag());
	if(y > dify+EPS)y = dify;
      }else{
	D x1 = min(l.fs.real(),l.sc.real()), x2 = max(l.fs.real(),l.sc.real());
	if(x1<c.fs.real()+EPS && c.fs.real()<x2+EPS && EQ(l.fs.imag(),l.sc.imag())){
	  if( (dir == 0 && c.fs.imag()+EPS < l.fs.imag())
	      || (dir == 2 && l.fs.imag()+EPS < c.fs.imag()) ){
	    D dify = abs(l.fs.imag() - c.fs.imag()) - c.sc;
	    if(y > dify+EPS)y = dify;
	  }
	}
      }
    }else{
      if(abs(c.fs.imag()-p[i].imag())+EPS < c.sc){
	if( (dir == 1 && c.fs.real()+EPS < p[i].real() )
	    || (dir == 3 && p[i].real()+EPS < c.fs.real()) ){ 
	  D dify = c.fs.imag() - p[i].imag();
	  D dx = sqrt(c.sc*c.sc - dify*dify);
	  D difx = abs(p[i].real() - c.fs.real()) - dx; 
	  if(x > difx+EPS)x = difx;
	}
      }
      
      L l = L(p[i],p[(i+1)%n]);
      if(ccw(l.fs,l.sc,origin) == 0){
	if(EQ(l.fs.real(),l.sc.real()))continue;
	D difx = abs(l.sc.real()-c.fs.real());
	if(x > difx+EPS)x = difx;
      }else{
	D y1 = min(l.fs.imag(),l.sc.imag()), y2 = max(l.fs.imag(),l.sc.imag());
	if(y1<c.fs.imag()+EPS && c.fs.imag()<y2+EPS && EQ(l.fs.real(),l.sc.real())){
	  if( (dir == 1 && c.fs.real()+EPS < l.fs.real())
	      || (dir == 3 && l.fs.real()+EPS < c.fs.real()) ){
	    D difx = abs(l.fs.real() - c.fs.real()) - c.sc;
	    if(x > difx+EPS)x = difx;
	  }
	}
      }
    }
  }
  return P(c.fs.real() + (dir==3?-x:x), c.fs.imag() + (dir==2?-y:y));
}

//rotate at one point
inline P rotate_circle(const C &c, const Poly &p, const P &origin){
  D seta = -PI/2;
  int n = p.sz;
  rep(i,n){
    if(EQ(p[i],origin)){
      P nv = norm(p[(i+1)%n]-p[i]).fs, cenv = c.fs-origin;
      seta = max(seta,asin(cross(cenv,nv)/(abs(cenv)*abs(nv))));
    }
  }

  rep(i,n){
    if(EQ(origin,p[(i+n-1)%n]) || EQ(origin,p[i]) || EQ(origin,p[(i+1)%n]))continue;
    D dis = abs(origin-p[i]);

    if(dis+EPS < 2*c.sc){  
      D z = sqrt(4*c.sc*c.sc - dis*dis);
      if(cross(c.fs-origin, p[i]-origin)>-EPS)continue;
      seta = max(seta, arg(z,2*c.sc,dis) - arg(origin,c.fs,p[i]));
    }
  }

  rep(i,n){
    D x = 0, y = 0;
    L l = L(p[i],p[(i+1)%n]);
    if(EQ(l.fs.real(), l.sc.real())){
      if(EQ(l.fs.real(),c.fs.real()))continue;
      x = (l.fs.real() +EPS < c.fs.real())?c.sc:-c.sc;
    }
    if(EQ(l.fs.imag(), l.sc.imag())){
      if(EQ(l.fs.imag(),c.fs.imag()))continue;
      y = (l.fs.imag() +EPS < c.fs.imag())?c.sc:-c.sc;
    }
    l.fs = P(l.fs.real() + x, l.fs.imag() + y);
    l.sc = P(l.sc.real() + x, l.sc.imag() + y);
   
    C o = C(origin,c.sc);
    vector<P> vp = cp_cir_to_line(o,l);
    rep(j,vp.sz){
      if(cross(c.fs-origin, vp[j]-origin)>-EPS)continue;
      if(dot(c.fs-origin,vp[j]-origin)<EPS)continue;
      P nxt = P(vp[j].real() - x, vp[j].imag() - y);
      if(ccw(p[i],p[(i+1)%n],nxt))continue;
      seta = max(seta, -arg(origin,c.fs,vp[j]));
    }
  }
  
  P rot = rotate(c.fs-origin, seta);
  return rot+origin;
}

//cross check
inline vector<P> cross_check(const C &c, const Poly &p){
  vector<P> res;
  int n = p.sz;
  rep(i,n){
    L l = L(p[i],p[(i+1)%n]);
    vector<P> tmp = cp_cir_to_seg(c,l);
    for(P x : tmp){
      if(!EQ(x,p[i]))res.pb(x);
    }
  }  
  return res;
}

//sort points by their angle from center of circle
inline vector<P> sortarg(const C &c, const P &origin, const vector<P> &list){
  vector< pair<D,int> > tmp(list.sz);
  rep(i,list.sz){
    tmp[i] = make_pair(arg(c.fs, origin, list[i]), i);
  }
  sort(all(tmp));

  vector<P> res(list.sz);
  rep(i,list.sz)res[i] = list[tmp[i].second];
  return res;
}

//polygon area
inline D area(const Poly &p){
  if(p.sz<3)return 0;
  D res = cross(p[p.sz-1],p[0]);
  rep(i,p.sz-1)res += cross(p[i],p[i+1]);
  return res/2;
}

inline D curve(const C &c, P p1, P p2){
  p1 -= c.fs; p2 -= c.fs;
  D tri = cross(p1, p2)/2;
  D seta = acos(dot(p1,p2)/(abs(p1)*abs(p2)));
  return c.sc*c.sc*seta/2 - tri;
}

//simulate roomba moves
inline D simulate( C c, const Poly &p ){
  int n = p.sz;
  Poly trajectry;
  c.fs = straight_move(c,p,0,c.fs);
  P adj = P(c.fs.real(), c.fs.imag() + c.sc);

  P start_cen = P(1e9,1e9);

  int cnt = 0;
  D res = 0;
  for(;;){
    vector<P> list = cross_check(c,p);
    assert(list.sz>0);
    list = sortarg(c,adj,list);
 
    P nxt = list[0];    
    if(list.sz>1)nxt = list.back();
    
    if(cnt>0){
      if(EQ(start_cen,c.fs))break;
      rep(i,list.sz)trajectry.pb(list[i]);
      if(list.sz>1){
	rep(i,list.sz-1)res += curve(c,list[i],list[i+1]);
      }
    }
    if(cnt==1)start_cen = c.fs;
    cnt++;

    int d = -1;
    rep(i,n){
      P a = p[i], b = p[(i+1)%n];
      if(ccw(a,b,nxt) == 0){
	if(EQ(cross(norm(b-a).fs,c.fs-nxt),0) && !EQ(b,nxt)){
	  if(a.imag() < b.imag() - EPS)d = 0;
	  if(a.real() < b.real() - EPS)d = 1;
	  if(a.imag() > b.imag() + EPS)d = 2;
	  if(a.real() > b.real() + EPS)d = 3;
	  break;
	}
      }
    }

    if(d<0){
      c.fs = rotate_circle(c,p,nxt);
      adj = nxt;
    }else{      
      P rel_adj = nxt-c.fs;
      c.fs = straight_move(c,p,d,nxt);
      adj = rel_adj + c.fs;
    }
  }

  res += area(trajectry);
  return res;
}

int main(){
  int n,x,y,r;
  while(cin >> n >> x >> y >> r){
    C c = C(P(x,y),r);
    if(n==0)break;
    Poly p(n);
    rep(i,n){
      cin >> x >> y;
      p[i] = P(x,y);
    }

    cout << fixed << setprecision(10) << simulate(c,p) << endl;
  }
}

Measured memory_bytes: 1312