Пример #1
0
        /// <summary>
        /// 获取逆矩阵
        /// </summary>
        /// <returns></returns>
        public Matrix2D?Inverse()
        {
            Matrix2D mat = Clone();

            if (GeoUtils.Inverse(ref mat._elements, 3))
            {
                return(mat);
            }
            else
            {
                return(null);
            }
        }
Пример #2
0
        /// <summary>
        /// 插值点反求控制点
        /// </summary>
        /// <param name="closed"></param>
        /// <param name="fitPoints"></param>
        public Spline2D(bool closed, IEnumerable <Point2D> fitPoints)
        {
            Periodic     = false;
            HasFitPoints = true;
            FitPoints    = new List <Point2D>(fitPoints);

            //参数区间数
            int n = FitPoints.Count - 1;

            //参数化
            List <double> knots = new List <double>();

            knots.Add(0);
            double totalLength = 0;

            for (int i = 0; i < n; i++)
            {
                totalLength += (FitPoints[i + 1] - FitPoints[i]).Length;
                knots.Add(totalLength);
            }
            if (closed)
            {
                totalLength += (FitPoints[0] - FitPoints[FitPoints.Count - 1]).Length;
                knots.Add(totalLength);
            }

            NurbsData = new NurbsData(knots, 3, closed);

            if (closed)
            {
                //构建矩阵方程组
                double[,] mat = new double[n + 1, n + 1];
                for (int i = 0; i < n + 1; i++)
                {
                    var par  = NurbsData.Knots[i + Degree];
                    int span = NurbsData.Knots.FindSpan(par);
                    var nn   = NurbsData.Knots.BasicFuns(span, par);
                    for (int j = 0; j < Degree; j++)
                    {
                        mat[i, (span - Degree + j) % (n + 1)] = nn[j];
                    }
                }
                var fpts = new List <Point2D>(FitPoints);
                //求解
                GeoUtils.Inverse(ref mat, n + 1);
                for (int i = 0; i < n + 1; i++)
                {
                    NurbsData.AddControlPoint(new Point2D());
                    for (int j = 0; j < n + 1; j++)
                    {
                        NurbsData.ControlPoints[i] += fpts[j] * mat[i, j];
                    }
                }
            }
            else
            {
                //构建矩阵方程组
                double[,] mat = new double[n + 3, n + 3];
                //计算插值点的非零幂基函数值
                for (int i = 1; i < n; i++)
                {
                    var par  = NurbsData.Knots[i + Degree];
                    int span = NurbsData.Knots.FindSpan(par);
                    var nn   = NurbsData.Knots.BasicFuns(span, par);
                    for (int j = 0; j < Degree; j++)
                    {
                        mat[i + 1, span - Degree + j] = nn[j];
                    }
                }

                mat[1, 0] = mat[n + 1, n + 2] = 1;

                //使用自由边界条件,即端点处二阶导数为0
                var t1 = totalLength / NurbsData.Knots[Degree + 1];
                var t2 = totalLength / NurbsData.Knots[Degree + 2];
                mat[0, 0]         = t1;
                mat[0, 1]         = -t1 - t2;
                mat[0, 2]         = t2;
                t1                = totalLength / (totalLength - NurbsData.Knots[n + Degree - 2]);
                t2                = totalLength / (totalLength - NurbsData.Knots[n + Degree - 1]);
                mat[n + 2, n]     = t1;
                mat[n + 2, n + 1] = -t1 - t2;
                mat[n + 2, n + 2] = t2;

                var fpts = new List <Point2D>();
                fpts.Add(Point2D.Origin);
                fpts.AddRange(FitPoints);
                fpts.Add(Point2D.Origin);

                //求解
                GeoUtils.Inverse(ref mat, n + 3);
                for (int i = 0; i < n + 3; i++)
                {
                    NurbsData.AddControlPoint(new Point2D());
                    for (int j = 0; j < n + 3; j++)
                    {
                        NurbsData.ControlPoints[i] += fpts[j] * mat[i, j];
                    }
                }
            }
        }