在 C# 中,可以使用最小二乘法来实现多点拟合圆心计算。以下是一个示例代码:

using System;

namespace CircleFitting
{
    class Program
    {
        static void Main(string[] args)
        {
            // 输入多个点的坐标
            double[,] points = new double[,] 
            {
                {1, 1},
                {2, 3},
                {3, 5},
                {4, 7}
            };

            // 计算多点拟合圆心
            double centerX, centerY, radius;
            FitCircle(points, out centerX, out centerY, out radius);

            Console.WriteLine('圆心坐标:({0}, {1})', centerX, centerY);
            Console.WriteLine('半径:{0}', radius);

            Console.ReadLine();
        }

        static void FitCircle(double[,] points, out double centerX, out double centerY, out double radius)
        {
            int n = points.GetLength(0); // 点的数量

            // 构造系数矩阵A和常数向量b
            double[,] A = new double[n, 3];
            double[,] b = new double[n, 1];

            for (int i = 0; i < n; i++)
            {
                double x = points[i, 0];
                double y = points[i, 1];

                A[i, 0] = 2 * x;
                A[i, 1] = 2 * y;
                A[i, 2] = 1;

                b[i, 0] = x * x + y * y;
            }

            // 使用最小二乘法求解Ax=b的最小二乘解
            Matrix aMatrix = new Matrix(A);
            Matrix bMatrix = new Matrix(b);
            Matrix xMatrix = aMatrix.SolveLeastSquares(bMatrix);

            centerX = xMatrix[0, 0];
            centerY = xMatrix[1, 0];
            radius = Math.Sqrt(centerX * centerX + centerY * centerY + xMatrix[2, 0]);
        }
    }

    class Matrix
    {
        private double[,] data;
        public int RowCount { get; }
        public int ColumnCount { get; }

        public Matrix(double[,] data)
        {
            this.data = data;
            RowCount = data.GetLength(0);
            ColumnCount = data.GetLength(1);
        }

        public double this[int i, int j]
        {
            get { return data[i, j]; }
            set { data[i, j] = value; }
        }

        public Matrix SolveLeastSquares(Matrix b)
        {
            // 使用QR分解求解最小二乘解
            Matrix qr = QRDecomposition();
            Matrix q = qr.GetQMatrix();
            Matrix r = qr.GetRMatrix();

            Matrix bPrime = q.Transpose() * b;

            Matrix x = new Matrix(new double[ColumnCount, 1]);

            for (int i = ColumnCount - 1; i >= 0; i--)
            {
                double sum = 0;
                for (int j = i + 1; j < ColumnCount; j++)
                {
                    sum += r[i, j] * x[j, 0];
                }
                x[i, 0] = (bPrime[i, 0] - sum) / r[i, i];
            }

            return x;
        }

        private Matrix QRDecomposition()
        {
            Matrix q = new Matrix(new double[RowCount, ColumnCount]);
            Matrix r = new Matrix(new double[ColumnCount, ColumnCount]);

            Matrix a = Clone();
            for (int k = 0; k < ColumnCount; k++)
            {
                double norm = 0;
                for (int i = 0; i < RowCount; i++)
                {
                    norm += a[i, k] * a[i, k];
                }
                norm = Math.Sqrt(norm);

                r[k, k] = norm;

                for (int i = 0; i < RowCount; i++)
                {
                    q[i, k] = a[i, k] / norm;
                }

                for (int j = k + 1; j < ColumnCount; j++)
                {
                    double dotProduct = 0;
                    for (int i = 0; i < RowCount; i++)
                    {
                        dotProduct += q[i, k] * a[i, j];
                    }

                    r[k, j] = dotProduct;

                    for (int i = 0; i < RowCount; i++)
                    {
                        a[i, j] -= dotProduct * q[i, k];
                    }
                }
            }

            return new Matrix[] { q, r };
        }

        public Matrix Transpose()
        {
            double[,] transposedData = new double[ColumnCount, RowCount];
            for (int i = 0; i < ColumnCount; i++)
            {
                for (int j = 0; j < RowCount; j++)
                {
                    transposedData[i, j] = data[j, i];
                }
            }
            return new Matrix(transposedData);
        }

        public Matrix GetQMatrix()
        {
            Matrix qr = QRDecomposition();
            return qr[0];
        }

        public Matrix GetRMatrix()
        {
            Matrix qr = QRDecomposition();
            return qr[1];
        }

        public Matrix Clone()
        {
            double[,] clonedData = new double[RowCount, ColumnCount];
            Array.Copy(data, clonedData, data.Length);
            return new Matrix(clonedData);
        }
    }
}

在上面的代码中,我们首先定义了一个FitCircle方法,该方法接收一个多维数组points,其中存储了多个点的坐标。然后,我们使用最小二乘法来拟合圆心。

FitCircle方法中,我们首先根据多个点的坐标构造了系数矩阵A和常数向量b。然后,我们使用Matrix类来实现最小二乘法,该类用于进行矩阵运算。我们使用QR分解来求解最小二乘解,然后计算出圆心坐标和半径。

最后,我们在Main方法中定义了一个示例点集,然后调用FitCircle方法来计算圆心坐标和半径,并将结果输出到控制台。

希望这个示例能帮助到你!

C# 最小二乘法实现多点拟合圆心计算

原文地址: https://www.cveoy.top/t/topic/AMQ 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录