三点确定一个圆的计算方法

三点确定一个圆的计算方法

 

最近在写的一个软件需要根据三个坐标点来计算一个圆。因此花了点时间推导了相关的公式。这个推导不算太难,放在这里主要是做个备忘。

 

我们设一个圆的圆心坐标为 (x 0 ,y) (x0,y)(x_0, y),半径为 r rr。那么这个圆的方程可以写为:
(x−x 0 ) 2 +(y−y 0 ) 2 =r 2  (x−x0)2+(y−y0)2=r2
(x - x_0)^2 + (y - y_0)^2 = r^2

 


在这个圆上随便取三个点,设这三个点的坐标分别是 (x 1 ,y 1 ) (x1,y1)(x_1, y_1),(x 2 ,y 2 ) (x2,y2)(x_2, y_2),(x 3 ,y 3 ) (x3,y3)(x_3, y_3)。那么有:

 

 

 

⎧ ⎩ ⎨ ⎪ ⎪ (x 1 −x 0 ) 2 +(y 1 −y 0 ) 2 =r 2 (x 2 −x 0 ) 2 +(y 2 −y 0 ) 2 =r 2 (x 3 −x 0 ) 2 +(y 3 −y 0 ) 2 =r 2  (1)(2)(3)  {(x1−x0)2+(y1−y0)2=r2(1)(x2−x0)2+(y2−y0)2=r2(2)(x3−x0)2+(y3−y0)2=r2(3)
\begin{cases}
(x_1 - x_0)^2 + (y_1-y_0)^2 = r^2 & (1)\\
(x_2 - x_0)^2 + (y_2-y_0)^2 = r^2 & (2)\\
(x_3 - x_0)^2 + (y_3-y_0)^2 = r^2 & (3)
\end{cases}

 


公式(1)(2)相减,(1)(3)相减之后经过化简可以得到:
(x 1 −x 2 )x 0 +(y 1 −y 2 )y 0 =(x 2 1 −x 2 2 )−(y 2 2 −y 2 1 )2 (x 1 −x 3 )x 0 +(y 1 −y 3 )y 0 =(x 2 1 −x 2 3 )−(y 2 3 −y 2 1 )2  (x1−x2)x0+(y1−y2)y0=(x12−x22)−(y22−y12)2(x1−x3)x0+(y1−y3)y0=(x12−x32)−(y32−y12)2
(x_1 - x_2) x_0 + (y_1- y_2) y_0 = \frac{(x_1^2-x_2^2)-(y_2^2-y_1^2)}{2}\\
(x_1 - x_3) x_0 + (y_1- y_3) y_0 = \frac{(x_1^2-x_3^2)-(y_3^2-y_1^2)}{2}\\

 


x 0 ,y 0  x0,y0x_0,y_0有唯一解的条件是系数行列式不为 0 00:
∣ ∣ ∣ (x 1 −x 2 )(x 1 −x 3 ) (y 1 −y 2 )(y 1 −y 3 ) ∣ ∣ ∣ ≠0 |(x1−x2)(y1−y2)(x1−x3)(y1−y3)|≠0
\begin{vmatrix}
(x_1 - x_2) & (y_1- y_2) \\
(x_1 - x_3) & (y_1- y_3)
\end{vmatrix} \neq 0

 


简单变变型也就是:
x 1 −x 2 y 1 −y 2  ≠x 1 −x 3 y 1 −y 3   x1−x2y1−y2≠x1−x3y1−y3
\frac{x_1 - x_2}{y_1-y_2} \neq \frac{x_1 - x_3}{y_1-y_3}

 


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

 

设:
a=x 1 −x 2 b=y 1 −y 2 c=x 1 −x 3 d=y 1 −y 3 e=(x 2 1 −x 2 2 )−(y 2 2 −y 2 1 )2 f=(x 2 1 −x 2 3 )−(y 2 3 −y 2 1 )2  a=x1−x2b=y1−y2c=x1−x3d=y1−y3e=(x12−x22)−(y22−y12)2f=(x12−x32)−(y32−y12)2a = x_1-x_2\\
b = y_1-y_2\\
c = x_1-x_3\\
d = y_1-y_3\\
e = \frac{(x_1^2-x_2^2)-(y_2^2-y_1^2)}{2}\\
f = \frac{(x_1^2-x_3^2)-(y_3^2-y_1^2)}{2}

 


那么 :
x 0 =−de−bfbc−ad y 0 =−af−cebc−ad  x0=−de−bfbc−ady0=−af−cebc−ad
x_0 = -\frac{d e-b f}{b c-a d}\\
y_0 = -\frac{a f-c e}{b c-a d}

 


有了 x 0  x0x_0 和 y 0  y0y_0 的值后,带入(1) 式就可以得到 r rr的值。至此,三点确定圆的问题就解决了。

 

下面是个 C++ 代码(用到了Qt 的 QPointF 类型):

 

 

 

    #include <math.h>
    #include <limits>
    #include <QPoint>
    #include <QDebug>
    QPointF tcircle(QPointF pt1, QPointF pt2, QPointF pt3, double &radius)
    {
        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) < 1e-5)
        {
            radius = -1;
            return QPointF(0,0);
        }

 

        double x0 = -(d * e - b * f) / det;
        double y0 = -(a * f - c * e) / det;
        radius = hypot(x1 - x0, y1 - y0);
        return QPointF(x0, y0);
    }

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值