import java.awt.geom.Point2D; import java.io.File; import java.io.PrintStream; import java.util.Scanner; public class BanjoThreeie_artur { static final double eps = 1e-9; static Point2D.Double p, q; static double r, t, chord; static double[] pbounds, qbounds; public static void main(String[] args) throws Exception { Scanner in = new Scanner(System.in); while (true) { p = new Point2D.Double(in.nextInt(), in.nextInt()); q = new Point2D.Double(in.nextInt(), in.nextInt()); double x = in.nextInt(), y = in.nextInt(); r = in.nextInt(); t = in.nextInt(); if (r == 0) break; chord = 2 * Math.asin(t / r / 2); p.x -= x; p.y -= y; q.x -= x; q.y -= y; double[] line = { p.y - q.y, q.x - p.x, p.y * (p.x - q.x) - p.x * (p.y - q.y) }; double result = p.distance(q); Point2D.Double[] points = getLineCircleIntersection(line[0], line[1], line[2], r); if (points != null && segmentIntersects(points) && points[0].distance(points[1]) + eps > t) { Point2D.Double p1, p2, q1, q2; if (points[0].distanceSq(p) < points[1].distanceSq(p)) { p1 = points[0]; q1 = points[1]; } else { p1 = points[1]; q1 = points[0]; } p2 = getCloserTangentPoint(r, p, p1); q2 = getCloserTangentPoint(r, q, q1); if (equal(chord, 0)) { double diff = Math.abs(Math.atan2(p2.y, p2.x) - Math.atan2(q2.y, q2.x)); result = Math.min(diff, 2 * Math.PI - diff) * r; result += p.distance(p2) + q2.distance(q); } else { pbounds = getAngles(p1, p2); qbounds = getAngles(q1, q2); result = search(0, 0, 0); } } System.out.printf("%.2f\n", result); } } static double search(int idx, double lambda1, double lambda2) { if (idx > 1) return getValue(lambda1, lambda2); double low = 0, high = 1; for (int i = 0; i < 50; i++) { double mid1 = (2 * low + high) / 3, mid2 = (low + 2 * high) / 3; double value1 = search(idx + 1, idx == 0 ? mid1 : lambda1, idx == 1 ? mid1 : lambda2); double value2 = search(idx + 1, idx == 0 ? mid2 : lambda1, idx == 1 ? mid2 : lambda2); if (value1 < value2) high = mid2; else low = mid1; } return search(idx + 1, idx == 0 ? low : lambda1, idx == 1 ? low : lambda2); } static double getAngle(double lambda, double[] bounds) { return lambda * bounds[1] + (1 - lambda) * bounds[0]; } static double getValue(double lambda1, double lambda2) { double angle1 = getAngle(lambda1, pbounds); double angle2 = getAngle(lambda2, qbounds); double diff = Math.min(Math.abs(angle1 - angle2), 2 * Math.PI - Math.abs(angle1 - angle2)); double inside = t * (int) (diff / chord) + Math.sin((diff % chord) / 2) * 2 * r; double outside = p.distance(r * Math.cos(angle1), r * Math.sin(angle1)) + q.distance(r * Math.cos(angle2), r * Math.sin(angle2)); return inside + outside; } static double[] getAngles(Point2D.Double p1, Point2D.Double p2) { double a = Math.atan2(p1.y, p1.x); double b = Math.atan2(p2.y, p2.x); if (a < 0) a += 2 * Math.PI; if (b < 0) b += 2 * Math.PI; if (a < b && (b - a > 2 * Math.PI + a - b)) { double t = a; a = b; b = t; } if (a > b && (a - b < 2 * Math.PI + b - a)) { double t = a; a = b; b = t; } while (b < a) b += 2 * Math.PI; return new double[] { a, b }; } static boolean segmentIntersects(Point2D.Double[] intersections) { if (equal(p.distance(q), p.distance(intersections[0]) + q.distance(intersections[0]))) return true; else return false; } static Point2D.Double[] getLineCircleIntersection(double a, double b, double c, double r) { double sqAB = a * a + b * b, sqR = r * r, sqC = c * c; double x = -a * c / sqAB, y = -b * c / sqAB; if (sqC > sqR * sqAB + 1e-9) return null; else if (Math.abs(sqC - sqR * sqAB) < 1e-9) return null; else { double d = r * r - c * c / sqAB; double t = Math.sqrt(d / sqAB); return new Point2D.Double[] { new Point2D.Double(x + b * t, y - a * t), new Point2D.Double(x - b * t, y + a * t) }; } } static Point2D.Double getCloserTangentPoint(double r, Point2D.Double p, Point2D.Double pA) { double a = -2 * p.x; double b = -2 * p.y; double c = p.x * p.x + p.y * p.y - p.distanceSq(0, 0) + 2 * r * r; Point2D.Double[] points = getLineCircleIntersection(a, b, c, r); double dist0 = pA.distanceSq(points[0]), dist1 = pA.distanceSq(points[1]); if (equal(dist0, dist1)) { if (equal(points[0].x, points[1].x)) return points[0].y < points[1].y ? points[0] : points[1]; else return points[0].x < points[1].x ? points[0] : points[1]; } else return dist0 < dist1 ? points[0] : points[1]; } static boolean equal(double x, double y) { return Math.abs(x - y) < eps; } }