/* Kristoffer Hansen. arnsfelt@daimi.au.dk */ #include #include #include #include #include double sqr(double x) { return x*x; } const double eps = 0.000000001; class point { public: double x,y; point() {}; point(double x, double y) : x(x),y(y) {}; }; class circle { public: double x,y,r; circle() {}; circle(double x, double y, double r) : x(x),y(y),r(r) {}; circle(const point &c, double r) : x(c.x),y(c.y),r(r) {}; circle(const circle &c) : x(c.x),y(c.y),r(c.r) {}; }; vector intersect(const circle &c1, const circle &c2) { vector I; point u(c2.x-c1.x,c2.y-c1.y); double s,t,tsqr; double invusqrlen = 1.0/(sqr(u.x)+sqr(u.y)); s = 0.5 * ((sqr(c1.r)-sqr(c2.r))*invusqrlen+1); tsqr = sqr(c1.r)*invusqrlen-sqr(s); if (tsqr>=-eps) { if (tsqr>eps) { t = sqrt(tsqr); I.push_back(point(c1.x+s*u.x+t*u.y,c1.y+s*u.y-t*u.x)); I.push_back(point(c1.x+s*u.x-t*u.y,c1.y+s*u.y+t*u.x)); } else { I.push_back(point(c1.x+s*u.x,c1.y+s*u.y)); } } return I; } vector tangents(const point &p, const circle &c) { point m(p.x+0.5*(c.x-p.x),p.y+0.5*(c.y-p.y)); double r = sqrt(sqr(0.5*(c.x-p.x))+sqr(0.5*(c.y-p.y))); return intersect(c, circle(m,r)); } double project(const point &p, const point &q) { return p.x-p.y/(q.y-p.y)*(q.x-p.x); } typedef pair interval; int main() { int i,j,n; double a,b,r; circle pipe; point light; vector P; interval I; vector Is; vector::const_iterator II; while (cin >> n && n>0) { cin >> light.x >> light.y; Is.clear(); for (i=0; i> a >> b >> r; pipe = circle(a,b,r); P = tangents(light,pipe); I.first = project(light,P[0]); I.second = project(light,P[1]); if (I.first>I.second) { a = I.first; I.first=I.second; I.second=a; } Is.push_back(I); } sort(Is.begin(),Is.end()); a = Is[0].first; b = Is[0].second; for (II=Is.begin(); II!=Is.end(); II++) { if (II->first<=b) { if (II->second>b) b = II->second; } else { printf("%.2lf %.2lf\n",a,b); a = II->first; b = II->second; } } printf("%.2lf %.2lf\n",a,b); cout << endl; } return 0; }