protected static List <IntPoint> CreatePolygon(IPolyLine2D polyline, PolyLine2DDiscretizator discretizator, bool counterClockwise)
        {
            IPolygon2D polygon = new Polygon2D();

            discretizator.Discretize(polyline, ref polygon, null);
            return(CreatePolygon(polygon, counterClockwise));
        }
Example #2
0
        public static IPolyLine3D TrimmedRegion(Matrix44 lcs, IPolyLine3D trimmedRegion, IPolyLine3D trimRegion, out bool done)
        {
            done = false;

            List <IPoint3D> listOfIntersectionPoint = new List <IPoint3D>();

            Intersect(trimmedRegion, trimRegion, listOfIntersectionPoint);
            if (listOfIntersectionPoint.Count > 0)
            {
                done = true;
                IPolyLine3D trimmedRegionCopy = new PolyLine3D(trimmedRegion);
                IPolyLine3D trimRegionCopy    = new PolyLine3D(trimRegion);

                IPolyLine2D trimmedPolyLine2D = ConvertTo2D(lcs, trimmedRegionCopy);
                IPolyLine2D trimPolyLine2D    = ConvertTo2D(lcs, trimRegionCopy);
                Region2D    trimmedRegion2D   = new Region2D(trimmedPolyLine2D);
                Region2D    trimRegion2D      = new Region2D(trimPolyLine2D);

                // odecte od "trimmedRegion2D" "trimRegion2D".
                var         clipper = new ClipperController(trimmedRegion2D, trimRegion2D);
                IRegion2D[] regions = clipper.Difference().ToArray();

                if (regions.Length > 0)
                {
                    IPolyLine3D adaptedRegion = ConvertTo3D(regions[0].Outline);
                    TransformToGCS(lcs, adaptedRegion);
                    return(adaptedRegion);
                }
            }
            return(trimmedRegion);
        }
Example #3
0
        public static IPolyLine3D ConvertTo3D(IPolyLine2D polyline, IMatrix44 lcs)
        {
            var geom = GeomOperation.ConvertTo3D(polyline);

            GeomOperation.TransformToGCS(lcs, geom);
            return(geom);
        }
Example #4
0
 /// <summary>
 /// Creates region and sets its outline and openings
 /// </summary>
 /// <param name="outline">Outline of the region</param>
 /// <param name="openings">Openings in the region</param>
 public Region2D(IPolyLine2D outline, IList <IPolyLine2D> openings)
 {
     this.isEditing = false;
     Outline        = outline;
     Openings       = openings;
     ArcDiscrAngle  = Math.PI / 12;            // 15 degrees
 }
Example #5
0
 /// <summary>
 /// Creates region and sets its outline by passed polyline
 /// </summary>
 /// <param name="outline">outline of the region</param>
 public Region2D(IPolyLine2D outline)
 {
     this.isEditing = false;
     Outline        = outline;
     Openings       = new ObservableList <IPolyLine2D>();
     ArcDiscrAngle  = Math.PI / 12;            // 15 degrees
 }
Example #6
0
        public static Polyline Convert(this IPolyLine2D source, Point?origin = null)
        {
            var   segments = new List <Segment>(source.Segments.Count + 1);
            Point start    = source.StartPoint;

            if (origin.HasValue)
            {
                start = new Point(start.X - origin.Value.X, start.Y - origin.Value.Y);
            }
            segments.Add(Segment.StartPoint(start.X, start.Y));
            foreach (var s in source.Segments)
            {
                segments.Add(s.Convert(ref start, origin));
                start = s.EndPoint;
                if (origin.HasValue)
                {
                    start = new Point(start.X - origin.Value.X, start.Y - origin.Value.Y);
                }
            }

            var target = new Polyline {
                Segments = segments,
            };

            return(target);
        }
Example #7
0
        internal static IPolygon2D ToPolygon2D(IPolyLine2D polyline, int numberOfArcTiles = 2)
        {
            var discr = new PolyLine2DDiscretizator {
                Angle = 180, NumberOfArcTiles = numberOfArcTiles, LengthOfTile = double.PositiveInfinity,
            };
            IPolygon2D polygon = new Polygon2D();

            discr.Discretize(polyline, ref polygon, null);
            return(polygon);
        }
        public void Add(IPolyLine2D polyline, PolyType type)
        {
            if (!this.containsCircArc)
            {
                this.containsCircArc |= polyline.Segments.FirstOrDefault(s => s is CircularArcSegment2D) != null;
            }

            var p = CreatePolygon(polyline, this.Discretizator, false);

            this.clipper.AddPath(p, type, polyline.IsClosed);
        }
Example #9
0
        public static Rect2D Boundary(this IPolyLine2D source)
        {
            Point start = source.StartPoint;
            var   ret   = new Rect2D(start, new Size());

            foreach (var s in source.Segments)
            {
                var sg = s.Convert(ref start);
                ret.Union(sg.GetBoundary(start));
                start = s.EndPoint;
            }
            return(ret);
        }
Example #10
0
        /// <summary>
        /// adds opening in opening list, create new Id for new opening
        /// </summary>
        /// <param name="opening">new opening</param>
        public void AddOpening(IPolyLine2D opening)
        {
            var lastId = 0;

            if (Openings.Count > 0)
            {
                var opLast = Openings.MaxByOrDefault(o => o.Id);
                lastId = opLast != null ? opLast.Id : 0;
            }

            opening.Id = lastId + 1;
            Openings.Add(opening);
        }
        private static bool TrySortSegments(IPolyLine2D pattern, IPolyLine2D polyline, double offset)
        {
            if (pattern.Segments.Count == polyline.Segments.Count && pattern.Segments.Count > 0)
            {
                Point patStart   = pattern.StartPoint;
                var   patSegment = pattern.Segments[0];
                var   patU       = patSegment.EndPoint - patStart;
                patU.Normalize();
                Point start = polyline.StartPoint;
                for (var i = 0; i < polyline.Segments.Count; ++i)
                {
                    var segment = polyline.Segments[i];
                    var u       = segment.EndPoint - start;
                    var t       = Vector.CrossProduct(patU, u);
                    if (t.IsZero(1e-4))
                    {
                        // jsou rovnobezne, zkusime vzdalenost
                        t = GeomTools2D.LineToPointDistance(ref patStart, ref patU, ref start);
                        if (t.IsEqual(System.Math.Abs(offset), 0.001))
                        {
                            // mam segment odpovidajici prvnimu ve vzorove geometrii
                            u.Normalize();
                            if (!u.X.IsEqual(patU.X, 0.1) || !u.Y.IsEqual(patU.Y, 0.1))
                            {
                                // jsou opracne orientovane
                                start = segment.EndPoint;
                                GeomTools2D.ReversePolyline(ref polyline);
                            }

                            if (i == 0)
                            {
                                return(true);
                            }

                            var circ    = polyline.Segments.AsCircular();
                            var rotated = circ.Skip(i).Take(polyline.Segments.Count).ToList();
                            polyline.Segments.Clear();
                            (polyline.Segments as List <ISegment2D>).AddRange(rotated);
                            polyline.StartPoint = start;
                            return(true);
                        }
                    }

                    start = segment.EndPoint;
                }
            }

            return(false);
        }
Example #12
0
        internal static Polygon3D ToPolygon3D(IPolyLine2D outline, IMatrix44 lcs)
        {
            /// pozor - konvertuje pouze koncove body - tzn. zadne obloucky
            var count   = outline.Segments.Count;
            var polygon = new Polygon3D(count + 1);

            var point   = outline.StartPoint;
            var point3D = lcs.TransformToGCS(new WM.Point3D(0, point.X, point.Y));

            polygon.Add(point3D);

            for (var i = 0; i < count; ++i)
            {
                point   = outline.Segments[i].EndPoint;
                point3D = lcs.TransformToGCS(new WM.Point3D(0, point.X, point.Y));
                polygon.Add(point3D);
            }

            return(polygon);
        }
Example #13
0
        public static void SortSegments(IPolyLine2D polyline, IPolyLine2D pattern)
        {
            var patternStart = (Point)pattern.StartPoint;
            var patternCount = pattern.Segments.Count;
            int patternInx = -1, inx = -1;

            for (var i = 0; i < patternCount; ++i)
            {
                var patternSegment = pattern.Segments[i];

                var start = (Point)polyline.StartPoint;
                var count = polyline.Segments.Count;
                for (var j = 0; j < count; ++j)
                {
                    var segment = polyline.Segments[j];

                    if (start.IsEqualWithTolerance(patternStart, 1e-6) &&
                        segment.EndPoint.IsEqualWithTolerance(patternSegment.EndPoint, 1e-6) &&
                        segment.GetType() == patternSegment.GetType())
                    {
                        patternInx = i;
                        inx        = j;
                        break;
                    }

                    start = segment.EndPoint;
                }

                if (inx >= 0)
                {
                    break;
                }

                patternStart = patternSegment.EndPoint;
            }

            if (patternInx != inx)
            {
                GeomTools2D.RotateSegments(polyline, inx - patternInx);
            }
        }
        public static IEnumerable <IPolyLine2D> BuildOffset(IPolyLine2D polyline, double delta, JoinType joinType, EndType endType, double mitterLimit, bool sort = false, double maxDiscretizationAngle = 5)
        {
            PolyLine2DDiscretizator discretizator = new PolyLine2DDiscretizator
            {
                NumberOfTiles = 1,
                LengthOfTile  = double.MaxValue,
                Angle         = maxDiscretizationAngle
            };
            var p = CreatePolygon(polyline, discretizator, true);

            bool containsCircArc = joinType == JoinType.jtRound || endType == EndType.etOpenRound;

            if (!containsCircArc)
            {
                containsCircArc = polyline.Segments.FirstOrDefault(s => s is CircularArcSegment2D) != null;
            }

            var co = new ClipperOffset(mitterLimit);

            co.AddPath(p, joinType, endType);
            var solution = new List <List <IntPoint> >();

            co.Execute(ref solution, delta * ClipperScale);
            if (sort && polyline.IsClosed && !containsCircArc && joinType == JoinType.jtMiter && (endType == EndType.etClosedLine || endType == EndType.etClosedPolygon) && solution.Count == 1)
            {
                // try to sort offset path according to source path
                var newPolyline = CreatePolyline(solution[0], containsCircArc, maxDiscretizationAngle + 1);
                TrySortSegments(polyline, newPolyline, delta);
                yield return(newPolyline);
            }
            else
            {
                foreach (var polygon in solution)
                {
                    yield return(CreatePolyline(polygon, containsCircArc, maxDiscretizationAngle + 1));
                }
            }
        }
        /// <summary>
        /// Discretize of <c>PolyLine2D</c> to <c>Polygon2D</c>.
        /// </summary>
        /// <param name="source">The <c>PolyLine2D</c> to discretization.</param>
        /// <param name="target">The <c>Polygon2D</c> as destination.</param>
        /// <param name="targetInxs">The <c>IList</c> as destination.</param>
        public void Discretize(IPolyLine2D source, ref IPolygon2D target, IList <int> targetInxs)
        {
            if (source == null)
            {
                return;
            }

            Point start = source.StartPoint;

            target.Add(start);
            int i       = 0;
            int lastInx = 0;

            foreach (var segment in source.Segments)
            {
                SelectSegment2DDiscretizator(segment.GetType()).Discretize(start, segment, target);
                start = segment.EndPoint;
                if (targetInxs != null)
                {
                    for (int j = lastInx; j < target.Count; j++)
                    {
                        targetInxs.Add(i);
                    }

                    lastInx = target.Count;
                }

                i++;
            }

            if (targetInxs != null)
            {
                if (source.IsClosed && (targetInxs.Count > 0))
                {
                    targetInxs[0] = targetInxs[targetInxs.Count - 1];
                }
            }
        }
Example #16
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);
        }
Example #17
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);
        }