예제 #1
0
        /// <summary>
        /// Prepare new region by divide the arc segments into several linear segments
        /// </summary>
        /// <param name="region">IRegion3D</param>
        /// <param name="numberOfParts">Number of linear parts</param>
        /// <returns>New PolyLine3D</returns>
        public static IRegion3D GetLinearSegments(IRegion3D region, int numberOfParts)
        {
            IRegion3D newRegion = new Region3D
            {
                Outline = GetLinearSegments(region.Outline, numberOfParts)
            };

            foreach (IPolyLine3D opening in region.Openings)
            {
                newRegion.AddOpening(GetLinearSegments(opening, numberOfParts));
            }

            return(newRegion);
        }
예제 #2
0
        /// <summary>
        /// Prepare new region by divide the arc segments into several linear segments
        /// </summary>
        /// <param name="region">IRegion3D</param>
        /// <param name="distance">Maximum distance of a line segment which is created from curved segments</param>
        /// <returns>New PolyLine3D</returns>
        public static IRegion3D GetLinearSegments(IRegion3D region, double distance)
        {
            IRegion3D newRegion = new Region3D
            {
                Outline = GetLinearSegments(region.Outline, distance)
            };

            foreach (IPolyLine3D opening in region.Openings)
            {
                newRegion.AddOpening(GetLinearSegments(opening, distance));
            }

            return(newRegion);
        }
예제 #3
0
        /// <summary>
        /// Prepare a region without reflex angles
        /// If any segment exists with reflex angle, divide it into two
        /// </summary>
        /// <param name="region">Region</param>
        /// <returns>New region without reflex angle</returns>
        public static IRegion3D SplitSegmentWithReflexAngle(IRegion3D region)
        {
            if (region == null)
            {
                return(null);
            }

            IRegion3D newRegion = new Region3D
            {
                Outline = SplitSegmentWithReflexAngle(region.Outline)
            };

            foreach (IPolyLine3D opening in region.Openings)
            {
                newRegion.AddOpening(SplitSegmentWithReflexAngle(opening));
            }

            return(newRegion);
        }
예제 #4
0
        /// <summary>
        /// Validates the arc segment in region.
        /// </summary>
        /// <param name="region">IRegion3D</param>
        /// <returns>Validated Region3D</returns>
        public static IRegion3D GetValidRegion(IRegion3D region)
        {
            if (region == null)
            {
                return(null);
            }

            IRegion3D newRegion = new Region3D
            {
                Outline = GetValidPolyLine(region.Outline)
            };

            foreach (IPolyLine3D opening in region.Openings)
            {
                newRegion.AddOpening(GetValidPolyLine(opening));
            }

            return(newRegion);
        }
예제 #5
0
        /// <summary>
        /// Converting Geometry2D.IRegion2D to Geometry3D.IRegion3D
        /// </summary>
        /// <param name="region2D">Geometry2D.IRegion2D</param>
        /// <returns>Geometry3D.IRegion3D</returns>
        public static IRegion3D ConvertTo3D(IRegion2D region2D)
        {
            if (region2D == null)
            {
                return(null);
            }

            var region3D = new Region3D
            {
                Outline = ConvertTo3D(region2D.Outline)
            };

            foreach (var o in region2D.Openings)
            {
                region3D.AddOpening(ConvertTo3D(o));
            }

            return(region3D);
        }
예제 #6
0
        /// <summary>
        /// Create a new region as union of two input regions
        /// </summary>
        /// <param name="a">region a</param>
        /// <param name="b">region b</param>
        /// <param name="result">returns result region = a + b</param>
        /// <returns>false if the operation failed</returns>
        public static bool MergeRegions(IRegion3D a, IRegion3D b, out IRegion3D result)
        {
            List <Tuple <ISegment3D, ISegment3D, bool> > foundPairs = new List <Tuple <ISegment3D, ISegment3D, bool> >();
            var res = new Region3D(a);

            //simple solution - regiony se dotýkají, nepřekrývají
            foreach (var segA in res.Outline.Segments)
            {
                foreach (var segB in b.Outline.Segments)
                {
                    // default used tolerance is too big MathConstants.ZeroGeneral = 1E-10
                    // tolerance to find the same segments is set to 1E-4m = 0.0001m = 0.1mm, maximum sensitivity to find same points on segment is 1E-6 (tested)
                    if (IsEqualWithTolerance(segA, segB, MathConstants.ZeroWeak))
                    {
                        foundPairs.Add(new Tuple <ISegment3D, ISegment3D, bool>(segA, segB, false));
                        break;
                    }
                    else if (IsEqualWithTolerance(segA, Reverse(segB), MathConstants.ZeroWeak))
                    {
                        foundPairs.Add(new Tuple <ISegment3D, ISegment3D, bool>(segA, segB, true));
                        break;
                    }
                }
            }

            if (foundPairs.Any())
            {
                Tuple <ISegment3D, ISegment3D, bool> first = foundPairs[0];
                IPolyLine3D polylineB = new PolyLine3D(b.Outline);
                var         segmentB  = first.Item2;

                if (!first.Item3)
                {
                    polylineB = Reverse(polylineB);
                }

                foreach (var seg in polylineB.Segments)
                {
                    if (IsEqual(segmentB, seg) || IsEqual(segmentB, Reverse(seg)))
                    {
                        segmentB = seg;
                    }
                }

                var polyline = new PolyLine3D();
                int segInx   = GetIndexOfSegment(polylineB, segmentB);
                for (int i = segInx + 1; i < polylineB.Segments.Count(); i++)
                {
                    polyline.Add(polylineB[i].CloneSegment());
                }

                for (int i = 0; i < segInx; i++)
                {
                    polyline.Add(polylineB[i].CloneSegment());
                }

                int resSegInx = GetIndexOfSegment(res.Outline, first.Item1);
                var prevSeg   = GetPreviousSegment(res.Outline, resSegInx);

                ISegment3D baseSeg = prevSeg;
                foreach (var seg in polyline.Segments)
                {
                    res.Outline.InsertSegmentAfterSegment(baseSeg, seg);
                    baseSeg = seg;
                }

                int baseSegInx = GetIndexOfSegment(res.Outline, baseSeg);
                var nextSeg    = GetNextSegment(res.Outline, baseSegInx);
                res.Outline.Remove(nextSeg);

                foreach (var opening in b.Openings)
                {
                    res.AddOpening(opening);
                }

                result = res;
                return(true);
            }

            result = null;
            return(false);
        }