文章目录

  • 一、2D圆弧拟合
    • 1、不经过给定起点与终点
    • 2、精确经过给定起点与终点
  • 二、3D圆弧拟合

一、2D圆弧拟合

1、不经过给定起点与终点

  平面圆的一般方程为:
x2+y2+ax+by+c=0(1)x^2 + y^2 + ax + by +c = 0\tag 1 x2+y2+ax+by+c=0(1)
  其中,a,b,c∈Ra,b,c\in Ra,b,c∈R。
  式(1)配方,可以得到:
(x+a/2)2+(x+b/2)2=a2/4+b2/4−c(2)(x + a/2)^2 + (x + b/2)^2 = a^2/4 + b^2/4 - c \tag 2 (x+a/2)2+(x+b/2)2=a2/4+b2/4−c(2)

  对于给定的一系列二维数据(xi,yi),i=0,...,n(x_i,y_i),i=0,...,n(xi​,yi​),i=0,...,n,根据式(1)可以列出n+1n+1n+1个线性方程,然后可以采用最小二乘法求解,非常简单有效。
  不经过给定起点与终点的2D圆弧拟合另一种方法可参考:最小二乘法拟合圆。

2、精确经过给定起点与终点

  有时候我们需要约束圆弧精确经过给定起点与终点,设起点坐标为(x0,y0)(x_0,y_0)(x0​,y0​),终点坐标为(xn,yn)(x_n,y_n)(xn​,yn​),则有约束等式:
{x02+y02+ax0+by0+c=0xn2+yn2+axn+byn+c=0(3)\begin{cases} x_0^2 + y_0^2 + ax_0 + by_0 +c = 0 \\ x_n^2 + y_n^2 + ax_n + by_n +c = 0 \\ \tag 3 \end{cases} {x02​+y02​+ax0​+by0​+c=0xn2​+yn2​+axn​+byn​+c=0​(3)
  (1)若起点与终点坐标重合,则式(3)退化为一个约束等式,将参数ccc的表达式代入到式(1),利用最小二乘法求解参数a,ba,ba,b,再计算参数ccc。
  (2)若x0≠xnx_0\ne x_nx0​​=xn​,根据式(3)解出参数a,ca,ca,c的表达式,然后代入到式(1),利用最小二乘法求解参数bbb,再计算参数a,ca,ca,c。
  (3)若y0≠yny_0\ne y_ny0​​=yn​,根据式(3)解出参数b,cb,cb,c的表达式,然后代入到式(1),利用最小二乘法求解参数aaa,再计算参数b,cb,cb,c。

  circle_fitting_2D.m

function [ center, R, fittingError ] = circle_fitting_2D( points, pointCount, crossStartAndEndPointFlag )
%{Function: circle_fitting_2D
Description: 2D圆弧拟合
Input: 二维点points, 点个数pointCount, 是否经过起点/终点标志位crossStartAndEndPointFlag
Output: 圆心center, 半径R, 拟合误差fittingError
Author: Marc Pony(marc_pony@163.com)
圆的方程:x^2 + y^2 + a*x + b*y +c = 0  -> (x + a/2)^2 + (x + b/2)^2 = a^2/4 + b^2/4 - c
%}
if crossStartAndEndPointFlag == 0x = points(:, 1);y = points(:, 2);A = [x, y, ones(size(x))];B = -x.^2 - y.^2;temp = A \ B;a = temp(1);b = temp(2);c = temp(3);
elsex0 = points(1, 1);y0 = points(1, 2);xn = points(pointCount, 1);yn = points(pointCount, 2);x = points(2 : pointCount - 1, 1);y = points(2 : pointCount - 1, 2);EPS = 1.0e-4;if abs(x0 - xn) < EPS && abs(y0 - yn) < EPS %起点与终点重合A = [x - x0, y - y0];B = x0^2 + y0^2 - x.^2 - y.^2;temp = A \ B;a = temp(1);b = temp(2);c = -x0^2 - y0^2 - a * x0 - b * y0;elseif abs(x0 - xn) > abs(y0 - yn)A = x * (yn - y0) / (x0 - xn) + y - (x0 * yn - xn * y0) / (x0 - xn);B = -x.^2 - y.^2 - x * (xn^2 + yn^2 - x0^2 - y0^2) / (x0 - xn) + ((xn^2 + yn^2) * x0 - (x0^2 + y0^2) * xn) / (x0 - xn);b = A \ B;P = -x0^2 - y0^2 - b * y0;Q = -xn^2 - yn^2 - b * yn;a = (P - Q) / (x0 - xn);c = -(P * xn - Q * x0) / (x0 - xn);elseA = x * (xn - x0) / (y0 - yn) + y - (y0 * xn - yn * x0) / (y0 - yn);B = -x.^2 - y.^2 - x * (yn^2 + xn^2 - y0^2 - x0^2) / (y0 - yn) + ((yn^2 + xn^2) * y0 - (y0^2 + x0^2) * yn) / (y0 - yn);a = A \ B;P = -y0^2 - x0^2 - a * x0;Q = -yn^2 - xn^2 - a * xn;b = (P - Q) / (y0 - yn);c = -(P * yn - Q * y0) / (y0 - yn);endend
endR = sqrt(a^2 / 4 + b^2 / 4 - c);
center(1) = -a / 2;
center(2) = -b / 2;
fittingError = sqrt((points(:, 1) - center(1)).^2 + (points(:, 2) - center(2)).^2) - R;end

  test_circle_fitting_2D.m

clc
clear
close all%% 绘参考圆
figure
axis([0 100 0 100])
theta = linspace(0, 2*pi, 1000);
r = 30;
x = 50 + r*cos(theta);
y = 50 + r*sin(theta);
plot(x,y,'g--')
hold on
axis equal%% 左键点击取点,按回车键退出
pos = ginput();
%pos = [pos;pos(1,1), pos(1,2)];  %起点与终点重合
pointCount = size(pos, 1);
plot(pos(1, 1), pos(1, 2), 'k+')
plot(pos(pointCount, 1), pos(pointCount, 2), 'k+')
plot(pos(2:pointCount-1, 1), pos(2:pointCount-1, 2), 'o')%% 圆最小二乘拟合
crossStartAndEndPointFlag = 1; %0:不经过给定起点与终点;  1:精确经过给定起点与终点
[ center, R, fittingError ] = circle_fitting_2D( pos, pointCount, crossStartAndEndPointFlag )x = center(1) + R * cos(theta);
y = center(2) + R * sin(theta);
plot(x, y, 'b')
plot(center(1), center(2), 'b+')
plot(center(1), center(2), 'bo')

二、3D圆弧拟合

   3D圆弧拟合可以分解两个问题:
   (1)三维点的球面拟合(见博文:最小二乘法球面拟合(附完整代码))
   (2)平面拟合
  球面拟合后,球心便为3D圆弧的圆心,平面拟合则可以得到3D圆弧所在平面的法向量,3D圆弧的方程便确定。

最小二乘法圆拟合(附完整代码)相关推荐

  1. 三次样条拟合(附完整代码)

    文章目录 一.推导步骤 二.三种不同端点约束下的三次样条拟合 1.给定起始速度 v 0 v_0 v0​与结束速度 v n v_n vn​ 2.起始位置 q 0 q_0 q0​与结束位置 q n q_n ...

  2. c++ 三次多项式拟合_线性回归进阶版,多项式线性回归讲解与实现(附完整代码)...

    每天给小编五分钟,小编用自己的代码,带你轻松学习深度学习!本文将会带你做完一个深度学习进阶版的线性回归---多项式线性回归,带你进一步掌握线性回归这一深度学习经典模型,然后在此基础上,小编将在下篇文章 ...

  3. 基于MATLAB的三维数据插值拟合与三次样条拟合算法(附完整代码)

    目录 一. 三维插值 例题1 二. 高维度插值拟合 格式一 格式二 格式三 格式四 格式五 例题2 三. 单变量三次样条插值 例题3 例题4 四. 多变量三次样条插值 例题6 一. 三维插值 首先三维 ...

  4. 基于MATLAB的二维与三维插值拟合运算(附完整代码)

    · 一. 一维插值 interp1函数在上个博客中(如下链接)已经更新了,此处再补充两个相关例题. 基于MATLAB的数据插值运算:Lagrange与Hermite算法(附完整代码)_唠嗑!的博客-C ...

  5. 吴恩达机器学习python实现(6):SVM支持向量机(文末附完整代码)

    所有的数据来源:链接:https://pan.baidu.com/s/1vTaw1n77xPPfKk23KEKARA 提取码:5gl2 1 Support Vector Machines 1.1 Pr ...

  6. php 3d animation,css3D+动画的例子(附完整代码)

    本篇文章给大家带来的内容是关于css3D+动画的例子(附完整代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 前言 最近玩了玩用css来构建3D效果,写了几个demo,所以博客总 ...

  7. Py之pygame:有趣好玩—利用pygame库实现鱼儿自动实时目标跟踪(附完整代码)

    Py之pygame:有趣好玩-利用pygame库实现鱼儿自动实时目标跟踪(附完整代码) 目录 输出结果 实现代码 输出结果 实现代码 #Py之pygame:利用pygame库实现鱼儿自动实时目标跟踪i ...

  8. c++代码好玩_Py之pygame:有趣好玩—利用pygame库实现鱼儿自动实时目标跟踪(附完整代码)...

    Py之pygame:有趣好玩-利用pygame库实现鱼儿自动实时目标跟踪(附完整代码) 目录 输出结果 实现代码 输出结果 ​ 实现代码 #Py之pygame:利用pygame库实现鱼儿自动实时目标跟 ...

  9. OpenCV基本线性变换轨迹栏的实例(附完整代码)

    OpenCV基本线性变换轨迹栏的实例 OpenCV基本线性变换轨迹栏的实例 OpenCV基本线性变换轨迹栏的实例 OpenCV基本线性变换轨迹栏的实例(附完整代码) #include "op ...

最新文章

  1. 哈工大威海c语言实验报告 第八章 无法运行程序,哈工大(威海)c语言实验报告册答案...
  2. 乌鲁木齐市计算机职业高中,乌鲁木齐职高有哪些专业
  3. java读取Properties文件及赋值
  4. C基础(31——35)
  5. (零)我为什么要写Linux学习笔记?
  6. web python 自动化是什么_Selenium 凭什么成为 Web 自动化测试的首选?(内附源码)...
  7. Uva11729 Commando War
  8. linux搜索文件内容含有星号,文本内容查找grep、文件查找find、正则匹配
  9. C#中使用多线程访问Winform问题解决方案
  10. Python练习之 对文件进行创建,然后重命名文件最近进行文件删除
  11. 调用一个Activity并返回结果
  12. 数据结构(C语言版清华严蔚敏)
  13. matlab中国官网下载,首页 - MATLAB中文论坛
  14. JavaScript阿拉伯数字“1“转中文数“一“
  15. 国产系统中标麒麟安装教程
  16. 透过西安未来人工智能计算中心,看到AI不一样的未来
  17. 7-1 婚宴座次排定
  18. Kaggle 注册问题
  19. CC3200+TB6612FNG 驱动电机实现开环控制
  20. 2019年最具影响力的技术大会 | Elastic首发中国开发者调查报告 ——百格活动

热门文章

  1. 学会制作柱形图,一眼区分工作效率差异
  2. SCIP | 数学规划求解器SCIP超详细的使用教程
  3. IE浏览器的调试工具
  4. cf723D 连通块
  5. matlab并行计算 linux,MATLAB并行计算工具箱 -- Parallel Computing Toolbox的使用
  6. Java并发基础,不怕你看不懂
  7. 对于训练时loss出现负值的情况
  8. APP数据模拟处理流程—[shell脚本]
  9. 学习记录562@公钥密码体系基本概念
  10. 【计算机毕业文章】垃圾分类系统设计与实现