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

const int nrep = 50; //num of reptition of binary search

/********************* Geometry Library *****************/
const double EPS = 1e-9;
const double INF = 1e12;
#define LE(n,m) ((n) < (m) + EPS)
#define GE(n,m) ((n) + EPS > (m))
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<double> P;
typedef vector<P> VP;
struct L : VP{
    L(const P& a, const P& b){ resize(2); at(0)=a; at(1)=b; }
    L(){ resize(2); }
};
struct C{
    P p;
    double r;
    C(const P& p, const double& r) : p(p), r(r) {}
};
namespace std{
    bool operator < (const P& a, const P& b){
        return (a.X != b.X) ? a.X<b.X : a.Y<b.Y;
    }
}

double dot(P a, P b){
    return (conj(a)*b).X;
}
double cross(P a, P b){
    return (conj(a)*b).Y;
}

int ccw(P a, P b, P c){
    b -= a;
    c -= a;
    if(cross(b,c) > EPS) return +1;
    if(cross(b,c) <-EPS) return -1;
    if(dot(b,c) < EPS) return +2;
    if(norm(b) < norm(c)) return -2;
    return 0;
}

P projection(const L& l, const P& p) {
    double t = dot(p-l[0], l[0]-l[1]) / norm(l[0]-l[1]);
    return l[0] + t*(l[0]-l[1]);
}
bool intersectSP(const L &s, const P &p) {
    return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < EPS;
}
double distanceLP(const L &l, const P &p) {
    return abs(p - projection(l, p));
}
double distanceSP(const L &s, const P &p) {
    const P r = projection(s, p);
    if (intersectSP(s, r)) return abs(r - p);
    return min(abs(s[0] - p), abs(s[1] - p));
}

VP crosspointLC(const L &l, const C &c){
    VP ret;
    P mid = projection(l, c.p);
    double dlp = distanceLP(l, c.p);
    if(EQ(dlp, c.r)){
        ret.push_back(mid);
        return ret;
    }
    if(dlp > c.r){
        return ret;
    }
    P d = sqrt(c.r*c.r -dlp*dlp)/abs(l[1]-l[0]) *(l[1]-l[0]);
    ret.push_back(mid+d);
    ret.push_back(mid-d);
    return ret;
}
VP crosspointSC(const L &s, const C &c){
    VP ret;
    VP cp = crosspointLC(s,c);
    for(int i=0; i<(int)cp.size(); i++){
        if(dot(s[1]-s[0], cp[i]-s[0]) < EPS) continue;
        if(norm(s[1]-s[0]) < norm(cp[i]-s[0]) +EPS) continue;
        ret.push_back(cp[i]);
    }
    return ret;
}

double getangle(P p, P a, P b){
    a -= p;
    b -= p;
    return acos(dot(a,b)/(abs(a)*abs(b)));
}
double getarea(const VP &p) {
    double ret = 0;
    for (int i=0; i<(int)p.size(); i++){ 
        ret += cross(p[i], p[(i+1)%p.size()]);
    }
    return ret*0.5;
}
/********************* end Library ***********************/

int main(){
    while(1){
        /******************* Input ************************/
        int n,x,y,r;
        cin >> n >> x >> y >> r;
        if(n==0) break;
    
        C robot(P(x,y), r);
        VP v(n);
        for(int i=0; i<n; i++){
            int vx,vy;
            cin >> vx >> vy;
            v[i] = P(vx, vy);
        }
        //rotate the order of vertices to start from horizontal edge
        if(v[0].X == v[1].X){ 
            v.push_back(v[0]);
            v.erase(v.begin());
        }
        /****************** end Input **********************/

        /*********** Move to the initial state ***********/
        //go right until touch the wall
        while(1){
            robot.p += P(1.0, 0);
            bool reach = false;
            for(int i=0; i<n; i++){
                if(distanceSP(L(v[i],v[(i+1)%n]), robot.p) < r){
                    reach = true;
                    break;
                }
            }
            if(reach) break;
        }
        //binary search
        P s = robot.p -P(1.0, 0);
        P e = robot.p;
        for(int i=0; i<nrep; i++){
            robot.p = (s+e)*0.5;
            bool reach = false;
            for(int i=0; i<n; i++){
                if(distanceSP(L(v[i],v[(i+1)%n]), robot.p) < r){
                    reach = true;
                }
            }
            if(reach) e = robot.p;
            else s = robot.p;
        }

        bool onedge;
        int sidx;
        for(int i=0; i<n; i++){
            if(abs(robot.p -v[i]) < r+EPS){
                sidx = i;
                onedge = false;
                break;
            }
            if(distanceSP(L(v[i], v[(i+1)%n]), robot.p) < r+EPS){
                if(abs(robot.p -v[i]) > r+EPS && abs(robot.p -v[(i+1)%n]) > r+EPS){
                    sidx = i;
                    onedge = true;
                    break;
                }
            }
        }
        /********************* end initial state **********************/

        /************************* Main Loop **************************/
        //move along the wall
        VP vlist;
        double area = 0.0;
        int step=0;
        cerr << fixed;
        cerr << setprecision(10);
        while(1){
            if(step++ ==50) break;
            /*
            cerr << robot.p << endl;
            if(onedge) cerr << "edge ";
            else cerr << "vertex ";
            cerr << sidx << endl;
            //cerr << "area " << area << endl;
            */
            
            /****************** Case 1. contact with the edge *************/
            if(onedge){
                //search the limit
                P dir = (v[(sidx+1)%n]-v[sidx])/abs(v[(sidx+1)%n]-v[sidx]);
                P limit = (sidx%2==0)? P(v[(sidx+1)%n].X, robot.p.Y) :P(robot.p.X, v[(sidx+1)%n].Y);
                P s,e;
                s = e = robot.p;
                while(1){
                    e += dir;
                    if(dot(limit-e, dir) < 0){
                        e = limit;
                        break;
                    }
                    bool reach = false;
                    for(int i=0; i<n; i++){
                        if(i==sidx || i==(sidx-1+n)%n) continue;
                        if(distanceSP(L(v[i],v[(i+1)%n]), e) < r){
                            reach = true;
                            break;
                        }
                    }
                    if(reach) break;
                }
        
                //binary search
                //cerr << s << " " << e << endl;
                for(int i=0; i<nrep; i++){
                    robot.p = (s+e)*0.5;
                    //cerr << robot.p << endl;
                    bool reach = false;
                    for(int i=0; i<n; i++){
                        if(i==sidx || i==(sidx-1+n)%n) continue;
                        //if turn left (avoid errors)
                        if(i==(sidx+1)%n && cross(v[(sidx+1)%n]-v[sidx],v[(sidx+2)%n]-v[sidx])<0){
                            continue;
                        }
                        if(distanceSP(L(v[i], v[(i+1)%n]), robot.p) < r){
                            reach = true;
                            break;
                        }
                    }
                    if(reach) e = robot.p;
                    else s = robot.p;
                }

                //calculate ridx and last;
                P last;
                double eval = -INF;
                int ridx;
                bool n_onedge;
                bool terminate = false;
                P cpedge = (sidx%2==0)? P(robot.p.X, v[sidx].Y) :P(v[sidx].X, robot.p.Y);
                for(int i=0; i<n; i++){
                    if(i==sidx || i==(sidx-1+n)%n) continue;                
                    if(abs(robot.p -v[i]) < r+EPS){
                        if(!vlist.empty() && EQ(vlist[0], v[i])){
                            last = v[i];
                            terminate = true;
                            break;
                        }
                        if(dot(robot.p-cpedge, v[i]-cpedge) > eval) {
                            last = v[i];
                            eval = dot(robot.p-cpedge, v[i]-cpedge);
                            ridx = i;
                            n_onedge = false;
                        }
                    }
                    if(distanceSP(L(v[i], v[(i+1)%n]), robot.p) < r +EPS){
                        if(abs(robot.p -v[i])>r+EPS && abs(robot.p -v[(i+1)%n])>r+EPS){
                            //except vertices
                            VP cp = crosspointSC(L(v[i], v[(i+1)%n]), robot);
                            if(!vlist.empty() && EQ(vlist[0], cp[0])){
                                last = cp[0];
                                terminate = true;
                                break;
                            }
                            if(dot(robot.p-cpedge, cp[0]-cpedge) > eval) {
                                last = cp[0];
                                eval = dot(robot.p-cpedge, cp[0]-cpedge);
                                ridx = i;
                                n_onedge = true;
                            }
                        }
                    }
                }
                                                 
                //calculate area ...
                if(!vlist.empty() && EQ(vlist[0], cpedge)){
                    terminate = true;
                    last = cpedge;
                }
                double a = getangle(robot.p, last, cpedge);
                area += r*r*M_PI*a/(2*M_PI) -r*r*sin(a)*0.5;
                vlist.push_back(cpedge);
                vlist.push_back(last);
                if(terminate){
                    break;
                }else{
                    onedge = n_onedge;
                    sidx = ridx;
                }
            }
            /************************* end Case 1. *********************/
            /************ Case 2. contact with the vertex *********************/
            else{
                //rotate
                double d;
                double dxy;
                P s, e;
                s = e = robot.p;
                //search limit
                if(sidx%2==1){
                    d = (v[sidx].X-v[(sidx-1+n)%n].X > 0)? 1: -1;
                    dxy = fabs(e.X -v[sidx].X);
                    if(abs(2*e.X -round(2*e.X)) > EPS){
                        dxy = floor(2*dxy) *0.5;
                    }
                }else{
                    d = (v[sidx].Y-v[(sidx-1+n)%n].Y > 0)? 1: -1;
                    dxy = fabs(e.Y -v[sidx].Y);
                    if(abs(2*e.Y -round(2*e.Y)) > EPS){
                        dxy = floor(2*dxy) *0.5;
                    }
                }

                P start = (v[sidx] -v[(sidx+1)%n]) *(r / abs(v[sidx] -v[(sidx+1)%n]));
                while(1){
                    dxy += 0.5;
                    if(dxy +EPS > r){
                        e = v[sidx] + start*P(0,-1);
                        break;
                    }
                    if(sidx%2==1){
                        e = v[sidx] +d*P(dxy, sqrt(fabs(r*r-dxy*dxy)));
                    }else{
                        e = v[sidx] +d*P(-sqrt(fabs(r*r-dxy*dxy)), dxy);
                    }
                    bool reach = false;
                    for(int i=0; i<n; i++){
                        if(i==sidx || i==(sidx-1+n)%n) continue;
                        if(distanceSP(L(v[i], v[(i+1)%n]), e) < r){
                            reach = true;
                            break;
                        }
                    }
                    if(reach) break;
                }

                //binary search
                //cerr << s << " " << e << endl;
                for(int i=0; i<nrep; i++){
                    double angle_s = getangle(v[sidx],start+v[sidx],s);
                    double angle_e = getangle(v[sidx],start+v[sidx],e);
                    double midangle = (angle_s +angle_e)*0.5;
                    robot.p = v[sidx] + start*P(cos(midangle), -sin(midangle));
                    //cerr << robot.p << endl;
                    bool reach = false;
                    for(int i=0; i<n; i++){
                        if(i==sidx || i==(sidx-1+n)%n) continue;
                        if(distanceSP(L(v[i], v[(i+1)%n]), robot.p) < r){
                            reach = true;
                            break;
                        }
                    }
                    if(reach) e = robot.p;
                    else s = robot.p;
                }

                //calculate ridx, last
                P last;
                double eval = -INF;
                int ridx;
                bool n_onedge;
                bool terminate = false;
                for(int i=0; i<n; i++){
                    if(abs(robot.p -v[i]) < r+EPS){
                        if(cross(robot.p-v[sidx], v[i]-v[sidx]) < EPS){
                            if(i!=sidx && !vlist.empty() && EQ(vlist[0], v[i])){
                                last = v[i];
                                terminate = true;
                                break;
                            }
                            if(dot(robot.p-v[sidx], v[i]-v[sidx]) > eval) {
                                last = v[i];
                                eval = dot(robot.p-v[sidx], v[i]-v[sidx]);
                                ridx = i;
                                n_onedge = false;
                            }
                        }
                    }
                    if(distanceSP(L(v[i], v[(i+1)%n]), robot.p) < r +EPS){
                        if(abs(robot.p -v[i])>r+EPS && abs(robot.p -v[(i+1)%n])>r+EPS){
                            //except vertices
                            VP cp = crosspointSC(L(v[i], v[(i+1)%n]), robot);
                            if(cross(robot.p-v[sidx], v[i]-v[sidx]) < EPS){
                                if(!vlist.empty() && EQ(vlist[0], cp[0])){
                                    last = cp[0];
                                    terminate = true;
                                    break;
                                }
                                if(dot(robot.p-v[sidx], cp[0]-v[sidx]) > eval){
                                    last = cp[0];
                                    eval = dot(robot.p-v[sidx], cp[0]-v[sidx]);
                                    ridx = i;
                                    n_onedge = true;
                                }
                            }
                        }
                    }
                }
                if(last == v[sidx]){
                    onedge = true;
                    continue;
                }
                
                //calculate area ...
                if(!vlist.empty()){
                    double a = getangle(robot.p, last, v[sidx]);
                    area += r*r*M_PI*a/(2*M_PI) -r*r*sin(a)*0.5;
                }
                vlist.push_back(last);
                if(terminate){
                    break;
                }else{
                    onedge = n_onedge;
                    sidx = ridx;
                }
            }
            /************************ end Case 2. *********************/
        }

        /*
        for(int i=0; i<(int)vlist.size(); i++){
            cerr << vlist[i] << endl;
        }
        cerr << getarea(vlist) << endl;
        */
        area += getarea(vlist);
        cout << fixed;
        cout << setprecision(10);
        cout << area << endl;
    }
    /*********************** end Main Loop ************************/
    return 0;
}

Measured memory_bytes: 3548