由圆上三点确定圆心和半径(附Python&Matlab程序)

更多阅读:sppy.site

背景

如何计算曲线   y ( x )   ~y(x)~  y(x) 上的曲率,而曲线是由若干离散点构成。我的第一反应是根据离散点差分得到一阶导数   y ′   ~y'~  y 和二阶导数   y ′ ′   ~y''~  y ,然后由下式计算
k = ∣ y ′ ′ ∣ ( 1 + y ′ 2 ) 3 / 2 (0a) \tag{0a} k=\frac{|y''|}{(1+y'^2)^{3/2}} k=(1+y2)3/2y(0a)

曲线的凹凸方向则由   y ′ ′   ~y''~  y 的符号确定。

后面,我想到了可以根据曲率的几何意义来计算,即
k = 1 r (0b) \tag{0b} k=\frac{1}{r} k=r1(0b)

式中, r   r~ r 是该点的曲率半径,可以通过该点及其两个相邻点得到(不共线的三点确定一个圆)。

公式

平面三点

三个已知点的坐标分别记为   ( x 1 , y 1 ) ~(x_1,y_1)  (x1,y1) ( x 2 , y 2 ) (x_2,y_2) (x2,y2) ( x 3 , y 3 ) (x_3,y_3) (x3,y3),圆的一般方程可写为二次多项式,即
A ( x 2 + y 2 ) + B x + C y + D = 0 (1a) \tag{1a} A(x^2+y^2)+Bx+Cy+D=0 A(x2+y2)+Bx+Cy+D=0(1a)

将式 ( 1 a ) (1\mathrm{a}) (1a)变形可得圆的标准方程,即
( x + B 2 A ) 2 + ( y + C 2 A ) 2 = B 2 + C 2 − 4 A D 4 A 2 (1b) \tag{1b} \bigg(x+\frac{B}{2A}\bigg)^2+\bigg(y+\frac{C}{2A}\bigg)^2=\frac{B^2+C^2-4AD}{4A^2} (x+2AB)2+(y+2AC)2=4A2B2+C24AD(1b)

将三个已知点代入式 ( 1 a ) (1\mathrm{a}) (1a),可得关于   A ~A  A B B B C C C D   D~ D 的齐次线性方程组,即
[ x 2 + y 2 x y 1 x 1 2 + y 1 2 x 1 y 1 1 x 2 2 + y 2 2 x 2 y 2 1 x 3 2 + y 3 2 x 3 y 3 1 ] ⋅ [ A B C D ] = [ 0 0 0 0 ] (2) \tag{2} \begin{bmatrix} x^2+y^2 & x & y & 1 \\[3pt] x^2_1+y^2_1 & x_1 & y_1 & 1 \\[3pt] x^2_2+y^2_2 & x_2 & y_2 & 1 \\[3pt] x^2_3+y^2_3 & x_3 & y_3 & 1 \end{bmatrix} \cdot \begin{bmatrix} A\\ B\\ C\\ D \end{bmatrix} = \begin{bmatrix} 0\\ 0\\ 0\\ 0 \end{bmatrix} x2+y2x12+y12x22+y22x32+y32xx1x2x3yy1y2y31111ABCD=0000(2)

显然在三点不共线的前提下,该齐次线性方程组有非零解,其等价于系数矩阵不满秩,即有
∣ x 2 + y 2 x y 1 x 1 2 + y 1 2 x 1 y 1 1 x 2 2 + y 2 2 x 2 y 2 1 x 3 2 + y 3 2 x 3 y 3 1 ∣ = 0 (3) \tag{3} \begin{vmatrix} x^2+y^2 & x & y & 1 \\[3pt] x^2_1+y^2_1 & x_1 & y_1 & 1 \\[3pt] x^2_2+y^2_2 & x_2 & y_2 & 1 \\[3pt] x^2_3+y^2_3 & x_3 & y_3 & 1 \end{vmatrix} = 0 x2+y2x12+y12x22+y22x32+y32xx1x2x3yy1y2y31111=0(3)

将式 ( 3 ) (3) (3)展开,并与式 ( 1 ) (1) (1)对比可得四个系数,即
A = + ∣ x 1 y 1 1 x 2 y 2 1 x 3 y 3 1 ∣ (4a) \tag{4a} A=+\begin{vmatrix} x_1 & y_1 & 1 \\ x_2 & y_2 & 1 \\ x_3 & y_3 & 1 \end{vmatrix} A=+x1x2x3y1y2y3111(4a)

B = − ∣ x 1 2 + y 1 2 y 1 1 x 2 2 + y 2 2 y 2 1 x 3 2 + y 3 2 y 3 1 ∣ (4b) \tag{4b} B=-\begin{vmatrix} x^2_1+y^2_1 & y_1 & 1 \\[3pt] x^2_2+y^2_2 & y_2 & 1 \\[3pt] x^2_3+y^2_3 & y_3 & 1 \end{vmatrix} B=x12+y12x22+y22x32+y32y

  • 22
    点赞
  • 97
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是用 C++ 实现已知圆上三点圆心半径的代码: ```cpp #include <iostream> #include <cmath> using namespace std; struct Point { double x, y; }; // 计算两点之间的距离 double distance(Point p1, Point p2) { return sqrt(pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2)); } // 已知圆上三点圆心半径 void circleFromPoints(Point p1, Point p2, Point p3, Point& center, double& radius) { double a = distance(p1, p2); double b = distance(p2, p3); double c = distance(p3, p1); double s = (a + b + c) / 2; double area = sqrt(s * (s - a) * (s - b) * (s - c)); double A = asin((p2.y - p1.y) / a); double B = asin((p3.y - p1.y) / c); double x = area * (cos(A) + cos(B)) / (sin(A) + sin(B)) / 2 + p1.x; double y = (p2.y - p1.y) / (p2.x - p1.x) * (x - (p1.x + p2.x) / 2) + (p1.y + p2.y) / 2; center.x = x; center.y = y; radius = distance(center, p1); } int main() { Point p1 = { 0, 0 }; Point p2 = { 1, 1 }; Point p3 = { 2, 0 }; Point center; double radius; circleFromPoints(p1, p2, p3, center, radius); cout << "Center: (" << center.x << ", " << center.y << ")" << endl; cout << "Radius: " << radius << endl; return 0; } ``` 在本例中,我们定义了一个 `Point` 结构体来表示点的坐标,并定义了一个 `distance` 函数来计算两点之间的距离。`circleFromPoints` 函数接收三个点作为参数,并计算出圆心半径,结果保存在 `center` 和 `radius` 变量中。主函数中调用 `circleFromPoints` 函数,并输出圆心半径的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值