/* @JUDGE_ID: 32472GK 1075 C++ */ #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef complex p2d; typedef p2d v2d; struct p3d { double x, y, z; p3d() : x(0), y(0), z(0) {} p3d(double x, double y, double z) : x(x), y(y), z(z) {} p3d(const p3d& p) : x(p.x), y(p.y), z(p.z) {} void operator/=(double a) { x/=a, y/=a, z/=a; } }; typedef p3d v3d; static inline v3d operator - (const v3d& a, const v3d& b) { return v3d(a.x - b.x, a.y - b.y, a.z - b.z); } static inline v3d operator + (const v3d& a, const v3d& b) { return v3d(a.x + b.x, a.y + b.y, a.z + b.z); } double inner_prod(const v3d& a, const v3d& b) { return a.x * b.x + a.y * b.y + a.z * b.z; } double abs(const v3d& a) { return sqrt(inner_prod(a,a)); } v3d outer_prod(const v3d& a, const v3d& b) { p3d result(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); return result; } double outer_prod(const p2d& a, const p2d& b) { return a.real() * b.imag() - a.imag() * b.real(); } #define EPSILON 1.0E-6 double solve(p3d& _A, p3d& _B, p3d& _C, double R) { p2d C(0, 0); v3d X = _B - _A; if(fabs(inner_prod(X, X)) < EPSILON) return 0.0; v3d Z = outer_prod(_C - _B, X); v3d Y = outer_prod(Z, X); p2d A, B; if(fabs(inner_prod(Z, Z)) < EPSILON) { X /= abs(X); A = p2d(inner_prod(X, _A - _C), 0); B = p2d(inner_prod(X, _B - _C), 0); } else { X/=abs(X), Y/=abs(Y), Z/=abs(Z); A = p2d(inner_prod(X, _A - _C), inner_prod(Y, _A - _C)); B = p2d(inner_prod(X, _B - _C), inner_prod(Y, _B - _C)); } //cout << A << B << endl; assert(fabs(A.imag() - B.imag()) < EPSILON); // make sure // A | B // ---+--- // | A = p2d(A.real(), abs(A.imag())); B = p2d(B.real(), abs(B.imag())); if(A.real() > 0) swap(A,B); /* cout << "A:" << A << endl; cout << "B:" << B << endl;*/ if(A.imag() >= R) { //cout << "trivial case 1" << endl; return abs(A - B); } if(A.real()*B.real()>0) { //cout << "trivial case 2" << endl; return abs(A - B); } double theA, theB; { double x = A.real(), y = A.imag(); double t = R*y + sqrt( R*y*R*y - norm(A)*(R*R-x*x) ); t /= norm(A); theA = 3.141592653589793 - asin(t); } { double x = B.real(), y = B.imag(); double t = R*y + sqrt( R*y*R*y - norm(B)*(R*R-x*x) ); t /= norm(B); theB = asin(t); } p2d Q( R*cos(theA), R*sin(theA) ); p2d P( R*cos(theB), R*sin(theB) ); double ans = R * (theA - theB) + abs(Q-A) + abs(P-B); return ans; } int main() { p3d A, B, C; double R; cin >> A.x >> A.y >> A.z; cin >> B.x >> B.y >> B.z; cin >> C.x >> C.y >> C.z; cin >> R; static char buffer[256]; double ans = solve(A, B, C, R); sprintf(buffer, "%.2f", floor(100.0 * ans + 0.5) / 100.0); cout << buffer << endl; return 0; }