Exemple #1
0
        public void ToX(XElement xe)
        {
            var closed = Closed;

            if (GeoUtils.Equals(ControlPoints[0], ControlPoints[ControlPoints.Count - 1]))
            {
                closed = true;
            }

            xe.Add(new XAttribute("Closed", closed));
            xe.Add(new XAttribute("Degree", Degree));
            var controlPoints = new XElement("ControlPoints");

            xe.Add(controlPoints);
            foreach (var pt in ControlPoints)
            {
                controlPoints.Add(pt.ToX("Point"));
            }
            xe.Add(Knots.ToX());
        }
Exemple #2
0
        public Curve2D GetSegmentAt(int index)
        {
            if (index < 0 || index >= SegmentCount)
            {
                return(null);
            }
            var pt1 = Vertexs[index];
            var pt2 =
                index == Vertexs.Count - 1 ?
                Vertexs[0] :
                Vertexs[index + 1];

            if (GeoUtils.Equals(pt1.Bulge, 0))
            {
                return(new LineSegment2D(pt1.Position, pt2.Position));
            }
            else
            {
                return(new CircleArc2D(pt1.Position, pt2.Position, pt1.Bulge));
            }
        }
Exemple #3
0
        public CircleArc2D(Point2D pt1, Point2D pt2, Point2D pt3, bool isWholeCircle)
        {
            if (isWholeCircle)
            {
                var xy1 = Math.Pow(pt1.X, 2) + Math.Pow(pt1.Y, 2);
                var xy2 = xy1 - Math.Pow(pt3.X, 2) - Math.Pow(pt3.Y, 2);
                var xy3 = xy1 - Math.Pow(pt2.X, 2) - Math.Pow(pt2.Y, 2);
                xy1 = (pt1.X - pt2.X) * (pt1.Y - pt3.Y) - (pt1.X - pt3.X) * (pt1.Y - pt2.Y);
                if (GeoUtils.Equals(xy1, 0))
                {
                    throw new Exception("无法创建圆!");
                }

                Center =
                    new Point2D(
                        (xy3 * (pt1.Y - pt3.Y) - xy2 * (pt1.Y - pt2.Y)) / (2 * xy1),
                        (xy2 * (pt1.X - pt2.X) - xy3 * (pt1.X - pt3.X)) / (2 * xy1));

                Radius = (pt1 - Center).Length;
                if (GeoUtils.Equals(Radius, 0))
                {
                    throw new Exception("半径为零!");
                }

                StartAngle = Angle.Zero;
                EndAngle   = Angle.Degree360;
            }
            else
            {
                CircleArc2D cir = new CircleArc2D(pt1, pt2, pt3, true);
                Center = cir.Center;
                Radius = cir.Radius;

                IsClockWise =
                    Vector2D.IsClockWise(
                        pt1 - cir.Center,
                        pt2 - cir.Center,
                        pt3 - cir.Center);
            }
        }
Exemple #4
0
        /// <summary>
        /// 按向量的镜像矩阵
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public static Matrix2D Mirror(Vector2D vec)
        {
            bool ex = GeoUtils.Equals(vec.X, 0);
            bool ey = GeoUtils.Equals(vec.Y, 0);

            if (ex && ey)
            {
                return(Rotation(new Angle(Math.PI)));
            }
            else if (ex)
            {
                return(new Matrix2D(-1, 0, 0, 1, 0, 0));
            }
            else if (ey)
            {
                return(new Matrix2D(1, 0, 0, -1, 0, 0));
            }

            double angle = vec.Angle * 2;
            double s2    = Math.Sin(angle);
            double c2    = Math.Cos(angle);

            return(new Matrix2D(c2, s2, s2, -c2, 0, 0));
        }
Exemple #5
0
 public void ToX(XElement xe)
 {
     xe.Add(new XAttribute("X", GeoUtils.Round(X)));
     xe.Add(new XAttribute("Y", GeoUtils.Round(Y)));
 }
Exemple #6
0
 public bool IsPerpendicularTo(Vector2D vec)
 {
     return(GeoUtils.Equals(DotProduct(vec), 0));
 }
Exemple #7
0
 public bool IsParallelTo(Vector2D vec)
 {
     return(GeoUtils.Equals(CrossProduct(vec), 0));
 }
Exemple #8
0
 public static bool operator ==(Vector2D v1, Vector2D v2)
 {
     return
         (GeoUtils.Equals(v1.X, v2.X, GeoUtils.EqualsPoint) &&
          GeoUtils.Equals(v1.Y, v2.Y, GeoUtils.EqualsPoint));
 }
Exemple #9
0
 public bool Equals(Angle x, Angle y)
 {
     return(GeoUtils.Equals(x._radian, y._radian));
 }
Exemple #10
0
 public bool IsWholeCircle()
 {
     return(GeoUtils.Equals(_radian, PI2));
 }
Exemple #11
0
 public bool IsZero()
 {
     return(GeoUtils.Equals(_radian, 0));
 }
Exemple #12
0
 /// <summary>
 /// 交换矩阵元素
 /// </summary>
 /// <param name="x1"></param>
 /// <param name="y1"></param>
 /// <param name="x2"></param>
 /// <param name="y2"></param>
 public void Swap(int x1, int y1, int x2, int y2)
 {
     GeoUtils.Swap(ref _elements, x1, y1, x1, y1);
 }
Exemple #13
0
 public override string ToString()
 {
     return(string.Format("{0},{1}", GeoUtils.Round(X), GeoUtils.Round(Y)));;
 }
Exemple #14
0
 public static bool operator ==(Point2D p1, Point2D p2)
 {
     return
         (GeoUtils.Equals(p1.X, p2.X, GeoUtils.EqualsPoint) &&
          GeoUtils.Equals(p1.Y, p2.Y, GeoUtils.EqualsPoint));
 }
Exemple #15
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];
                    }
                }
            }
        }