计算一般方程:
求解a、b、c、d、e、f六个未知数
转化为求如下方程组(矩阵、向量元素是均值):
程序中需要算线性方程组,所以得导入Math.Net数值计算包,导入过程如下:
--打开 Tools -> Nuget Package Manager -> Package Manager Console;
--在 Package Manager Console 中输入:Install-Package MathNet.Numerics。
完事后,添加划红线的引用:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Numerics;
using System.IO;
using MathNet.Numerics.LinearAlgebra.Double; //C#数值计算包,需要手动导入math.net;
struct Point
{
public double x, y, z;
public Point(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
}
class Getdata
{
public static List
{
List
List
string strline;
while (true)
{
strline = srr.ReadLine();
if (strline != null)
{
strlist.Add(strline);
}
else { break; }
}
for (int i = 0; i < strlist.Count; i++)
{
string[] strp = strlist[i].Split(' ');
Point pt = new Point(double.Parse(strp[0]), double.Parse(strp[1]), double.Parse(strp[2]));
pointlist.Add(pt);
}
return pointlist;
}
public static double[] GetC(List
{
double x1 = 0, y1 = 0, z1 = 0;
double x2 = 0, x1y1 = 0, y2 = 0, x1z1 = 0, y1z1 = 0, z2 = 0;
double x3 = 0, x2y1 = 0, x1y2 = 0, y3 = 0, x2z1 = 0, y2z1 = 0, z3 = 0,
x1z2 = 0, y1z2 = 0;
double z4 = 0, y4 = 0, x2y2 = 0, x2z2 = 0, y2z2 = 0;
double n = ptlt.Count;
double[] outarray = new double[6];
for (int i = 0; i < n; i++)
{
x1 += ptlt[i].x;
y1 += ptlt[i].y;
z1 += ptlt[i].z;
x2 += ptlt[i].x * ptlt[i].x;
x1y1 += ptlt[i].x * ptlt[i].y;
y2 += ptlt[i].y * ptlt[i].y;
x1z1 += ptlt[i].x * ptlt[i].z;
y1z1 += ptlt[i].y * ptlt[i].z;
z2 += ptlt[i].z * ptlt[i].z;
x3 += ptlt[i].x * ptlt[i].x * ptlt[i].x;
x2y1 += ptlt[i].x * ptlt[i].x * ptlt[i].y;
x1y2 += ptlt[i].x * ptlt[i].y * ptlt[i].y;
y3 += ptlt[i].y * ptlt[i].y * ptlt[i].y;
x2z1 += ptlt[i].x * ptlt[i].x * ptlt[i].z;
y2z1 += ptlt[i].y * ptlt[i].y * ptlt[i].z;
z3 += ptlt[i].z * ptlt[i].z * ptlt[i].z;
y4 += ptlt[i].y * ptlt[i].y * ptlt[i].y * ptlt[i].y;
z4 += ptlt[i].z * ptlt[i].z * ptlt[i].z * ptlt[i].z;
x2y2 += ptlt[i].x * ptlt[i].x * ptlt[i].y * ptlt[i].y;
x2z2 += ptlt[i].x * ptlt[i].x * ptlt[i].z * ptlt[i].z;
y2z2 += ptlt[i].y * ptlt[i].y * ptlt[i].z * ptlt[i].z;
}
var matrixA = DenseMatrix.OfArray(new[,] {{y4/n,y2z2/n,x1y2/n,y3/n,y2z1/n,y2/n},{y2z2/n,z4/n,x1z2/n,y1z2/n,z3/n,z2/n}
,{x1y2/n,x1z2/n,x2/n,x1y1/n,x1z1/n,x1/n},{y3/n,y1z2/n,x1y1/n,y2/n,y1z1/n,y1/n},{y2z1/n,z3/n,x1z1/n,y1z1/n,z2/n,z1/n}
,{y2/n,z2/n,x1/n,y1/n,z1/n,1}});
var vectorB = new DenseVector(new[] { -x2y2/n, -x2z2/n, -x3/n, -x2y1/n, -x2z1/n, -x2/n });
var resultX = matrixA.LU().Solve(vectorB);
for (int i = 0; i < 6; i++)
{
outarray[i] = resultX[i];
}
return outarray;
}
}
class Program
{
static void Main(string[] args)
{
StreamReader sr = new StreamReader("柱体1.txt", Encoding.Default);
List
double[] pointC = new double[6];
pointlist = Getdata.GetL(sr);
sr.Close();
pointC = Getdata.GetC(pointlist);
for (int i = 0; i < pointC.GetLength(0); i++)
{
Console.WriteLine(pointC[i]);
}
Console.WriteLine("拟合曲面方程一般形式:");
Console.WriteLine("x*x+({0:f3}*y*y)+({1:f3}*z*z)+({2:f3}*x)+({3:f3}*y)+({4:f3}*z)+({5:f3})=0",
pointC[0],pointC[1],pointC[2],pointC[3],pointC[4],pointC[5]);
double oures = 0;
oures = pointlist[0].x * pointlist[0].x + pointC[0] * pointlist[0].y * pointlist[0].y +
pointC[1] * pointlist[0].z * pointlist[0].z + pointC[2] * pointlist[0].x + pointC[3] * pointlist[0].y +
pointC[4] * pointlist[0].z + pointC[5];
Console.WriteLine(oures); //代入第一个点,查看误差大小;
Console.ReadLine();
}
}
}