示例#1
0
        public static IPolyLine2D Convert(this Polyline source)
        {
            var target = new PolyLine2D(source.Segments.Count);

            foreach (var s in source.Segments)
            {
                ISegment2D segment = null;
                switch (s.Type)
                {
                case SegmentType.StartPoint:
                    target.StartPoint = new Point(s.Parameters[0], s.Parameters[1]);
                    continue;

                case SegmentType.Line:
                    segment = new LineSegment2D(new Point(s.Parameters[0], s.Parameters[1]));
                    break;

                case SegmentType.CircArc3Points:
                    segment = new CircularArcSegment2D(new Point(s.Parameters[0], s.Parameters[1]), new Point(s.Parameters[2], s.Parameters[3]));
                    break;
                }

                target.Segments.Add(segment);
            }

            return(target);
        }
示例#2
0
        /// <summary>
        /// Divide <c>ParabolicArcSegment2D</c> on straight lines polygon.
        /// </summary>
        /// <param name="start">The start point of segment.</param>
        /// <param name="source">The segment to discretization.</param>
        /// <param name="target">The <c>Region2D</c> as target of discretization.</param>
        public void Discretize(Point start, ISegment2D source, IPolygon2D target)
        {
            var segment = source as ParabolicArcSegment2D;

            // The angle in degrees
            double totalAngle = segment.GetAngle(ref start);

            if (angle < Math.Abs(totalAngle) || this.numberOfTiles > 1)
            {
                int numberOfTiles = Math.Max((int)Math.Ceiling(Math.Abs(totalAngle) / angle), this.numberOfTiles);

                double deltaAngle = totalAngle / numberOfTiles;
                var    mat        = new Matrix();
                mat.Rotate(deltaAngle);
                var t = segment.GetTangentOnSegment(ref start, 0);
                for (int i = 1; i < numberOfTiles; ++i)
                {
                    t = mat.Transform(t);
                    if (segment.CoordinatesFromTangent(ref start, t, out Point p))
                    {
                        target.Add(p);
                    }
                }
            }

            target.Add(segment.EndPoint);
        }
示例#3
0
        private static Segment Convert(this ISegment2D segment, ref Point start, Point?origin = null)
        {
            var line = segment as LineSegment2D;

            if (line != null)
            {
                if (origin.HasValue)
                {
                    return(Segment.LineSegment(line.EndX - origin.Value.X, line.EndY - origin.Value.Y));
                }
                else
                {
                    return(Segment.LineSegment(line.EndX, line.EndY));
                }
            }

            var circArc = segment as CircularArcSegment2D;

            if (circArc != null)
            {
                double[] p;
                if (origin.HasValue)
                {
                    p = new double[]
                    {
                        circArc.EndX - origin.Value.X,
                        circArc.EndY - origin.Value.Y,
                        circArc.Point.X - origin.Value.X,
                        circArc.Point.Y - origin.Value.Y,
                    }
                }
                ;
                else
                {
                    p = new double[]
                    {
                        circArc.EndX,
                        circArc.EndY,
                        circArc.Point.X,
                        circArc.Point.Y,
                    }
                };
                return(new Segment {
                    Type = SegmentType.CircArc3Points, Parameters = p,
                });
            }

            throw new NotImplementedException();
        }
        /// <summary>
        /// Divide <c>LineSegment2D</c> on straight lines polygon.
        /// </summary>
        /// <param name="start">The start point of segment.</param>
        /// <param name="source">The segment to discretization.</param>
        /// <param name="target">The <c>Polygon2D</c> as target of discretization.</param>
        public void Discretize(Point start, ISegment2D source, IPolygon2D target)
        {
            double length = source.GetLength(ref start);

            if (numberOfTiles > 1 || length > lengthOfTile)
            {
                int           tiles   = Math.Max(numberOfTiles, (int)Math.Ceiling(length / lengthOfTile));
                LineSegment2D segment = source as LineSegment2D;
                Vector        u       = Point.Subtract(segment.EndPoint, start) / tiles;
                Point         pt      = start;
                for (int i = 1; i < tiles; ++i)
                {
                    pt = Point.Add(pt, u);
                    target.Add(pt);
                }
            }

            target.Add(source.EndPoint);
        }
示例#5
0
        /// <summary>
        /// Divide <c>CircularArcSegment2D</c> on straight lines polygon.
        /// </summary>
        /// <param name="start">The start point of segment.</param>
        /// <param name="source">The segment to discretization.</param>
        /// <param name="target">The <c>Region2D</c> as target of discretization.</param>
        public void Discretize(Point start, ISegment2D source, IPolygon2D target)
        {
            CircularArcSegment2D segment = source as CircularArcSegment2D;

            // The angle in degrees
            double totalAngle = Math.Abs(segment.GetAngle(ref start));

            if (angle < totalAngle || this.numberOfTiles > 1)
            {
                int numberOfTiles = Math.Max((int)Math.Ceiling(totalAngle / angle), this.numberOfTiles);

                double deltaAngle = totalAngle / numberOfTiles * segment.IsCounterClockwise(ref start);
                Matrix mat        = new Matrix();
                Point  centre     = segment.GetCentre(ref start);
                for (int i = 1; i < numberOfTiles; ++i)
                {
                    mat.RotateAt(deltaAngle, centre.X, centre.Y);
                    target.Add(mat.Transform(start));
                }
            }

            target.Add(segment.EndPoint);
        }
示例#6
0
 private static void CreateCenterlineSegment(Point plateSideBegPt, ISegment2D plateSide, Point oppositeSideBegPt, ISegment2D oppositeSide, out Point clBegPt, out Point clEndPt)
 {
     clBegPt = new Point((plateSideBegPt.X + oppositeSide.EndPoint.X) * 0.5, (plateSideBegPt.Y + oppositeSide.EndPoint.Y) * 0.5);
     clEndPt = new Point((plateSide.EndPoint.X + oppositeSideBegPt.X) * 0.5, (plateSide.EndPoint.Y + oppositeSideBegPt.Y) * 0.5);
 }
示例#7
0
        private static IList <ISegment2D> FindSecondSideOfPlate(Point plateSideBegPt, ISegment2D plateSide, IPolyLine2D outline, double distance, double tolerance = 0.0001)
        {
            Vector            vec2            = new Vector(plateSideBegPt.X - plateSide.EndPoint.X, plateSideBegPt.Y - plateSide.EndPoint.Y);
            List <ISegment2D> foundCandidates = new List <ISegment2D>();
            Point             begPt           = outline.StartPoint;

            foreach (ISegment2D seg in outline.Segments)
            {
                if (seg != plateSide)
                {
                    Vector vec1  = new Vector(begPt.X - seg.EndPoint.X, begPt.Y - seg.EndPoint.Y);
                    double angle = Math.Abs(GeomTools2D.AngleBetweenVectors(vec1, vec2));
                    if (angle.IsEqual(0.0, 0.035) || angle.IsEqual(Math.PI, 0.035))
                    {
                        if (GeomTools2D.Distance(plateSideBegPt, plateSide.EndPoint, seg.EndPoint).IsEqual(distance, tolerance))
                        {
                            Vector vector  = new Vector(1.0, 0.0);
                            Vector vector2 = new Vector(plateSide.EndPoint.X - plateSideBegPt.X, plateSide.EndPoint.Y - plateSideBegPt.Y);
                            double angle2  = Vector.AngleBetween(vector, vector2);                           //GeomTools2D.AngleBetweenVectors(vector, vector2);
                            Matrix mx      = Matrix.Identity;
                            mx.Rotate(-angle2);
                            Point a1   = mx.Transform(plateSideBegPt);
                            Point a2   = mx.Transform(plateSide.EndPoint);
                            Point b1   = mx.Transform(begPt);
                            Point b2   = mx.Transform(seg.EndPoint);
                            bool  test = false;

                            if (b1.X.IsEqual(a1.X) || b1.X.IsEqual(a2.X) || b2.X.IsEqual(a1.X) || b2.X.IsEqual(a2.X))
                            {
                                test = true;
                            }
                            else
                            {
                                if (Math.Sign(b1.X - a1.X) != Math.Sign(b1.X - a2.X))
                                {
                                    test = true;
                                }

                                if (Math.Sign(b2.X - a1.X) != Math.Sign(b2.X - a2.X))
                                {
                                    test = true;
                                }

                                if (Math.Sign(a1.X - b1.X) != Math.Sign(a1.X - b2.X))
                                {
                                    test = true;
                                }

                                if (Math.Sign(a2.X - b1.X) != Math.Sign(a2.X - b2.X))
                                {
                                    test = true;
                                }
                            }

                            if (test)
                            {
                                foundCandidates.Add(seg);
                            }
                        }
                    }
                }

                begPt = seg.EndPoint;
            }

            return(foundCandidates);
        }
示例#8
0
        public static bool TryGetCenterlineOfOpenCFSection(IPolyLine2D outline, double thickness, out IList <IPolyLine2D> centerlines, double tolerance = 0.0001, bool isClosed = true)
        {
            int edgeSegmentsCount = 0;

            centerlines = new List <IPolyLine2D>();
            List <Tuple <int, int, Point, Point> > segLst = new List <Tuple <int, int, Point, Point> >();
            Point begPt = outline.StartPoint;

            for (int i = 0, sz = outline.Segments.Count; i < sz; i++)
            {
                ISegment2D         seg        = outline.Segments[i];
                IList <ISegment2D> candidates = FindSecondSideOfPlate(begPt, seg, outline, thickness, tolerance);
                if (!candidates.Any())
                {
                    edgeSegmentsCount++;
                }

                foreach (ISegment2D candidate in candidates)
                {
                    int   ix             = outline.Segments.IndexOf(candidate);
                    Point candidateBegPt = (ix == 0) ? outline.StartPoint : outline.Segments[ix - 1].EndPoint;
                    CreateCenterlineSegment(begPt, seg, candidateBegPt, candidate, out Point clBegPt, out Point clEndPt);
                    segLst.Add(new Tuple <int, int, Point, Point>(i, ix, clBegPt, clEndPt));
                }

                begPt = seg.EndPoint;
            }

            if (edgeSegmentsCount != 2)
            {
                return(false);
            }

            //iterations
            List <Tuple <Point, Point> > centerlineSegments = new List <Tuple <Point, Point> >();

            while (segLst.Any())
            {
                List <Tuple <int, int, Point, Point> > resolved = new List <Tuple <int, int, Point, Point> >();

                for (int i = 0, sz = segLst.Count; i < sz; i++)
                {
                    bool pair = false;
                    Tuple <int, int, Point, Point> seg = segLst[i];
                    if (resolved.Contains(seg) && isClosed)
                    {
                        continue;
                    }

                    if (i < sz - 1)
                    {
                        if (i > 0)
                        {
                            if (segLst[i - 1].Item1 == seg.Item1)
                            {
                                pair = true;
                            }
                        }

                        if (segLst[i + 1].Item1 == seg.Item1)
                        {
                            pair = true;
                        }
                    }

                    if (!pair)
                    {
                        centerlineSegments.Add(new Tuple <Point, Point>(seg.Item3, seg.Item4));
                        resolved.Add(seg);

                        Tuple <int, int, Point, Point> secondPart = segLst.FirstOrDefault((item) => item.Item1 == seg.Item2 && item.Item2 == seg.Item1);
                        if (secondPart != null)
                        {
                            resolved.Add(secondPart);
                            int secIx = segLst.IndexOf(secondPart);
                            Tuple <int, int, Point, Point> prev = (secIx == 0) ? null : segLst[secIx - 1];
                            Tuple <int, int, Point, Point> next = (secIx == segLst.Count - 1) ? null : segLst[secIx + 1];

                            Tuple <int, int, Point, Point> pairMember = null;
                            if (prev != null)
                            {
                                if (prev.Item1 == secondPart.Item1)
                                {
                                    pairMember = prev;
                                }
                            }

                            if (next != null)
                            {
                                if (next.Item1 == secondPart.Item1)
                                {
                                    pairMember = next;
                                }
                            }

                            if (pairMember != null)
                            {
                                resolved.Add(pairMember);
                                Tuple <int, int, Point, Point> part3 = segLst.FirstOrDefault((item) => item.Item1 == pairMember.Item2 && item.Item2 == pairMember.Item1);
                                if (part3 != null)
                                {
                                    resolved.Add(part3);
                                }
                            }
                        }
                    }
                }

                var toBeRemoved = resolved.Distinct();
                foreach (Tuple <int, int, Point, Point> remItem in toBeRemoved)
                {
                    segLst.Remove(remItem);
                }
            }

            if (!centerlineSegments.Any())
            {
                return(false);
            }

            List <Tuple <Point, Point> > centerlineOrder = new List <Tuple <Point, Point> >();

            centerlineOrder.Add(centerlineSegments.First());
            centerlineSegments.Remove(centerlineSegments.First());

            bool escape = false;

            while (centerlineSegments.Any() && !escape)
            {
                List <Tuple <Point, Point> > toBeRemoved = new List <Tuple <Point, Point> >();
                Tuple <Point, Point>         forwardDir  = centerlineOrder.Last();
                Tuple <Point, Point>         backwardDir = centerlineOrder.First();

                foreach (Tuple <Point, Point> seg in centerlineSegments)
                {
                    if (seg.Item1.IsEqualWithTolerance(forwardDir.Item2))
                    {
                        forwardDir = seg;
                        toBeRemoved.Add(seg);
                        centerlineOrder.Add(seg);
                    }
                    else if (seg.Item2.IsEqualWithTolerance(forwardDir.Item2))
                    {
                        forwardDir = new Tuple <Point, Point>(seg.Item2, seg.Item1);
                        toBeRemoved.Add(seg);
                        centerlineOrder.Add(forwardDir);
                    }
                    else if (seg.Item2.IsEqualWithTolerance(backwardDir.Item1))
                    {
                        backwardDir = seg;
                        toBeRemoved.Add(seg);
                        centerlineOrder.Insert(0, seg);
                    }
                    else if (seg.Item1.IsEqualWithTolerance(backwardDir.Item1))
                    {
                        backwardDir = new Tuple <Point, Point>(seg.Item2, seg.Item1);
                        toBeRemoved.Add(seg);
                        centerlineOrder.Insert(0, backwardDir);
                    }
                }

                foreach (Tuple <Point, Point> remItem in toBeRemoved)
                {
                    centerlineSegments.Remove(remItem);
                }

                if (!toBeRemoved.Any())
                {
                    Debug.Fail("Nespojitá střednice!! V algoritmu je chyba.");
                    escape = true;
                }
            }

            IPolyLine2D centerline = new PolyLine2D(centerlineOrder.Count);

            for (int i = 0, sz = centerlineOrder.Count; i < sz; i++)
            {
                Tuple <Point, Point> segPts = centerlineOrder[i];
                if (i == 0)
                {
                    centerline.StartPoint = segPts.Item1;
                }

                centerline.Segments.Add(new LineSegment2D(segPts.Item2));
            }

            centerlines.Add(centerline);
            return(true);
        }