Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
                }
            }
        }
Пример #3
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);
        }
Пример #4
0
        /// <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);
        }