Beispiel #1
0
        public static List <Vector> GetConvexHull(this PointString poly)
        {
            var points     = new List <Vector>();
            var collection = new List <Vector>();
            int num        = 0;
            var source     = poly.Points.ToList();

            source.Sort((p1, p2) => (p1.X - p2.X == 0) ? (int)(p1.Y - p2.Y) : (int)(p1.X - p2.X));

            points.Add(source[0]);
            points.Add(source[1]);
            for (num = 2; num <= (source.Count - 1); num++)
            {
                points.Add(source[num]);
                while ((points.Count >= 3) && !IsTurnRight(points[points.Count - 3], points[points.Count - 2], points[points.Count - 1]))
                {
                    points.RemoveAt(points.Count - 2);
                }
            }
            collection.Add(source[source.Count - 1]);
            collection.Add(source[source.Count - 2]);
            for (num = source.Count - 2; num >= 0; num--)
            {
                collection.Add(source[num]);
                while ((collection.Count >= 3) && !IsTurnRight(collection[collection.Count - 3], collection[collection.Count - 2], collection[collection.Count - 1]))
                {
                    collection.RemoveAt(collection.Count - 2);
                }
            }
            collection.RemoveAt(collection.Count - 1);
            collection.RemoveAt(0);
            points.AddRange(collection);
            return(points);
        }
Beispiel #2
0
        public static double DistToPoint(this PointString poly, Vector p, int divs) // newly 20130523 近似法
        {
            var    points = poly.Points;
            double delta  = (double)(points.Count - 1) / divs;
            var    pts    = Enumerable.Range(0, divs + 1).Select(i => poly.Lerp(i * delta)).ToList();

            return(pts.Min(pt => pt.Dist(p)));
        }
Beispiel #3
0
        public static LineSeg GetSegAt(this PointString poly, int i)
        {
            var points = poly.Points;

            if (i < 0)
            {
                i = 0;
            }
            else if (i > points.Count - 1)
            {
                i = points.Count - 1;
            }
            int j = i >= points.Count - 1 ? 0 : i + 1;

            return(new LineSeg(points[i], points[j]));
        }
Beispiel #4
0
        public static PointString Offset(this PointString poly, double offset)
        {
            var points0 = poly.Points;
            var points1 = new List <Vector>();

            if (points0.Count <= 0)
            {
                //return null;
            }
            else if (points0.Count == 1)
            {
                var pt = new Vector(points0[0].X + offset, points0[0].Y);
                points1.Add(pt);
            }
            else if (points0.Count == 2)
            {
                points1 = GetOffsetSeg(points0[0], points0[1], offset);
            }
            else
            {
                var pt1 = GetOffsetSeg(points0[0], points0[1], offset)[0];
                points1.Add(pt1);

                for (int count = 1; count <= points0.Count - 1; count++)
                {
                    if (count == points0.Count - 1)
                    {
                        var pt = GetOffsetSeg(points0[count - 1], points0[count], offset)[1];
                        points1.Add(pt);
                    }
                    else
                    {
                        var p10 = GetOffsetSeg(points0[count - 1], points0[count], offset)[0];
                        var p11 = GetOffsetSeg(points0[count - 1], points0[count], offset)[1];
                        var p20 = GetOffsetSeg(points0[count], points0[count + 1], offset)[0];
                        var p21 = GetOffsetSeg(points0[count], points0[count + 1], offset)[1];

                        var d0 = new Vector(p11.X - p10.X, p11.Y - p10.Y);
                        var d1 = new Vector(p20.X - p21.X, p20.Y - p21.Y);

                        points1.Add(GetIntersection(p10, p21, d0, d1));
                    }
                }
            }
            return(new PointString(points1));
        }
Beispiel #5
0
        public static void ReducePoints(this PointString poly, double epsilon)
        {
            var points    = poly.Points;
            var cleanList = new List <int>();
            int j         = 0;

            for (int i = 1; i < points.Count; i++)
            {
                if (points[i].Dist(points[j]) < epsilon)
                {
                    cleanList.Add(i);
                }
                else
                {
                    j = i;
                }
            }
            cleanList.Reverse();
            cleanList.ForEach(x => points.RemoveAt(x));
        }
Beispiel #6
0
        public static PointString GetSubPoly(this PointString poly, double start, double end)
        {
            var points = poly.Points;

            start = (start < 0) ? 0 : start;
            end   = (end > points.Count - 1) ? (points.Count - 1) : end;
            var    pts = new List <Vector>();
            double a   = Math.Ceiling(start);
            double b   = Math.Floor(end);

            for (int i = (int)a; i <= (int)b; i++)
            {
                pts.Add(points[i]);
            }
            if (start < a)
            {
                pts.Insert(0, poly.Lerp(start));
            }
            if (end > b)
            {
                pts.Add(poly.Lerp(end));
            }
            return(new PointString(pts));
        }
Beispiel #7
0
        public static double DistToPoint(this PointString poly, Vector p)
        {
            Vector foot;

            return(DistToPoint(poly, p, out foot));
        }
Beispiel #8
0
        public static double DistToPoint(this PointString poly, Vector p, out Vector footPos)
        {
            var    points   = poly.Points;
            double minDist  = points.Min(x => x.Dist(p));
            var    minPoint = points.First(x => x.Dist(p) == minDist);

            if (minPoint.Equals(points.First()))
            {
                LineSeg seg1 = new LineSeg(points[0], points[1]);
                LineSegPointRelation relation1 = new LineSegPointRelation(seg1, p);
                if (relation1.Inner)
                {
                    footPos = relation1.Foot;
                    return(relation1.Dist);
                }
                else
                {
                    footPos = minPoint;
                    return(minDist);
                }
            }
            else if (minPoint.Equals(points.Last()))
            {
                int     n    = points.Count;
                LineSeg seg1 = new LineSeg(points[n - 2], points[n - 1]);
                LineSegPointRelation relation1 = new LineSegPointRelation(seg1, p);
                if (relation1.Inner)
                {
                    footPos = relation1.Foot;
                    return(relation1.Dist);
                }
                else
                {
                    footPos = minPoint;
                    return(minDist);
                }
            }
            else
            {
                int     index = points.IndexOf(minPoint);
                LineSeg seg1  = new LineSeg(points[index - 1], points[index]);
                LineSeg seg2  = new LineSeg(points[index + 1], points[index]);
                LineSegPointRelation relation1 = new LineSegPointRelation(seg1, p);
                LineSegPointRelation relation2 = new LineSegPointRelation(seg2, p);
                if (relation1.Inner)
                {
                    footPos = relation1.Foot;
                    return(relation1.Dist);
                }
                else if (relation2.Inner)
                {
                    footPos = relation1.Foot;
                    return(relation2.Dist);
                }
                else
                {
                    footPos = minPoint;
                    return(minDist);
                }
            }
        }