// Arup Guha
// 6/25/2013
// Solution to 2012 Chicago Invitational Problem H: Red Gem.

// The key to this solution is using similar triangles created when drawing
// in the appropriate site lines between the gem and a blocking circle.

import java.util.*;

public class h {

	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);

		// Get this case.
		int n = stdin.nextInt();
		int largeR = stdin.nextInt();
		int x = stdin.nextInt();
		int y = stdin.nextInt();
		int r = stdin.nextInt();
		circle gem = new circle(x, y, r);

		// Go through each case.
		while (n != 0) {

			// Read in obstructions.
			circle[] inway = new circle[n];
			for (int i=0; i<n; i++) {
				x = stdin.nextInt();
				y = stdin.nextInt();
				r = stdin.nextInt();
				inway[i] = new circle(x, y, r);
			}

			// Print solution.
			System.out.printf("%.4f\n", solve(largeR, gem, inway));

			// Go onto the next case.
			n = stdin.nextInt();
			largeR = stdin.nextInt();
			x = stdin.nextInt();
			y = stdin.nextInt();
			r = stdin.nextInt();
			gem = new circle(x, y, r);
		}
	}

	public static double solve(int platformR, circle gem, circle[] inway) {

		int n = inway.length;
		ArrayList<interval> gaps = new ArrayList<interval>();

		// Store all parts of the circumference (scaled to [0,1]) that are blocked.
		for (int i=0; i<n; i++) {
			ArrayList<interval> newgaps = getBlocks(platformR, gem, inway[i]);
			for (int j=0; j<newgaps.size(); j++)
				gaps.add(newgaps.get(j));
		}

		// Sort by start value.
		Collections.sort(gaps);

		double missing = 0, curStart = gaps.get(0).start, curEnd = gaps.get(0).end;

		// Loop through, updating whenever a streak ends and a new one starts.
		for (int i=1; i<gaps.size(); i++) {

			// For the new interval
			double newStart = gaps.get(i).start;
			double newEnd = gaps.get(i).end;

			// Old interval ended.
			if (newStart > curEnd) {
				missing += (curEnd - curStart);
				curStart = newStart;
				curEnd = newEnd;
			}

			// It's continuing, let's see if the end changes though.
			else {
				if (newEnd > curEnd)
					curEnd = newEnd;
			}
		}

		// Need to add this part.
		missing += (curEnd - curStart);

		// We want the unobstructed part...
		return 1-missing;
	}

	public static ArrayList<interval> getBlocks(int platformR, circle gem, circle block) {

		// Get direction vector from center gem to center block.
		double centerAngle = Math.atan2(block.center[1]-gem.center[1], block.center[0]-gem.center[0]);

		// Set up info about the similar triangles to get the offset to the vector above that form the sight lines.
		double ratio = ((double)gem.radius)/(gem.radius+block.radius);
		double hyp = ratio*dist(gem.center, block.center);
		double offset = Math.asin(gem.radius/hyp);

		// This is the intersection point of the two site lines.
		double[] pt = new double[2];
		for (int i=0; i<2; i++)
			pt[i] = gem.center[i] + ratio*(block.center[i] - gem.center[i]);

		// Here are the two vectors from the intersection point to the wall of the floor.
		double[] vect1 = getVect(centerAngle-offset);
		double[] vect2 = getVect(centerAngle+offset);

		// Two key lines.
		lineseg line1 = new lineseg(pt, vect1);
		lineseg line2 = new lineseg(pt, vect2);

		double left = line1.intersect(platformR)/(2*Math.PI);
		double right = line2.intersect(platformR)/(2*Math.PI);

		ArrayList<interval> ans = new ArrayList<interval>();

		// Normal case.
		if (left <= right)
			ans.add(new interval(left, right));

		// Case where the interval must be split into two.
		else {
			ans.add(new interval(left, 1));
			ans.add(new interval(0, right));
		}

		return ans;
	}

	public static double[] getVect(double angle) {
		double[] ans = new double[2];
		ans[0] = Math.cos(angle);
		ans[1] = Math.sin(angle);
		return ans;
	}

	public static double[] multiply(double[] vector, double m) {
		double[] ans = new double[2];
		for(int i=0; i<2; i++)
			ans[i] = vector[i]*m;
		return ans;
	}

	public static double[] add(double[] pt1, double[] pt2) {
		double[] ans = new double[pt1.length];
		for (int i=0; i<ans.length; i++)
			ans[i] = pt1[i] + pt2[i];
		return ans;
	}

	public static double dist(double[] pt1, double[] pt2) {
		double sum = 0;
		for (int i=0; i<pt1.length; i++)
			sum += Math.pow(pt1[i]-pt2[i],2);
		return Math.sqrt(sum);
	}
}

// Helps us store intervals and sort them.
class interval implements Comparable<interval> {

	public double start;
	public double end;

	public interval(double s, double e) {
		start = s;
		end = e;
	}

	// Sorts by start time, then reverse end time.
	public int compareTo(interval other) {
		if (this.start < other.start)
			return -1;
		else if (this.start > other.start)
			return 1;
		if (other.end < this.end)
			return -1;
		else if (other.end > this.end)
			return 1;
		return 0;
	}
}

class circle {

	public double[] center;
	public double radius;

	public circle(int x, int y, int r) {
		center = new double[2];
		center[0] = x;
		center[1] = y;
		radius = r;
	}
}

// Stores a line segment, which we extrapolate to a ray.
class lineseg {

	public double[] start;
	public double[] vector;

	// Start point and vector.
	public lineseg(double[] s, double[] v) {
		start = s;
		vector = v;
	}

	// Returns the point on this line evaluated at parameter t.
	public double[] getPt(double t) {
		double[] ans = new double[2];
		for (int i=0; i<2; i++)
			ans[i] = start[i] + t*vector[i];
		return ans;
	}

	// Returns the intersection point between this segment (a ray) and the
	// circle centered at (0,0) with radius. The point is returned as an angle
	// as specified by atan2, with PI added so the range is [0, 2PI).
	// Returns only positive lambda value intersection.
	public double intersect(double radius) {

		// Coefficients for quadratic that solves for t, the parameter of intersection.
		double a = vector[0]*vector[0] + vector[1]*vector[1];
		double b = 2*(start[0]*vector[0]+start[1]*vector[1]);
		double c = start[0]*start[0] + start[1]*start[1] - radius*radius;

		// We are guaranteed an intersection with t > 0, so return it.
		double t = (-b + Math.sqrt(b*b-4*a*c))/(2*a);
		double[] ans = getPt(t);
		return Math.atan2(ans[1], ans[0]) + Math.PI;
	}
}