Exemple #1
0
        public Spline2D(bool closed, bool periodic, List <Point2D> controlPoints, List <double> knots)
        {
            Periodic = periodic;
            int n = controlPoints.Count() - 1;

            FitPoints    = new List <Point2D>();
            HasFitPoints = false;

            NurbsData = new NurbsData(controlPoints, knots, 3, closed);
        }
Exemple #2
0
 public override void ToX(XElement xe)
 {
     xe.Add(new XAttribute("Periodic", Periodic));
     xe.Add(new XAttribute("HasFitPoints", HasFitPoints));
     xe.Add(NurbsData.ToX());
     if (HasFitPoints)
     {
         var e = new XElement("FitPoints",
                              new XAttribute("TangentsExist", TangentsExist));
         xe.Add(e);
         if (TangentsExist)
         {
             e.Add(new XAttribute("Start", StartTangent.ToString()));
             e.Add(new XAttribute("End", EndTangent.ToString()));
         }
         foreach (var pt in FitPoints)
         {
             e.Add(pt.ToX("Point"));
         }
     }
     MakeLayer(xe);
 }
Exemple #3
0
        public override void FromX(XElement xe)
        {
            Periodic  = bool.Parse(xe.Attribute("Periodic").Value);
            NurbsData = new NurbsData();
            NurbsData.FromX(xe.Element("NurbsData"));

            HasFitPoints = bool.Parse(xe.Attribute("HasFitPoints").Value);
            if (HasFitPoints)
            {
                var fpts = xe.Element("FitPoints");
                FitPoints = new List <Point2D>();
                foreach (var pt in fpts.Elements())
                {
                    FitPoints.Add(XParser.Parse <Point2D>(pt));
                }
                TangentsExist = bool.Parse(fpts.Attribute("TangentsExist").Value);
                if (TangentsExist)
                {
                    StartTangent = Vector2D.Parse(fpts.Attribute("Start").Value);
                    EndTangent   = Vector2D.Parse(fpts.Attribute("End").Value);
                }
            }
        }
Exemple #4
0
 internal KnotCollection(NurbsData owner)
 {
     _owner = owner;
     _knots = new List <double>();
 }
Exemple #5
0
 /// <summary>
 /// 获取参数对应点
 /// </summary>
 /// <param name="par">参数</param>
 /// <returns>参数对应点</returns>
 public override Point2D GetPointAtParam(double par)
 {
     return(NurbsData.GetPointAtParam(par));
 }
Exemple #6
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];
                    }
                }
            }
        }