import java.util.*; public class RSRDownsize { static int cx,cy; // center of inversion circle static int r; // radius of inversion circle static double x[],y[]; // (x,y) coordinates of vertices of polygon static double xi[],yi[]; // (x,y) coordinates of inverted polygon vertices static int n; // sides of the polygon static Scanner in; static double EPS = 1e-8; public static void main(String[] args) { in = new Scanner(System.in); cx = in.nextInt(); cy = in.nextInt(); r = in.nextInt(); n = in.nextInt(); x = new double[n]; y = new double[n]; // adjust every coordinate to put inversion center at (0,0) for (int i = 0; i < n; i++) { x[i] = in.nextDouble()-cx; y[i] = in.nextDouble()-cy; } cx = cy = 0; // recenter to zero xi = new double[n]; yi = new double[n]; for (int i = 0; i < n; i++) { double dr = dist(x[i],y[i],cx,cy); // distance of vertex from center double di = r*r/dr; // distance of inversion point from center xi[i] = di/dr*x[i]; yi[i] = di/dr*y[i]; } // Find area of the inverted polygon: double area = polya(xi,yi); // Find circular arcs for each side and add/subtract them from area: for (int i = 0; i < n; i++) { // See if rectangle edge maps to a straight line: if (Math.abs(right(x[i],y[i],x[(i+1)%n],y[(i+1)%n],0,0))< EPS) { continue; } // First, find the circle containing the arc: double[] circ = findCircle(xi[i],yi[i],xi[(i+1)%n],yi[(i+1)%n],cx,cy); // Next, figure out the portion of the arc corresponding to the line: double a1 = myacos(xi[i],yi[i],circ); double a2 = myacos(xi[(i+1)%n],yi[(i+1)%n],circ); double z = myacos(cx,cy,circ); double start, end; // for finding midpoint later on // There must be a simpler way to do this! boolean swap = false; if (a1 > a2) { // Adjust a2 to keep proper orientation for "arc" method // (leftover code from Processing, which requires a1 < a2; not // sure if it serves any other purpose, so leaving it in to be safe): a2 += 2*Math.PI; if (z < a1 && z+2*Math.PI > a2) { start=a1; end=a2; } else { start=a2; end=a1+2*Math.PI; swap=true; } } else if (z > a2 || z < a1) { start=a1; end=a2; } else { start=a2; end=a1+2*Math.PI; swap=true; } double seg = .5*circ[2]*circ[2]*(end-start-Math.sin(end-start)); // Now, do we add or subtract? Find a point on the arc, e.g., midpoint: int st = i; if (swap) {st = (i+1)%n;} double xp = xi[st]-circ[0], yp = yi[st]-circ[1], half = (end-start)/2.; double xm = xp*Math.cos(half)-yp*Math.sin(half) +circ[0]; double ym = xp*Math.sin(half)+yp*Math.cos(half) + circ[1]; if (right(xm,ym,xi[i],yi[i],xi[(i+1)%n],yi[(i+1)%n]) < 0) { area -= seg; } else { area += seg; } } System.out.println(Math.abs(area)); } // correct angle in range 0 to 2pi: static double myacos(double x, double y, double cinfo[]) { double xc = cinfo[0], yc = cinfo[1], rr = cinfo[2]; // First quadrant: double z = (x-xc)/rr; if (z > 1) z = 1.0; // this is annoying, but I need it if (z < -1) z = -1.0; if (y >= yc) return Math.acos(z); else return 2*Math.PI-Math.acos(z); } // Distance between two points (x1,y1) and (x2,y2): static double dist(double x1, double y1, double x2, double y2) { return Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)); } // The following code was taken from // https://www.geeksforgeeks.org/equation-of-circle-when-three-points-on-the-circle-are-given/ static double[] findCircle(double x1, double y1, double x2, double y2, double x3, double y3) { double x12 = x1 - x2; double x13 = x1 - x3; double y12 = y1 - y2; double y13 = y1 - y3; double y31 = y3 - y1; double y21 = y2 - y1; double x31 = x3 - x1; double x21 = x2 - x1; // x1^2 - x3^2 double sx13 = Math.pow(x1, 2) - Math.pow(x3, 2); // y1^2 - y3^2 double sy13 = Math.pow(y1, 2) - Math.pow(y3, 2); double sx21 = Math.pow(x2, 2) - Math.pow(x1, 2); double sy21 = Math.pow(y2, 2) - Math.pow(y1, 2); double f = ((sx13) * (x12) + (sy13) * (x12) + (sx21) * (x13) + (sy21) * (x13)) / (2 * ((y31) * (x12) - (y21) * (x13))); double g = ((sx13) * (y12) + (sy13) * (y12) + (sx21) * (y13) + (sy21) * (y13)) / (2 * ((x31) * (y12) - (x21) * (y13))); double c = -Math.pow(x1, 2) - Math.pow(y1, 2) - 2 * g * x1 - 2 * f * y1; // eqn of circle be x^2 + y^2 + 2*g*x + 2*f*y + c = 0 // where centre is (h = -g, k = -f) and radius r // as r^2 = h^2 + k^2 - c double h = -g; double k = -f; double sqr_of_r = h * h + k * k - c; // r is the radius double r = Math.sqrt(sqr_of_r); return new double[]{h,k,r}; } // Find area of a polygon using the "shoelace" algorithm: static double polya(double x[], double y[]) { double a = 0; for (int i = 0; i < n; i++) { a += x[i]*y[(i+1)%n] - x[(i+1)%n]*y[i]; } return -(a)/2.; } // Finds (signed) area of a triangle; used to check left/right orientation // and collinearity (probably could have just used polya, above): static double right(double x1, double y1, double x2, double y2, double x3, double y3) { double area = x1*y2 + x2*y3 + x3*y1 - x2*y1 - x3*y2 - x1*y3; return area; } }