Решение матричных уравнений - круг из 3 точек - PullRequest
0 голосов
/ 20 июня 2020

enter image description here

I'm looking for a high precision solution to find the center point of a circle from 3 data points on a canvas (x,y). I found this example in the attached screenshot above, now I'm using the Math.NET package to solve the equation and I'm comparing the results against this online tool: https://planetcalc.com/8116/.

Однако, когда я вычисляю радиус, он полностью отключен, и часто это отрицательное число!

using MathNet.Numerics.LinearAlgebra.Double.Solvers;
using MathNet.Numerics.LinearAlgebra.Double;
using System;

namespace ConsoleAppTestBed
{
  class Program
  {
    static void Main(string[] args)
    {
        var dataPoints = new double[,]
        {

            { 5, 80 },
            { 20, 100 },
            { 40, 140 }
        };


        var fitter = new CircleFitter();
        var result = fitter.Fit(dataPoints);

        var x = -result[0];
        var y = -result[1];
        var c = result[2];

        Console.WriteLine("Center Point:");
        Console.WriteLine(x);
        Console.WriteLine(y);
        Console.WriteLine(c);

        //// (x^2 + y^2 - c^2)
        var radius = Math.Pow(x, 2) + Math.Pow(y, 2) - Math.Pow(c, 2);
        //// sqrt((x^2 + y^2 - c^2))
        radius =  Math.Sqrt(radius);
        Console.WriteLine("Radius:");
        Console.WriteLine(radius);
        Console.ReadLine();
    }

    public class CircleFitter
    {
        public double[] Fit(double[,] v)
        {
            var xy1 = new double[] { v[0,0], v[0,1] };
            var xy2= new double[] { v[1, 0], v[1, 1] };
            var xy3 = new double[] { v[2, 0], v[2, 1] };

            // Create Left Side Matrix of Equation
            var a = CreateLeftSide_(xy1);
            var b = CreateLeftSide_(xy2);
            var c = CreateLeftSide_(xy3);
            var matrixA = DenseMatrix.OfArray(new[,] 
            {
                { a[0], a[1], a[2] },
                { b[0], b[1], b[2] },
                { c[0], c[1], c[2] }
            });

            // Create Right Side Vector of Equation
            var d = CreateRightSide_(xy1);
            var e = CreateRightSide_(xy2);
            var f = CreateRightSide_(xy3);
            double[] vector = { d, e, f };
            var vectorB =  Vector<double>.Build.Dense(vector);

            // Solve Equation
            var r = matrixA.Solve(vectorB);
            var result = r.ToArray();

            return result;
        }

        //2x, 2y, 1
        public double[] CreateLeftSide_(double[] d) 
        {
            return new double[] { (2 * d[0]), (2 * d[1]) , 1};
        
        }

        // -(x^2 + y^2)
        public double CreateRightSide_(double[] d) 
        { 
            return -(Math.Pow(d[0], 2) + Math.Pow(d[1], 2));

        }
    }
  }

}

Любые идеи ?

1 Ответ

0 голосов
/ 21 июня 2020

Я не уверен, как можно получить отрицательный результат с помощью функции root квадрата, но в любом случае: в математике есть ошибка. 'c' не следует возводить в квадрат в формуле радиуса, т.е. должно быть написано:

var radius = Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2) - c);
...