UVA 12304 2D Geometry 110 in 1! 【几何基础知识题】【敲个两三百行也没啥是吧?咱们都是纯爷们儿】
这题是RujiaLiu的几何专场中,第四简单的题目了。果断无脑流,果断需要敲无数行模板,果断需要考虑各种情况。
还好srgba给的sample照顾到了所有情况,并且没有太卡精度,不过没有spj,不得不说老uva在这一点上太二了。
题目六部分,六个和圆有关的问题。以及附上我的模板:
预备知识(模板):
eps
sgn符号函数
点(向量)类:
构造、加、减、数乘(放缩)、点积、叉积、比较器、反向、法向、单位向量、向量以任意角度旋转。
直线类:
构造、旋转、平移、判点其上、算点距离、点投影、点对称(后加的,无关)、求交点。
圆类:
两点构造、三点构造(外接圆)、点半径构造、点在内or上or外、求点到圆的切线。
六个问题:
三角形外接圆:
根据垂径定理搞定,两线求交(不是自己写的),精度比较高的方法是叉积算比例求定比分点什么的。
三角形内切圆:
抄的别人的模板。(我觉得这个最难,虽然我自己也写了一个吧,后来删掉了,因为丢精度比较厉害。就是用那种算夹角,旋转向量再求交的方法)
给定一点一圆,求过该点的圆切线:
两种情况(第三种是圆内点,无解):一,点在圆上,直接求出点到圆心的矢量的法向量,就是所求;二,点在圆外,求出点心矢量后,根据切线三角形,算出旋转角,向量对称旋转即得。
给定一点一线和半径求圆:
四种情况:一,圆直径小于点线距离,无解;二,等于,唯一解,求出点在直线投影,两点连线中点即为圆心;三,圆直径大于点线距离,做个梯形,算一下夹角,对称旋转即可出两解;四,点在线上,点平移即可。
两条线加半径定圆:
因为线不平行,所以一定有解,且是四个解:即把每条线向两个方向平移半径长度即可确定2*2个圆。
两个圆加半径确定圆:
三种情况:两圆距离(圆心距离减半径和)大于新圆直径,无解:等于,唯一解,圆外线段中点,不好求,那么就是两圆连线上(ra+r)/(ra+rb+2*r)出的分点;小于,两解,构造三角形,算出定比分点比例,垂直平移分点即可。
上海比赛的时候模板确实用上了- -不过还是没出题。太悲剧了。自己还是太弱了啊- -。
附上我的2D几何模板吧~略长~387lines
/*
point class && line class && circle class
Many things about circle and so on
WTF
*/
#include < iostream >
#include < cstdio >
#include < algorithm >
#include < cstring >
#include < cmath >
using namespace std;
#define maxn 1005
#define sqr(x) ((x) * (x))
int n;
const double eps = 1e - 8 ;
const double pi = acos( - 1.0 );
int sgn( double x)
{
return fabs(x) < eps ? 0 : x < - eps ? - 1 : 1 ;
}
struct point
{
double x,y;
point(){}
point( double a, double b):x(a),y(b){}
point operator - (point p){ return point(x - p.x,y - p.y);}
point operator + (point p){ return point(x + p.x,y + p.y);}
double norm(){ return sqrt(sqr(x) + sqr(y));}
double norm2(){ return sqr(x) + sqr(y);}
double operator * (point p){ return x * p.x + y * p.y;}
point operator * ( double a){ return point(x * a,y * a);}
double operator ^ (point p){ return x * p.y - y * p.x;}
bool operator == (point p){ return sgn(x - p.x) == 0 && sgn(y - p.y) == 0 ;}
bool operator < ( const point & p){ return sgn(x - p.x) < 0 || (sgn(x - p.x) == 0 && sgn(y - p.y) < 0 );}
point rev(){ return point( - x, - y);}
point ver(){ return point(y, - x);}
point unit(){ return point(x / norm(),y / norm());}
point rotate( double theta) // the rotate function for vector to rotate
{ // in counter-clockwise direction
return point(x * cos(theta) - y * sin(theta),x * sin(theta) + y * cos(theta));
}
}p[maxn];
struct line
{
point p,k;
line(){}
// MIND THIS!!!!!
line(point a,point b):p(a),k(b){} // a is the fixed point,k is the directed vector
line rotate( double theta){line l;l.p = p;l.k = k.rotate(theta); return l;}
bool on(point q){ return sgn((q - p) ^ k) == 0 ;}
// move the line acording to the parpendicular-direction with offset distance
line move( double offset) // to which direction??
{ // every time we use this,we can try the bi-direction
point vec = k.ver();
vec = vec.unit() * offset;
point q = p + vec;
return line(q,k);
}
// distance from a point to a line
double dis(point q)
{
point a = p,b = a + k;
return fabs((a - q) ^ (b - q)) / k.norm();
}
// cast the point to the line and find the pedal
/*
by construct the line through the 'q' parallel to the origin line
calc the lq.p 's vector to 'q'
add it onto the origin line's p
*/
point cast(point q) // something wrong
{
double d = line(p,k).dis(q);
line lq = line(p,k).move(d);
point vec;
if ( ! lq.on(q))
lq = line(p,k).move( - d);
vec = q - lq.p;
return p + vec;
}
// calc the symmetrical point of the given one againt the given line
point sym(point q)
{
point c = line(p,k).cast(q);
point vec = c - q;
return c + vec;
}
// copied from some big cow
// by vector product and "division point"
int cross(line q,point & ans)
{
point a = p,b = p + k,c = q.p,d = q.p + q.k;
ans = d;
double rate = ((b - a) ^ (a - d)) / ((b - a) ^ (c - d));
ans = ans + ((c - d) * rate);
}
};
struct circle
{
point o;
double r;
circle(){}
circle(point _o, double _r):o(_o),r(_r){}
// by two points to calc the minimum circle
circle(point a,point b)
{
o = (a + b) * 0.5 ;
r = (a - o).norm();
}
// give three points (not on the same line)to calc the decided circle
circle(point a,point b,point c)
{
point m1 = (a + b) * 0.5 ,m2 = (b + c) * 0.5 ;
line l1 = line(m1,(b - a).ver()),l2 = line(m2,(c - b).ver());
l1.cross(l2,o);
r = (a - o).norm();
}
// judge a point in or on the circle or not
bool in (point x)
{
return sgn((x - o).norm() - r) <= 0 ;
}
// judge a point on the circular of the circle or not
bool inandon(point x)
{
return sgn((x - o).norm() - r) == 0 ;
}
// give a point and a cirlce,calc the two tangent line (just angles)
// by rotation ::mode 1
// if the point p is on the circular of the circle
// just output one tangentline ::mode 2
void tangentline(point p, double & th1, double & th2, int mode)
{
double alpha = atan2(o.y - p.y,o.x - p.x);
if (mode == 1 )
{
th1 = alpha + pi * 0.5 ;
if (sgn(th1 - pi) >= 0 )
th1 -= pi;
else if (sgn(th1) < 0 )
th1 += pi;
th1 = th1 / pi * 180.0 ;
}
else
{
// circle center and point p 's connected line 's angle
double theta = asin(r / (p - o).norm());
th1 = alpha + theta;
while (sgn(th1 - pi) >= 0 )
th1 -= pi;
while (sgn(th1) < 0 )
th1 += pi;
th2 = alpha - theta;
while (sgn(th2 - pi) >= 0 )
th2 -= pi;
while (sgn(th2) < 0 )
th2 += pi;
th1 = th1 / pi * 180.0 ;
th2 = th2 / pi * 180.0 ;
}
}
};
// copied from some big cow
// to calculate the insribed circle of a triangle
circle inscribed(point a,point b,point c)
{
point a1 = a + (b - a).unit() + (c - a).unit(),b1 = b + (a - b).unit() + (c - b).unit();
point ans;
line(a,a1 - a).cross(line(b,b1 - b),ans);
double r = line(a,b - a).dis(ans);
return circle(ans,r);
}
int onelineonepoint(point p,line l, double r,circle & a,circle & b)
{
double d = l.dis(p);
if (sgn(d - 2.0 * r) > 0 )
return 0 ;
else if (sgn(d - 2.0 * r) == 0 )
{
point c = l.cast(p);
a = circle((c + p) * 0.5 ,r);
return 1 ;
}
else if (sgn(d - 2.0 * r) < 0 && sgn(d) > 0 )
{
double det,theta;
det = d - r;
theta = acos(det / r);
point c = l.cast(p);
point to = c - p;
to = to.unit() * r;
point vec1 = to.rotate(theta),vec2 = to.rotate( - theta);
a = circle(p + vec1,r);
b = circle(p + vec2,r);
return 2 ;
}
else if (sgn(d) == 0 ) // the point is on the line
{
point per = l.k.ver();
per = per.unit() * r;
a = circle(p + per,r);
b = circle(p + per.rev(),r);
return 2 ;
}
}
// use two cross lines and one radius to calc four circles
// circle - answer array
circle four[ 10 ];
// use the center of circle to compare circles
bool cmpcircle(circle a,circle b)
{
return a.o < b.o;
}
void twolineoneradius(line a,line b, double r)
{
line A[ 2 ],B[ 2 ];
A[ 0 ] = a.move(r),A[ 1 ] = a.move( - r);
B[ 0 ] = b.move(r),B[ 1 ] = b.move( - r);
int cnt = 1 ;
for ( int i = 0 ;i < 2 ;i ++ )
for ( int j = 0 ;j < 2 ;j ++ )
{
point temp;
A[i].cross(B[j],temp);
four[cnt ++ ] = circle(temp,r);
}
}
// use two disjoint circle to calc one or two new circles tangent to them with given 'r'
// not in the middle line !!!!
int twocircle(circle a,circle b, double r,circle & c,circle & d)
{
point dir = (b.o - a.o);
double dis = dir.norm();
double len = dis - a.r - b.r;
double ra = r + a.r,rb = r + b.r;
if (sgn(len - 2.0 * r) > 0 )
return 0 ;
else if (sgn(len - 2.0 * r) == 0 )
{
point to = dir * (ra / (ra + rb));
c = circle(a.o + to,r);
return 1 ;
}
else
{
// r1^2 - l1^2 = r2^2 - l2^2
// l1 + l2 = l
// wtf
double tempto = (sqr(ra) - sqr(rb) + sqr(dis)) / ( 2.0 * dis);
point to = dir * (tempto / dis);
point temp = (a.o + to);
point per = to.ver();
double rate = sqrt(sqr(ra) - to.norm2()) / per.norm();
per = per * rate;
point per2 = per.rev();
c = circle(temp + per,r);
d = circle(temp + per2,r);
return 2 ;
}
}
// we judge three points on the same line or not
bool oneline(point a,point b,point c){ return sgn((a - b) ^ (a - c)) == 0 ;}
char opt[ 1000 ];
char type[][ 1000 ] = { " CircumscribedCircle " , " InscribedCircle " , " TangentLineThroughPoint " , " CircleThroughAPointAndTangentToALineWithRadius " , " CircleTangentToTwoLinesWithRadius " , " CircleTangentToTwoDisjointCirclesWithRadius " };
int main()
{
while (scanf( " %s " ,opt) == 1 )
{
int mark = - 1 ;
for ( int i = 0 ;i < 6 ;i ++ )
{
if (strcmp(opt,type[i]) == 0 )
{
mark = i;
break ;
}
}
if (mark == 0 )
{
for ( int i = 0 ;i < 3 ;i ++ )
{
double x,y;
scanf( " %lf %lf " , & x, & y);
p[i] = point(x,y);
}
circle ans = circle(p[ 0 ],p[ 1 ],p[ 2 ]);
printf( " (%.6lf,%.6lf,%.6lf)\n " ,ans.o.x + 1e - 10 ,ans.o.y + 1e - 10 ,ans.r + 1e - 10 );
}
else if (mark == 1 )
{
for ( int i = 0 ;i < 3 ;i ++ )
{
double x,y;
scanf( " %lf %lf " , & x, & y);
p[i] = point(x,y);
}
circle ans = inscribed(p[ 0 ],p[ 1 ],p[ 2 ]);
printf( " (%.6lf,%.6lf,%.6lf)\n " ,ans.o.x + 1e - 10 ,ans.o.y + 1e - 10 ,ans.r + 1e - 10 );
}
else if (mark == 2 )
{
double x,y,r;
scanf( " %lf %lf %lf " , & x, & y, & r);
circle o = circle(point(x,y),r);
scanf( " %lf %lf " , & x, & y);
double t1,t2;
point p = point(x,y);
if (o. in (p))
{
if (o.inandon(p))
{
o.tangentline(p,t1,t2, 1 );
printf( " [%.6lf]\n " ,t1 + 1e - 10 );
}
else
puts( " [] " );
}
else
{
o.tangentline(p,t1,t2, 2 );
if (sgn(t1 - t2) > 0 )
swap(t1,t2);
printf( " [%.6lf,%.6lf]\n " ,t1 + 1e - 10 ,t2 + 1e - 10 );
}
}
else if (mark == 3 )
{
double x,y;
for ( int i = 0 ;i < 3 ;i ++ )
{
scanf( " %lf %lf " , & x, & y);
p[i] = point(x,y);
}
double r;
scanf( " %lf " , & r);
circle a,b;
int mod = onelineonepoint(p[ 0 ],line(p[ 1 ],p[ 2 ] - p[ 1 ]),r,a,b);
if (mod == 0 )
puts( " [] " );
else if (mod == 1 )
printf( " [(%.6lf,%.6lf)]\n " ,a.o.x + 1e - 10 ,a.o.y + 1e - 10 );
else
{
if (b.o < a.o)
swap(a,b);
printf( " [(%.6lf,%.6lf),(%.6lf,%.6lf)]\n " ,a.o.x + 1e - 10 ,a.o.y + 1e - 10 ,b.o.x + 1e - 10 ,b.o.y + 1e - 10 );
}
}
else if (mark == 4 )
{
double x,y,r;
for ( int i = 0 ;i < 4 ;i ++ )
{
scanf( " %lf %lf " , & x, & y);
p[i] = point(x,y);
}
scanf( " %lf " , & r);
twolineoneradius(line(p[ 0 ],p[ 1 ] - p[ 0 ]),line(p[ 2 ],p[ 3 ] - p[ 2 ]),r);
sort(four + 1 ,four + 5 ,cmpcircle);
putchar( ' [ ' );
for ( int i = 1 ;i <= 4 ;i ++ )
printf( " (%.6lf,%.6lf)%c " ,four[i].o.x + 1e - 10 ,four[i].o.y + 1e - 10 ,i == 4 ? ' ] ' : ' , ' );
puts( "" );
}
else if (mark == 5 )
{
double x,y,r;
scanf( " %lf %lf %lf " , & x, & y, & r);
circle a(point(x,y),r);
scanf( " %lf %lf %lf " , & x, & y, & r);
circle b(point(x,y),r);
scanf( " %lf " , & r);
circle c,d;
int mod = twocircle(a,b,r,c,d);
if (mod == 0 )
puts( " [] " );
else if (mod == 1 )
printf( " [(%.6lf,%.6lf)]\n " ,c.o.x + 1e - 10 ,c.o.y + 1e - 10 );
else
{
if (d.o < c.o)
swap(c,d);
printf( " [(%.6lf,%.6lf),(%.6lf,%.6lf)]\n " ,c.o.x + 1e - 10 ,c.o.y + 1e - 10 ,d.o.x + 1e - 10 ,d.o.y + 1e - 10 );
}
}
}
}
point class && line class && circle class
Many things about circle and so on
WTF
*/
#include < iostream >
#include < cstdio >
#include < algorithm >
#include < cstring >
#include < cmath >
using namespace std;
#define maxn 1005
#define sqr(x) ((x) * (x))
int n;
const double eps = 1e - 8 ;
const double pi = acos( - 1.0 );
int sgn( double x)
{
return fabs(x) < eps ? 0 : x < - eps ? - 1 : 1 ;
}
struct point
{
double x,y;
point(){}
point( double a, double b):x(a),y(b){}
point operator - (point p){ return point(x - p.x,y - p.y);}
point operator + (point p){ return point(x + p.x,y + p.y);}
double norm(){ return sqrt(sqr(x) + sqr(y));}
double norm2(){ return sqr(x) + sqr(y);}
double operator * (point p){ return x * p.x + y * p.y;}
point operator * ( double a){ return point(x * a,y * a);}
double operator ^ (point p){ return x * p.y - y * p.x;}
bool operator == (point p){ return sgn(x - p.x) == 0 && sgn(y - p.y) == 0 ;}
bool operator < ( const point & p){ return sgn(x - p.x) < 0 || (sgn(x - p.x) == 0 && sgn(y - p.y) < 0 );}
point rev(){ return point( - x, - y);}
point ver(){ return point(y, - x);}
point unit(){ return point(x / norm(),y / norm());}
point rotate( double theta) // the rotate function for vector to rotate
{ // in counter-clockwise direction
return point(x * cos(theta) - y * sin(theta),x * sin(theta) + y * cos(theta));
}
}p[maxn];
struct line
{
point p,k;
line(){}
// MIND THIS!!!!!
line(point a,point b):p(a),k(b){} // a is the fixed point,k is the directed vector
line rotate( double theta){line l;l.p = p;l.k = k.rotate(theta); return l;}
bool on(point q){ return sgn((q - p) ^ k) == 0 ;}
// move the line acording to the parpendicular-direction with offset distance
line move( double offset) // to which direction??
{ // every time we use this,we can try the bi-direction
point vec = k.ver();
vec = vec.unit() * offset;
point q = p + vec;
return line(q,k);
}
// distance from a point to a line
double dis(point q)
{
point a = p,b = a + k;
return fabs((a - q) ^ (b - q)) / k.norm();
}
// cast the point to the line and find the pedal
/*
by construct the line through the 'q' parallel to the origin line
calc the lq.p 's vector to 'q'
add it onto the origin line's p
*/
point cast(point q) // something wrong
{
double d = line(p,k).dis(q);
line lq = line(p,k).move(d);
point vec;
if ( ! lq.on(q))
lq = line(p,k).move( - d);
vec = q - lq.p;
return p + vec;
}
// calc the symmetrical point of the given one againt the given line
point sym(point q)
{
point c = line(p,k).cast(q);
point vec = c - q;
return c + vec;
}
// copied from some big cow
// by vector product and "division point"
int cross(line q,point & ans)
{
point a = p,b = p + k,c = q.p,d = q.p + q.k;
ans = d;
double rate = ((b - a) ^ (a - d)) / ((b - a) ^ (c - d));
ans = ans + ((c - d) * rate);
}
};
struct circle
{
point o;
double r;
circle(){}
circle(point _o, double _r):o(_o),r(_r){}
// by two points to calc the minimum circle
circle(point a,point b)
{
o = (a + b) * 0.5 ;
r = (a - o).norm();
}
// give three points (not on the same line)to calc the decided circle
circle(point a,point b,point c)
{
point m1 = (a + b) * 0.5 ,m2 = (b + c) * 0.5 ;
line l1 = line(m1,(b - a).ver()),l2 = line(m2,(c - b).ver());
l1.cross(l2,o);
r = (a - o).norm();
}
// judge a point in or on the circle or not
bool in (point x)
{
return sgn((x - o).norm() - r) <= 0 ;
}
// judge a point on the circular of the circle or not
bool inandon(point x)
{
return sgn((x - o).norm() - r) == 0 ;
}
// give a point and a cirlce,calc the two tangent line (just angles)
// by rotation ::mode 1
// if the point p is on the circular of the circle
// just output one tangentline ::mode 2
void tangentline(point p, double & th1, double & th2, int mode)
{
double alpha = atan2(o.y - p.y,o.x - p.x);
if (mode == 1 )
{
th1 = alpha + pi * 0.5 ;
if (sgn(th1 - pi) >= 0 )
th1 -= pi;
else if (sgn(th1) < 0 )
th1 += pi;
th1 = th1 / pi * 180.0 ;
}
else
{
// circle center and point p 's connected line 's angle
double theta = asin(r / (p - o).norm());
th1 = alpha + theta;
while (sgn(th1 - pi) >= 0 )
th1 -= pi;
while (sgn(th1) < 0 )
th1 += pi;
th2 = alpha - theta;
while (sgn(th2 - pi) >= 0 )
th2 -= pi;
while (sgn(th2) < 0 )
th2 += pi;
th1 = th1 / pi * 180.0 ;
th2 = th2 / pi * 180.0 ;
}
}
};
// copied from some big cow
// to calculate the insribed circle of a triangle
circle inscribed(point a,point b,point c)
{
point a1 = a + (b - a).unit() + (c - a).unit(),b1 = b + (a - b).unit() + (c - b).unit();
point ans;
line(a,a1 - a).cross(line(b,b1 - b),ans);
double r = line(a,b - a).dis(ans);
return circle(ans,r);
}
int onelineonepoint(point p,line l, double r,circle & a,circle & b)
{
double d = l.dis(p);
if (sgn(d - 2.0 * r) > 0 )
return 0 ;
else if (sgn(d - 2.0 * r) == 0 )
{
point c = l.cast(p);
a = circle((c + p) * 0.5 ,r);
return 1 ;
}
else if (sgn(d - 2.0 * r) < 0 && sgn(d) > 0 )
{
double det,theta;
det = d - r;
theta = acos(det / r);
point c = l.cast(p);
point to = c - p;
to = to.unit() * r;
point vec1 = to.rotate(theta),vec2 = to.rotate( - theta);
a = circle(p + vec1,r);
b = circle(p + vec2,r);
return 2 ;
}
else if (sgn(d) == 0 ) // the point is on the line
{
point per = l.k.ver();
per = per.unit() * r;
a = circle(p + per,r);
b = circle(p + per.rev(),r);
return 2 ;
}
}
// use two cross lines and one radius to calc four circles
// circle - answer array
circle four[ 10 ];
// use the center of circle to compare circles
bool cmpcircle(circle a,circle b)
{
return a.o < b.o;
}
void twolineoneradius(line a,line b, double r)
{
line A[ 2 ],B[ 2 ];
A[ 0 ] = a.move(r),A[ 1 ] = a.move( - r);
B[ 0 ] = b.move(r),B[ 1 ] = b.move( - r);
int cnt = 1 ;
for ( int i = 0 ;i < 2 ;i ++ )
for ( int j = 0 ;j < 2 ;j ++ )
{
point temp;
A[i].cross(B[j],temp);
four[cnt ++ ] = circle(temp,r);
}
}
// use two disjoint circle to calc one or two new circles tangent to them with given 'r'
// not in the middle line !!!!
int twocircle(circle a,circle b, double r,circle & c,circle & d)
{
point dir = (b.o - a.o);
double dis = dir.norm();
double len = dis - a.r - b.r;
double ra = r + a.r,rb = r + b.r;
if (sgn(len - 2.0 * r) > 0 )
return 0 ;
else if (sgn(len - 2.0 * r) == 0 )
{
point to = dir * (ra / (ra + rb));
c = circle(a.o + to,r);
return 1 ;
}
else
{
// r1^2 - l1^2 = r2^2 - l2^2
// l1 + l2 = l
// wtf
double tempto = (sqr(ra) - sqr(rb) + sqr(dis)) / ( 2.0 * dis);
point to = dir * (tempto / dis);
point temp = (a.o + to);
point per = to.ver();
double rate = sqrt(sqr(ra) - to.norm2()) / per.norm();
per = per * rate;
point per2 = per.rev();
c = circle(temp + per,r);
d = circle(temp + per2,r);
return 2 ;
}
}
// we judge three points on the same line or not
bool oneline(point a,point b,point c){ return sgn((a - b) ^ (a - c)) == 0 ;}
char opt[ 1000 ];
char type[][ 1000 ] = { " CircumscribedCircle " , " InscribedCircle " , " TangentLineThroughPoint " , " CircleThroughAPointAndTangentToALineWithRadius " , " CircleTangentToTwoLinesWithRadius " , " CircleTangentToTwoDisjointCirclesWithRadius " };
int main()
{
while (scanf( " %s " ,opt) == 1 )
{
int mark = - 1 ;
for ( int i = 0 ;i < 6 ;i ++ )
{
if (strcmp(opt,type[i]) == 0 )
{
mark = i;
break ;
}
}
if (mark == 0 )
{
for ( int i = 0 ;i < 3 ;i ++ )
{
double x,y;
scanf( " %lf %lf " , & x, & y);
p[i] = point(x,y);
}
circle ans = circle(p[ 0 ],p[ 1 ],p[ 2 ]);
printf( " (%.6lf,%.6lf,%.6lf)\n " ,ans.o.x + 1e - 10 ,ans.o.y + 1e - 10 ,ans.r + 1e - 10 );
}
else if (mark == 1 )
{
for ( int i = 0 ;i < 3 ;i ++ )
{
double x,y;
scanf( " %lf %lf " , & x, & y);
p[i] = point(x,y);
}
circle ans = inscribed(p[ 0 ],p[ 1 ],p[ 2 ]);
printf( " (%.6lf,%.6lf,%.6lf)\n " ,ans.o.x + 1e - 10 ,ans.o.y + 1e - 10 ,ans.r + 1e - 10 );
}
else if (mark == 2 )
{
double x,y,r;
scanf( " %lf %lf %lf " , & x, & y, & r);
circle o = circle(point(x,y),r);
scanf( " %lf %lf " , & x, & y);
double t1,t2;
point p = point(x,y);
if (o. in (p))
{
if (o.inandon(p))
{
o.tangentline(p,t1,t2, 1 );
printf( " [%.6lf]\n " ,t1 + 1e - 10 );
}
else
puts( " [] " );
}
else
{
o.tangentline(p,t1,t2, 2 );
if (sgn(t1 - t2) > 0 )
swap(t1,t2);
printf( " [%.6lf,%.6lf]\n " ,t1 + 1e - 10 ,t2 + 1e - 10 );
}
}
else if (mark == 3 )
{
double x,y;
for ( int i = 0 ;i < 3 ;i ++ )
{
scanf( " %lf %lf " , & x, & y);
p[i] = point(x,y);
}
double r;
scanf( " %lf " , & r);
circle a,b;
int mod = onelineonepoint(p[ 0 ],line(p[ 1 ],p[ 2 ] - p[ 1 ]),r,a,b);
if (mod == 0 )
puts( " [] " );
else if (mod == 1 )
printf( " [(%.6lf,%.6lf)]\n " ,a.o.x + 1e - 10 ,a.o.y + 1e - 10 );
else
{
if (b.o < a.o)
swap(a,b);
printf( " [(%.6lf,%.6lf),(%.6lf,%.6lf)]\n " ,a.o.x + 1e - 10 ,a.o.y + 1e - 10 ,b.o.x + 1e - 10 ,b.o.y + 1e - 10 );
}
}
else if (mark == 4 )
{
double x,y,r;
for ( int i = 0 ;i < 4 ;i ++ )
{
scanf( " %lf %lf " , & x, & y);
p[i] = point(x,y);
}
scanf( " %lf " , & r);
twolineoneradius(line(p[ 0 ],p[ 1 ] - p[ 0 ]),line(p[ 2 ],p[ 3 ] - p[ 2 ]),r);
sort(four + 1 ,four + 5 ,cmpcircle);
putchar( ' [ ' );
for ( int i = 1 ;i <= 4 ;i ++ )
printf( " (%.6lf,%.6lf)%c " ,four[i].o.x + 1e - 10 ,four[i].o.y + 1e - 10 ,i == 4 ? ' ] ' : ' , ' );
puts( "" );
}
else if (mark == 5 )
{
double x,y,r;
scanf( " %lf %lf %lf " , & x, & y, & r);
circle a(point(x,y),r);
scanf( " %lf %lf %lf " , & x, & y, & r);
circle b(point(x,y),r);
scanf( " %lf " , & r);
circle c,d;
int mod = twocircle(a,b,r,c,d);
if (mod == 0 )
puts( " [] " );
else if (mod == 1 )
printf( " [(%.6lf,%.6lf)]\n " ,c.o.x + 1e - 10 ,c.o.y + 1e - 10 );
else
{
if (d.o < c.o)
swap(c,d);
printf( " [(%.6lf,%.6lf),(%.6lf,%.6lf)]\n " ,c.o.x + 1e - 10 ,c.o.y + 1e - 10 ,d.o.x + 1e - 10 ,d.o.y + 1e - 10 );
}
}
}
}
å