#include #include #include using namespace std; const bool DEBUG = false; const double PI = 4.0*atan(1.0); const double TOL = 0.01; class point { public: point(double xx=0.0, double yy=0.0) : x(xx), y(yy) {}; void print(ostream& out) { out << '(' << x << ',' << y << ')'; } double x, y; }; ostream& operator<<(ostream& out, point p) { p.print(out); return out; } class vector { public: vector(point p1, point p2) // initialize as difference between 2 points { x = p1.x - p2.x; y = p1.y - p2.y; } double dot(vector rhs) { double ans = x*rhs.x + y*rhs.y; return ans/len()/rhs.len(); } double len() { return sqrt(x*x + y*y); } void print(ostream& out) { out << '(' << x << ',' << y << ')'; } double x, y; }; ostream& operator<<(ostream& out, vector p) { p.print(out); return out; } bool ok(double val) { return (val > TOL && val <= 1.0); } void calcInt(double a1, double a2, double b1, double b2, double c1, double c2, double r, double& t1, double & t2) // // calculate intersection of circle at (c1, c2), radius r with line defined by // // x = a1*t + a2 // y = b1*t + b2 // { //cout << "a1, a2, b1, b2 = " << a1 << "," << a2 << ' ' << b1 << ',' << b2 << endl; double a = a1*a1+b1*b1; double b = 2*(a1*a2 + b1*b2); double c = a2*a2+b2*b2-r*r; double disc = sqrt(b*b - 4*a*c); t1 = (-b-disc)/2/a; t2 = (-b+disc)/2/a; } point calcPoint(point p1, point p2, double r) { double a1 = p2.x - p1.x; double a2 = p1.x - p2.x; double b1 = p2.y - p1.y; double b2 = p1.y - p2.y; double t1, t2; calcInt(a1, a2, b1, b2, p2.x, p2.y, r, t1, t2); //cout << "t1, t2 = " << t1 << ',' << t2 << endl; point ans(p2.x+a1*t2+a2, p2.y+b1*t2+b2); return ans; } point calcRefl(point p1, point p2, point p3) // // calc reflection of point p3 across line connecting p1 to p2 // { double delx = p2.x-p1.x; double dely = p2.y-p1.y; // // look for intersection of line (p1.x+delx*t, p1.y+dely*t) with // line (p3.x-dely*u, p3.y+delx*u) double u = (-delx*(p3.y-p1.y)+dely*(p3.x-p1.x))/(delx*delx+dely*dely); // // reflected point found using parametric value 2*u point ans(p3.x-dely*2*u, p3.y + delx*2*u); return ans; } bool tooClose(double x1, double y1, double x2, double y2, double x3, double y3, double r) // // check if ball at (x3, y3) is less than 2r away from line from (x1,y1) to (x2, y2) // { double dx = x2-x1; double dy = y2-y1; double denom = dx*dx + dy*dy; double t = ((x3-x1)*dx + (y3-y1)*dy)/denom; double u = ((y3-y1)*dx - (x3-x1)*dy)/denom; double xint = x1 + t*dx; double yint = y1 + t*dy; // cout << endl; // cout << x1 << ',' << y1 << ' ' << x2 << ',' << y2 << ' ' << x3 << ',' << y3 << endl; // cout << xint << ',' << yint << endl; // cout << x3 + u*dy << ',' << y3 - u*dx << endl; dx = x3-xint; dy = y3-yint; double dist = sqrt(dx*dx + dy+dy); // cout << dist << ' ' << r << endl; return (dist - 2*r < TOL); } int main() { double w, l, h, r; point p1, p2, p3; double d, theta; double pi = 4*atan(1.0); cin >> w >> l; point lhole(0,l), rhole(w,l); cin >> r >> p1.x >> p1.y >> p2.x >> p2.y >> p3.x >> p3.y >> h; point p4 = calcPoint(lhole, p2, 2*r); point p5 = calcPoint(rhole, p3, 2*r); point p6 = calcPoint(p5, p1, 2*r); point p7 = calcRefl(p5, p6, p4); vector v1(p2,p4), // direction from ball 2 to left hole v2(p3,p5), // direction from ball 3 to right hole v3(p5,p1), // direction from ball 1 to ball 3 v4(p6,p7), // initial direction of cue ball v5(p4,p6); // direction from carom to ball 2 if (DEBUG) { cout << "p4 = " << p4 << endl; cout << "p5 = " << p5 << endl; cout << "p6 = " << p6 << endl; cout << "p7 = " << p7 << endl; cout << "v1 = " << v1 << endl; cout << "v2 = " << v2 << endl; cout << "v3 = " << v3 << endl; cout << "v4 = " << v4 << endl; cout << "v5 = " << v5 << endl; cout << "v1 dot v5 = " << v1.dot(v5) << endl; cout << "v2 dot v3 = " << v2.dot(v3) << endl; cout << "v3 dot v4 = " << v3.dot(v4) << endl; } // // direction is p6-p7 (= v4) // if (!ok(v1.dot(v5))) cout << "impossible" << endl; else if (!ok(v2.dot(v3))) cout << "impossible" << endl; else if (!ok(v3.dot(v4))) cout << "impossible" << endl; else { theta = atan2(p6.y-p7.y, p6.x-p7.x); theta *= (180/PI); d = (h-p7.y)/(p6.y-p7.y)*(p6.x-p7.x) + p7.x; if (DEBUG) cout << "d = " << d << endl; if (theta < 0.0 || d < r || d > w-r || tooClose(d, h, p1.x, p1.y, p2.x, p2.y, r)) cout << "impossible" << endl; else // cout << d << ' ' << theta << endl; printf("%.2f %.2f\n", d, theta); } return 0; }