#include<bits/stdc++.h>
#define inf 1<<29
#define linf (1e16)
#define eps (1e-5)
#define Eps (1e-12)
#define mod 1000000007
#define pi acos(-1.0)
#define phi (1.0+sqrt(5.0))/2.0
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define all(a) (a).begin(),(a).end()
#define pd(a) printf("%.10f\n",(double)(a))
#define pld(a) printf("%.10Lf\n",(ld)(a))
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define RFOR(i,a,b) for(int i=(a)-1;(b)<=i;i--)
#define Unique(v) v.erase(unique(all(v)),v.end())
#define equals(a,b) (fabs((a)-(b))<eps)
#define track() printf("HAHAHAHA\n");
using namespace std;
typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<int,double> pid;
typedef pair<double,int> pdi;
typedef pair<double,double> pdd;
typedef vector<int> vi;
typedef vector<pii> vpi;

class Point{
public:
  double x,y;
  Point(double x=0,double y=0):x(x),y(y){}

  Point operator+(Point p){ return Point(x+p.x,y+p.y);}
  Point operator-(Point p){ return Point(x-p.x,y-p.y);}
  Point operator*(double k){ return Point(x*k,y*k);}
  Point operator/(double k){ return Point(x/k,y/k);}
  bool operator<(Point p)const{ 
    return equals(x,p.x) ? y-p.y<-eps : x-p.x<-eps; }
  bool operator==(Point p)const{ 
    return fabs(x-p.x)<eps && fabs(y-p.y)<eps;}

  double abs(){ return sqrt(norm());}
  double norm(){ return (x*x+y*y);}
};
typedef Point Vector;
typedef vector<Point> Polygon;

class Segment{
public:
  Point p1,p2;
  Segment(Point p1=Point(),Point p2=Point()):p1(p1),p2(p2){}
};
typedef Segment Line;

class Circle{
public:
  Point c;
  double r;
  Circle(Point c=Point(),double r=0.0):c(c),r(r){}
};

double norm(Vector a){ return (a.x*a.x+a.y*a.y);}
double abs(Vector a){ return sqrt(norm(a));}
double dot(Vector a,Vector b){ return (a.x*b.x+a.y*b.y);}
double cross(Vector a,Vector b){ return (a.x*b.y-a.y*b.x);}
double arg(Vector p){ return atan2(p.y,p.x);}
Vector polar(double a,double r){ return Point(cos(r)*a,sin(r)*a);}

class Dedge{
  public:
  int s,t,f,l;
  double r;
  Dedge(int s,int t,double r):s(s),t(t),f(0),l(0){
    while(pi<r)r-=2.0*pi;
    while(r<-pi)r+=2.0*pi;
    this->r=r;
  }
  bool operator==(Dedge e)const{ return t==e.t; }
  bool operator<(Dedge e)const{ return r>e.r; }
  bool operator<(double R)const{ return r>R; }
};

class DualGraph{
  public:
  int n;
  vector<Point> v;
  vector<Polygon> P;
  vector<vector<Dedge> > g;

  DualGraph(vector<Point> v):v(v),g(v.size()),n(v.size()){}

  void add_edge(int s,int t){
    double r=arg(v[t]-v[s]);
    g[s].pb(Dedge(s,t,r));
    g[t].pb(Dedge(t,s,r+pi));
  }

  void add_polygon(int s,int t,double r){
    vector<Dedge>::iterator e=lower_bound(all(g[s]),r-eps);
    if(e==g[s].end())e=g[s].begin();
    if(e->f)return;
    e->f=1;
    e->l=t;
    P[t].pb(v[s]);
    add_polygon(e->t, t, e->r > 0 ? e->r-pi : e->r+pi);
  }

  vector<Polygon> dual(){
    FOR(i,0,n){ sort(all(g[i])); Unique(g[i]); }
    FOR(i,0,n){
      FOR(j,0,g[i].size()){
        if(!g[i][j].f){
          P.pb(Polygon());
          add_polygon(i,P.size()-1,g[i][j].r+eps);
        }
      }
    }
    return P;
  }
};

Point project(Segment s,Point p){
  Vector base=(s.p2-s.p1);
  double r=(dot(p-s.p1,base)/base.norm());
  return (s.p1+base*r);
}

bool isParallel(Segment s,Segment t){
  return equals(cross(s.p1-s.p2,t.p1-t.p2),0.0);
}

int ccw(Point p0,Point p1,Point p2){
  Vector a=p1-p0;
  Vector b=p2-p0;
  if(cross(a,b)>eps)return 1;
  if(cross(a,b)<-eps)return -1;
  if(dot(a,b)<-eps)return 2;
  if(a.norm()<b.norm())return -2;
  return 0;
}

bool intersect(Point p1,Point p2,Point p3,Point p4){
  return (ccw(p1,p2,p3)*ccw(p1,p2,p4)<=0 &&
          ccw(p3,p4,p1)*ccw(p3,p4,p2)<=0);
}

bool intersect(Segment s1,Segment s2){
  return intersect(s1.p1,s1.p2,s2.p1,s2.p2);
}

double getDistanceLP(Line l,Point p){
  return abs(cross(l.p2-l.p1,p-l.p1)/abs(l.p2-l.p1));
}

double getDistanceSP(Segment s,Point p){
  if(dot(s.p2-s.p1,p-s.p1)<0.0)return abs(p-s.p1);
  if(dot(s.p1-s.p2,p-s.p2)<0.0)return abs(p-s.p2);
  return getDistanceLP(s,p);
}

Point getCrossPointLL(Line a,Line b){
  double A=cross(a.p2-a.p1,b.p2-b.p1);
  double B=cross(a.p2-a.p1,a.p2-b.p1);
  if(abs(A)<eps || abs(B)<eps)return b.p1;
  return b.p1+(b.p2-b.p1)*(B/A);
}

pair<Point,Point> getCrossPoints(Circle c1,Circle c2){
  double d=abs(c1.c-c2.c);
  double a=acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2.0*c1.r*d));
  double t=arg(c2.c-c1.c);
  return mp(c1.c+polar(c1.r,t+a),c1.c+polar(c1.r,t-a));
}

bool onLine(Line L,Point p){ return getDistanceLP(L,p)<eps; }
bool onSegment(Segment s,Point p){
  if(!onLine(s,p))return false;
  if(dot(s.p2-s.p1,p-s.p1)<-eps)return false;
  if(dot(s.p1-s.p2,p-s.p2)<-eps)return false;
  return true;
}

bool intersect(Circle c,Line L){ return getDistanceLP(L,c.c)<c.r+eps; }

pair<Point,Point> getCrossPoints(Circle c,Line l){
  Vector pr=project(l,c.c);
  Vector e=(l.p2-l.p1)/abs(l.p2-l.p1);
  double base=sqrt(c.r*c.r-norm(pr-c.c));
  return mp(pr+e*base,pr-e*base);
}

vector<Point> getCrossPoint(Circle c,Segment s){
  vector<Point> res;
  if(!intersect(c,s))return res;
  pair<Point,Point> pp=getCrossPoints(c,s);
  if(ccw(s.p1,s.p2,pp.f)==0)res.pb(pp.f);
  if(ccw(s.p1,s.p2,pp.s)==0)res.pb(pp.s);
  return res;
}

double Area(Polygon p){
  double area=0.0;
  int n=p.size();
  for(int i=0;i<n;i++)area+=cross(p[i],p[(i+1)%n]);
  return area/2.0;
}

int contains(Polygon g,Point p){
  int n=g.size();
  bool x=false;
  for(int i=0;i<n;i++){
    Vector a=g[i]-p,b=g[(i+1)%n]-p;
    if(abs(cross(a,b))<eps && dot(a,b)<eps)return 1;
    if(a.y>b.y)swap(a,b);
    if(a.y<eps && eps<b.y && cross(a,b)>eps)x=!x;
  }
  if(x)return 2;
  return 0;
}

double getAngle(Vector a,Vector b){
  double tmp=dot(a,b)/(abs(a)*abs(b));
  if(tmp<-1.0)tmp=-1.0;
  if(1.0<tmp)tmp=1.0;
  double r=acos(tmp)*180.0/pi;
  if(cross(a,b)<eps)r=360.0-r;
  return r;
}

Segment ParallelShift(Segment s,double d){
  Vector v=(s.p2-s.p1)/abs(s.p2-s.p1);
  swap(v.x,v.y);
  v.x=-v.x;
  return Segment(s.p1+v*d,s.p2+v*d);
}

int n;
Point s;
double r;
Polygon p;

bool intersectCS(Circle c,Segment s){ return getDistanceSP(s,c.c)<c.r-eps; }

bool check(Circle c){
  FOR(i,0,n){
    Segment s(p[i],p[(i+1)%n]);
    if(intersectCS(c,s))return false;
  }
  return true;
}

double solve(){
  vector<Point> vp;
  vector<Segment> vs;
  FOR(i,0,n)vp.pb(p[i]);
  FOR(i,0,n){
    FOR(j,i+1,n){
      if(abs(p[i]-p[j])<2.0*r-eps){
        pair<Point,Point> pp = getCrossPoints(Circle(p[i],r),Circle(p[j],r));
        if(check(Circle(pp.f,r))){
          vp.pb(pp.f);
          vs.pb(Segment(pp.f,p[i]));
          vs.pb(Segment(pp.f,p[j]));
        }
        if(check(Circle(pp.s,r))){
          vp.pb(pp.s);
          vs.pb(Segment(pp.s,p[i]));
          vs.pb(Segment(pp.s,p[j]));
        }
      }
    }
  }
  FOR(i,0,n){
    Segment s1(p[i],p[(i+1)%n]);
    vs.pb(s1);
    FOR(j,0,n){
      if(j==i || j==(i+1)&n)continue;
      Vector v=p[j]-project(s1,p[j]);
      v = v/abs(v);
      vector<Point> tmp=getCrossPoint(Circle(p[j],r),Segment(s1.p1+v*r,s1.p2+v*r));
      FOR(k,0,tmp.size()){
        if(check(Circle(tmp[k],r))){
          vp.pb(tmp[k]);
          vp.pb(project(s1,tmp[k]));
          vs.pb(Segment(tmp[k],p[j]));
          vs.pb(Segment(tmp[k],project(s1,tmp[k])));
        }
      }
    }
  }
  FOR(i,0,n){
    Segment s1(p[i],p[(i+1)%n]),ps1=ParallelShift(s1,r);
    FOR(j,i+1,n){
      Segment s2(p[j],p[(j+1)%n]),ps2=ParallelShift(s2,r);
      if(isParallel(ps1,ps2))continue;
      if(!intersect(ps1,ps2))continue;
      Point mid=getCrossPointLL(ps1,ps2);
      if(check(Circle(mid,r))){
        vp.pb(mid);
        vp.pb(project(s1,mid));
        vp.pb(project(s2,mid));
        vs.pb(Segment(mid,project(s1,mid)));
        vs.pb(Segment(mid,project(s2,mid)));
      }
    }
  }
  sort(all(vp));
  Unique(vp);
  DualGraph dg = DualGraph(vp);
  FOR(i,0,vs.size()){
    vector<pair<double,int> > list;
    FOR(j,0,vp.size())
      if(onSegment(vs[i],vp[j]))
        list.pb(mp(abs(vs[i].p1-vp[j]),j));
    sort(all(list));
    FOR(j,0,list.size()-1){
      int a = list[j].s,b = list[j+1].s;
      dg.add_edge(a,b);
    }
  }
  vector<Polygon> d = dg.dual();
  Polygon P;
  FOR(i,1,d.size())
    if(contains(d[i],s)==2)
      P=d[i];
  double res=Area(P);
  int m = P.size();
  FOR(i,0,m){
    Point A=P[(i-1+m)%m],B=P[i],C=P[(i+1)%m];
    double ang=getAngle(C-B,B-A);
    if(contains(p,B)!=2)continue;
    res+=r*r*pi*(180.0-ang)/360.0;
  }
  return res;
}

int main(){
  while(cin>>n>>s.x>>s.y>>r && n){
    p.resize(n);
    FOR(i,0,n)
      cin>>p[i].x>>p[i].y;
    pd(solve());
  }
  return 0;
}



Measured memory_bytes: 3748