/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }