三角形的外切圆

两种方法:

方法一:

我们设一个圆的圆心坐标为 (x0,y0),半径为 r。那么这个圆的方程可以写为:

在这个圆上随便取三个点,设这三个点的坐标分别是 (x1,y1),(x2,y2),(x3,y3)。那么有:

公式(1)(2)相减,(1)(3)相减之后经过化简可以得到:

x0,y0有唯一解的条件是系数行列式不为 0: 

简单变变型也就是: 

这样写几何含义就很明显了,三点不能共线。

得出答案:

有了 x0 和 y0 的值后,带入(1) 式就可以得到r的值。至此,三点确定圆的问题就解决了。


#include<iostream>
#include<cstdio>
#include<cmath>

using namespace std;

const double eps=1e-10;

struct point{
    double x,y;
    point(){}
    point(double _x,double _y){x=_x;y=_y;}
};
point pt1,pt2,pt3;
double radius;

double hypot(double a,double b)
{
    return sqrt(a*a+b*b);
}

point tcircle()
{
    double x1=pt1.x,x2=pt2.x,x3=pt3.x;
    double y1=pt1.y,y2=pt2.y,y3=pt3.y;
    double a=x1-x2;
    double b=y1-y2;
    double c=x1-x3;
    double d=y1-y3;
    double e=((x1*x1-x2*x2)+(y1*y1-y2*y2))/2.0;
    double f=((x1*x1-x3*x3)+(y1*y1-y3*y3))/2.0;
    double det=b*c-a*d;
    if(fabs(det)<eps){
        radius=-1;
        return point(0,0);
    }
    double x0=-(d*e-b*f)/det;
    double y0=-(a*f-c*e)/det;
    radius=hypot(x1-x0,y1-y0);
    return point(x0,y0);
}

int main()
{
    scanf("%lf%lf%lf%lf%lf%lf",&pt1.x,&pt1.y,&pt2.x,&pt2.y,&pt3.x,&pt3.y);
    point ans=tcircle();
    printf("%f %f %f\n",ans.x,ans.y,radius);
    return 0;
}

第二种方法:最常用的方法:

了解向量旋转 
x’=xcosθ-ysinθ 
y’=xsinθ+ycosθ

附上代码:


#include<iostream>
#include<cstdio>
#include<cmath>

using namespace std;

const double eps=1e-10;

struct point{
    double x,y;
    point(){}
    point(double _x,double _y){x=_x;y=_y;}
    point operator * (double k){
        return point(x*k,y*k);
    }
    point operator + (point p){
        return point(x+p.x,y+p.y);
    }
    point operator - (point p){
        return point(x-p.x,y-p.y);
    }
};
point pt1,pt2,pt3,ans;
double radius;

double cross(point a,point b)
{
    return a.x*b.y-a.y*b.x;
}

double hypot(double a,double b)
{
    return sqrt(a*a+b*b);
}

point rotate(point a)
{
    return point(-a.y,a.x);
}

point getmid(point a,point b)
{
    return point((a.x+b.x)/2,(a.y+b.y)/2);
}

point circlein()
{
    point v1=pt2-pt1,v2=pt1-pt3;
    v1=rotate(v1),v2=rotate(v2);
    point p1=getmid(pt1,pt2),p2=getmid(pt1,pt3);
    point u=p1-p2;
    double t=cross(v2,u)/cross(v1,v2);
    ans=p1+v1*t;
    double x1=pt1.x,y1=pt1.y;
    radius=hypot(x1-ans.x,y1-ans.y);
}

int main()
{
    scanf("%lf%lf%lf%lf%lf%lf",&pt1.x,&pt1.y,&pt2.x,&pt2.y,&pt3.x,&pt3.y);
    circlein();
    printf("%f %f %f\n",ans.x,ans.y,radius);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhouzi2018/article/details/82026242