C++编程中两个圆的公切线

分为包含、内割、相交、外割、分离五种情况。

为了描述方便,c2默认为大圆(如果半径相等,取一个圆),d21表示大圆的圆心指向小圆的圆心,d12表示小圆的圆心指向大圆的圆心。

包括:圆心之间的距离小于半径之差。在这种情况下,没有切线,自然也就没有切点;因为至少保证了一个切点,所以不需要考虑这种情况。

落款:两个圆心的距离等于半径之差,此时有一个唯一的切点,只需在d12方向的任意圆上取一点。

相交:两个圆的圆心之间的距离介于半径之差和半径之和之间。这个时候,只有两个共同的切线。图纸显示它们的切线位于d12旋转的两个圆上。α?角度方向,其中α可以通过半径和中心距离找到。

外切:两个圆心的距离等于半径之和,比交点多一个公切线,随便在任意圆上取一个d12方向的点。

分离:两个中心之间的距离大于半径之和,并且比相交的情况下多了两条公共切线。绘图显示,它们的切线位于圆c1的d12旋转β角的方向,和圆c2的d12旋转β角的方向,其中β可由半径和中心距求出。

输入:两个圆C1和C2的圆心坐标和半径。

c1x c1y c1r

c2x c2y c2r

输出:所有切线的坐标(一行中两条切线代表一条切线,如果是公切线则输出一条)。

# include & ltiostream & gt

使用命名空间std

使用PDD = pair & ltdouble,double & gt;

#首先定义x

#定义y秒

# define BTN(func)_ _ builtin _ # # func

PDD运算符+ (PDD a,PDD b) {

返回PDD(a.x + b.x,a . y+b . y);

}

PDD操作员- (PDD b) {

返回PDD( - b.x,-b . y);

}

PDD操作员- (PDD a,PDD b) {

返回PDD(a.x - b.x,a . y-b . y);

}

PDD运算符* (double d,PDD b) {

返回PDD(d * b.x,d * b . y);

}

PDD运算符/ (PDD a,double d) {

返回PDD(a.x / d,a . y/d);

}

//点积

双重运算符& amp(PDD a,PDD b) {

返回a . x * b . x+a . y * b . y;

}

PDD旋转(PDD a,双t) {

双成本= btn(cos)(t),Sint = BTN(sin)(t);

返回PDD(a.x * cost - a.y * sint,a . x * Sint+a . y * cost);

}

模板& lttypename T & gtT平方(常数T & ampe){ return e * e;}

牡蛎&;操作员& lt& lt(ostream & ampos,const PDD & ampp) {

返回os & lt& lt(' & lt& ltp.x & lt& lt,' & lt& ltp.y & lt& lt')';

}

int main()

{

PDD c1,C2;

double r1,R2;

CIN & gt;& gtc 1 . x & gt;& gtc 1 . y & gt;& gtr 1;

CIN & gt;& gtc2.x & gt& gtc2.y & gt& gtR2;

if(r 1 & gt;r2) swap(c1,c2),swap(r1,R2);

int sqdis =((c 1-C2)& amp;(c 1-C2));

double d = BTN(sqrt)(sqdis);

PDD e 12 =(c 1-C2)/d;

PDD v 1 = r 1 * e 12;

PDD v2 = R2 * e 12;

if(sqdis & lt;平方(r2 - r1)) {

cout & lt& lt"不存在共同的目标。"& lt& ltendl

返回0;

}

if (sqdis ==平方(r2 - r1))?{

cout & lt& ltC2+v2 & lt;& ltendl

返回0;

}

double l = d * R2/(R2-r 1);

双α= BTN(acos)(R2/l);

cout & lt& ltc1 + rotate(v1,+alpha)& lt;& lt' & lt& ltc2 + rotate(v2,+alpha)& lt;& ltendl

cout & lt& ltc1 + rotate(v1,-alpha)& lt;& lt' & lt& ltc2 + rotate(v2,-alpha)& lt;& ltendl

if (sqdis ==平方(r1 + r2))?{

cout & lt& ltC2+C2 & lt;& ltendl

}

else if(sqdis & gt;平方(r1 + r2)) {

v 1 =-v 1;

l = d * R2/(r 1+R2);

双β= BTN(acos)(R2/l);

cout & lt& ltc1 + rotate(v1,+beta)& lt;& lt' & lt& ltc2 + rotate(v2,+beta)& lt;& ltendl

cout & lt& ltc1 + rotate(v1,-beta)& lt;& lt' & lt& ltc2 + rotate(v2,-beta)& lt;& ltendl

}

返回0;

}