基于圆弧点集推导最优拟合圆/椭圆的无矩阵算法问询
圆弧点序列的最优拟合圆(及椭圆)求解方案
需求说明
- 拥有构成圆弧的点序列,需要推导最优拟合的圆形(或椭圆形)曲线
- 分割圆弧的依据:圆弧长度范围内的角度变化相对稳定
- 偏好无矩阵的解决方案,熟练掌握C/Java/Kotlin语言,优先这类实现,也可接受伪代码或其他语言方案
最优拟合圆的Kotlin实现
感谢Renat提供的解决方案,效果极佳,以下是适配Kotlin的实现代码:
class Circle(val x: Int, val y: Int, val radius: Int) { companion object { /** * 为点集合拟合最优圆 */ fun fit(points: List<Point>): Circle { val sx = points.sumOf { it.x.toDouble() } val sy = points.sumOf { it.y.toDouble() } val sx2 = points.sumOf { it.x.toDouble() * it.x } val sy2 = points.sumOf { it.y.toDouble() * it.y } val sxy = points.sumOf { it.x.toDouble() * it.y } val sx3 = points.sumOf { it.x.toDouble() * it.x * it.x } val sy3 = points.sumOf { it.y.toDouble() * it.y * it.y } val sx2y = points.sumOf { it.x.toDouble() * it.x * it.y } val sxy2 = points.sumOf { it.x.toDouble() * it.y * it.y } val n = points.size val s11 = n * sxy - sx * sy val s20 = n * sx2 - sx * sx val s02 = n * sy2 - sy * sy val s30 = n * sx3 - sx2 * sx val s03 = n * sy3 - sy * sy2 val s21 = n * sx2y - sx2 * sy val s12 = n * sxy2 - sx * sy2 val a = ((s30 + s12)*s02 - (s03 + s21)*s11) / (2*( s20 * s02 - s11 * s11)) val b = ((s03 + s21)*s20 - (s30 + s12)*s11) / (2*( s20 * s02 - s11 * s11)) val c = (sx2 + sy2 - 2*a*sx - 2*b*sy) / n val radius = Math.sqrt(c + a*a + b*b) return Circle(a.roundToInt(), b.roundToInt(), radius.roundToInt()) } } }
补充指引
该算法基于最小二乘法实现,全程无需矩阵运算,适配需求场景。若需拟合椭圆,可搜索精准关键词:无矩阵椭圆最小二乘拟合、圆弧点集椭圆拟合算法
内容的提问来源于stack exchange,提问作者DrPhill
相关产品推荐
相关产品推荐

