/// <summary> /// Convert the points of polyline based on baseGeometry /// </summary> /// <param name="matrix">LCS matrix of baseGeometry</param> /// <param name="baseGeometry">Based on this region, the given polyline is modifed</param> /// <param name="polyline">Input polyline object</param> /// <param name="modifyInput">If true, given polyline object is modified. Otherwise prepare new polyline object</param> /// <returns>Polyline object which is based on baseGeometry</returns> public static IPolyLine3D GetPolylineOnRegion(IMatrix44 matrix, IRegion3D baseGeometry, IPolyLine3D polyline, bool modifyInput = true) { if (baseGeometry == null || polyline == null) { return(null); } if (matrix == null) { matrix = GetMatrixPlane(baseGeometry); } if (!modifyInput) { polyline = new PolyLine3D(polyline); } bool isIndependent = true; if (polyline.IsClosed) { isIndependent = false; } ISegment3D firstSegment = null; IPoint3D lastEndPoint = null; foreach (ISegment3D segment in polyline.Segments) { GetSegmentOnRegion(matrix, baseGeometry, segment, isIndependent); if (lastEndPoint != null) { segment.StartPoint = lastEndPoint; } if (firstSegment == null) { firstSegment = segment; } lastEndPoint = segment.EndPoint; isIndependent = false; } if (firstSegment != null && lastEndPoint != null) { firstSegment.StartPoint = lastEndPoint; } return(polyline); }
/// <summary> /// Creates a region from another one /// </summary> /// <param name="source">Source region</param> public Region3D(IRegion3D source) { if (source != null) { Name = (source as ElementBase).Name; Outline = new PolyLine3D(source.Outline); if (source.Openings != null) { openings = new List <IPolyLine3D>(); foreach (IPolyLine3D opening in source.Openings) { AddOpening(new PolyLine3D(opening)); } } if (source.LCS != null) { this.LCS = new CoordSystemByVector(source.LCS); } } }
/// <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); }
/// <summary> /// Calculate inner partial polyline by intersecting region and polyline /// </summary> /// <param name="region">IRegion3D</param> /// <param name="innerPolyline">Polyline3D used to calculate inner partial polyline</param> /// <param name="innerPolylineList">List of inner partial polyline prepared from the given polygon and polyline</param> /// <returns>IntersectionResults</returns> public static IntersectionResults Intersect(IRegion3D region, IPolyLine3D innerPolyline, ICollection <IPolyLine3D> innerPolylineList) { if (region == null || innerPolyline == null || innerPolylineList == null) { return(IntersectionResults.Undefined); } IPolyLine3D outerPolyline = region.Outline; List <IPoint3D> listOfIntersectionPoint = new List <IPoint3D>(); Intersect(outerPolyline, innerPolyline, listOfIntersectionPoint); foreach (IPolyLine3D opening in region.Openings) { Intersect(opening, innerPolyline, listOfIntersectionPoint); } if (listOfIntersectionPoint.Count < 1) { IPoint3D point = GetPointOnPolyLine(innerPolyline, 0.5); return(IsPointOn(region, point)); } SortedSet <double> relativePositionSet = new SortedSet <double>(); relativePositionSet.Add(0); relativePositionSet.Add(1); foreach (IPoint3D point in listOfIntersectionPoint) { double relativePosition = 0; if (GetRelativePosition(innerPolyline, point, ref relativePosition)) { if (!relativePositionSet.Contains(relativePosition)) { relativePositionSet.Add(relativePosition); } } } IList <ISegment3D> splittedSegments = SplitPolyline(innerPolyline, relativePositionSet); if (splittedSegments == null) { return(IntersectionResults.Undefined); } IntersectionResults interSectionResult = IntersectionResults.Undefined; foreach (ISegment3D segment in splittedSegments) { IPoint3D point = new Point3D(); if (GetPointOnSegment(segment, 0.5, ref point)) { IntersectionResults result = IsPointOn(region, point); interSectionResult |= result; if (result == IntersectionResults.Inside || result == IntersectionResults.OnBorderCurve) { IPolyLine3D polyline = new PolyLine3D(); if (innerPolylineList.Count < 1) { polyline.Add(segment); } else { IPolyLine3D existingPolyline = innerPolylineList.Last(); if (existingPolyline.Count < 1) { polyline.Add(segment); } else { if (existingPolyline.Count > 1) { ISegment3D lastSegment = existingPolyline.Segments.Last(); if (lastSegment.EndPoint.Equals(segment.StartPoint)) { polyline = existingPolyline; } } polyline.Add(segment); } } if (!innerPolylineList.Contains(polyline)) { innerPolylineList.Add(polyline); } } } } if (innerPolylineList.Count < 1) { return(IntersectionResults.OnBorderNode | IntersectionResults.Outside); } return(interSectionResult); }