import java.awt.geom.Line2D; import java.util.*; import static java.lang.Math.*; public class RedGem { public static void main(String[] args) { Scanner in = new Scanner(System.in); while(true) { double ans = solve(in); if (ans == -1) break; System.out.format("%.04f\n", 1-ans); } } static double solve(Scanner in) { int N = in.nextInt(); if (N == 0) return -1; Circle outer = new Circle(new Point(0, 0), in.nextInt()); Circle inner = new Circle(new Point(in.nextInt(), in.nextInt()), in.nextInt()); ArrayList I = new ArrayList(); for (int i = 0; i < N; i++) { Circle C = new Circle(new Point(in.nextInt(), in.nextInt()), in.nextInt()); Line[] L = circcirctan(inner, C); double ang1 = norm(circlineforward(outer, L[0]).ang()); double ang2 = norm(circlineforward(outer, L[1]).ang()); double mid = norm(circlineforward(outer, new Line(inner.p, C.p)).ang()); Interval inter = new Interval(min(ang1, ang2), max(ang1, ang2)); if (!inter.contains(mid)) { I.add(new Interval(inter.en, 2*PI)); I.add(new Interval(0, inter.st)); } else { I.add(inter); } } Collections.sort(I); double len = 0; double prev = 0; for (Interval i : I) { if (i.st <= prev) { len += max(0, i.en - prev); } else { len += i.en - i.st; } prev = max(prev, i.en); } return len / (2*PI); } static double norm(double theta) { while(theta < 0) theta += 2*PI; while(theta >= 2*PI) theta -= 2*PI; return theta; } static Line[] circcirctan(Circle a, Circle b){ if(a.r < b.r) { Line[] res = circcirctan(b, a); res[0].reverse(); res[1].reverse(); return res; } double d = a.p.dist(b.p); double d1 = a.r*d/(a.r + b.r); double t = acos(a.r/d1); Point v = b.p.sub(a.p);//crossing Line l1 = new Line(a.p.add(v.scale(a.r).rotate(t)), b.p.add(v.scale(-b.r).rotate(t))); Line l2 = new Line(a.p.add(v.scale(a.r).rotate(-t)), b.p.add(v.scale(-b.r).rotate(-t))); checkOnCircle(a, b, l1); checkOnCircle(a, b, l2); checkTangent(a, l1); checkTangent(a, l2); checkTangent(b, l1); checkTangent(b, l2); return new Line[]{l1, l2}; } private static void checkTangent(Circle c, Line l) { Point[] P = circline(c, l); if (P.length != 2 || !eq(P[0].dist(P[1]), 0.0)) throw new RuntimeException(); } static void checkOnCircle(Circle a, Circle b, Line l) { checkOnCircle(a, l.a); checkOnCircle(b, l.b); } static boolean eq(double a, double b) { return abs(a-b) < eps; } static void checkOnCircle(Circle a, Point p) { if (!eq(a.r, a.p.dist(p))) throw new RuntimeException(); } static void checkOnLine(Line l, Point p) { if (!eq(Line2D.ptLineDist(l.a.x, l.a.y, l.b.x, l.b.y, p.x, p.y), 0.0)) throw new RuntimeException(); } static Point circlineforward(Circle c, Line l) { Point[] P = circline(c, l); if (P[0].dot(l.b.sub(l.a)) > 0) { return P[0]; } return P[1]; } static Point[] circline(Circle c, Line l){ Point x = pointline(c.p, l); double d = x.dist(c.p); if(d > c.r + eps) return new Point[0]; double h = sqrt(max(0, SQ(c.r) - SQ(d))); Point perp = l.a.sub(l.b); Point[] P = new Point[]{x.add(perp.scale(h)), x.add(perp.scale(-h))}; checkOnCircle(c, P[0]); checkOnCircle(c, P[1]); checkOnLine(l, P[0]); checkOnLine(l, P[1]); return P; } static Point pointline(Point p, Line l){ Point v = l.b.sub(l.a).scale(1); double dot = p.sub(l.a).dot(v); return l.a.add(v.mult(dot)); } static double SQ(double d) { return d*d; } static double eps = 1e-4; static class Interval implements Comparable { double st, en; Interval(double st, double en) { this.st = st; this.en = en; } boolean contains(double p) { if (st < en) { return st <= p && p <= en; } else { return st <= p || p <= en; } } public int compareTo(Interval i) { if (st < i.st) return -1; if (st > i.st) return 1; return 0; } } static class Point{ double x, y; Point(double x, double y) { this.x = x; this.y = y; } Point sub(Point p) { return new Point(x-p.x, y-p.y); } Point add(Point p) { return new Point(x+p.x, y+p.y); } double len() { return hypot(x, y); } double dist(Point p) { return sub(p).len(); } Point rotate(double theta) { return new Point(x*cos(theta) - y*sin(theta), x*sin(theta) + y*cos(theta)); } Point scale(double length) { return mult(length/len()); } Point mult(double s) { return new Point(x*s, y*s); } double dot(Point p) { return x*p.x + y*p.y; } double ang() { return atan2(y, x); } public String toString() { return String.format("(%.03f, %.03f)", x, y); } } static class Line{ Point a, b; Line(Point a, Point b) { this.a = a; this.b = b; } void reverse() { Point temp = a; a = b; b = temp; } public String toString() { return String.format("[%s => %s]", a, b); } } static class Circle{ Point p; double r; Circle(Point p, double r) { this.p = p; this.r = r; } public String toString() { return String.format("{%s, %.03f}", p, r); } } }