07ad2e1283 2013-06-30 kinaba: // Verified: partly by geocon2013 D(1). 07ad2e1283 2013-06-30 kinaba: 07ad2e1283 2013-06-30 kinaba: // Crosspoing of a line (not lineseg!) and a circle). 07ad2e1283 2013-06-30 kinaba: bool line_circle(CMP la, CMP lb, CMP c, double r, CMP* p1, CMP* p2) 07ad2e1283 2013-06-30 kinaba: { 07ad2e1283 2013-06-30 kinaba: CMP v = (lb-la) / abs(lb-la); 07ad2e1283 2013-06-30 kinaba: CMP o = (c-la) / v; 07ad2e1283 2013-06-30 kinaba: if( abs(o.imag()) > r ) 07ad2e1283 2013-06-30 kinaba: return false; 07ad2e1283 2013-06-30 kinaba: double dx = sqrt(r*r - o.imag()*o.imag()); 07ad2e1283 2013-06-30 kinaba: *p1 = la + (o.real()-dx)*v; 07ad2e1283 2013-06-30 kinaba: *p2 = la + (o.real()+dx)*v; 07ad2e1283 2013-06-30 kinaba: return true; 07ad2e1283 2013-06-30 kinaba: } 07ad2e1283 2013-06-30 kinaba: 07ad2e1283 2013-06-30 kinaba: // Whether or not |p| is in the circle (c, r). 07ad2e1283 2013-06-30 kinaba: bool pt_in_circle(CMP p, CMP c, double r) 07ad2e1283 2013-06-30 kinaba: { 07ad2e1283 2013-06-30 kinaba: return norm(p-c) <= r*r; 07ad2e1283 2013-06-30 kinaba: } 07ad2e1283 2013-06-30 kinaba: 07ad2e1283 2013-06-30 kinaba: // Assuming |o| is outside (C,r), compute the two tangent points. 07ad2e1283 2013-06-30 kinaba: void sessen(CMP o, CMP c, double r, CMP* p1, CMP* p2) 07ad2e1283 2013-06-30 kinaba: { 07ad2e1283 2013-06-30 kinaba: double len = sqrt(norm(c-o) - r*r); 07ad2e1283 2013-06-30 kinaba: double theta = asin(r/abs(c-o)); 07ad2e1283 2013-06-30 kinaba: 07ad2e1283 2013-06-30 kinaba: if(p1) *p1 = o+(c-o)*polar(len/abs(c-o), theta); 07ad2e1283 2013-06-30 kinaba: if(p2) *p2 = o+(c-o)*polar(len/abs(c-o), -theta); 07ad2e1283 2013-06-30 kinaba: } 07ad2e1283 2013-06-30 kinaba: 07ad2e1283 2013-06-30 kinaba: // For two points |p| and |q| on (c,r), compute their distance along the circle. 07ad2e1283 2013-06-30 kinaba: double d_on_c(CMP c, double r, CMP p, CMP q) 07ad2e1283 2013-06-30 kinaba: { 07ad2e1283 2013-06-30 kinaba: return abs(arg((p-c) / (q-c))) * r; 07ad2e1283 2013-06-30 kinaba: }