コード例 #1
0
        /// <summary>
        /// Calculates LCS matrix of the plane of region according to points
        /// </summary>
        /// <param name="region">region of the plane</param>
        /// <returns>Matrix44 of LCS</returns>
        public static IMatrix44 GetMatrixPlane(IRegion3D region)
        {
            if (region == null)
            {
                return(null);
            }

            ISegment3D firstSeg     = region.Outline[0];
            Vector3D   firstVec     = Subtract(firstSeg.StartPoint, firstSeg.EndPoint);
            IPoint3D   pointInPlane = null;

            // loop for 1 not 0
            for (int i = 1; i < region.Outline.Count; i++)
            {
                ISegment3D nextSeg = region.Outline[i];
                Vector3D   nextVec = Subtract(nextSeg.StartPoint, nextSeg.EndPoint);
                if (!IsCollinear(firstVec, nextVec, MathConstants.ZeroWeak))
                {
                    pointInPlane = nextSeg.EndPoint;
                    break;
                }
            }

            if (pointInPlane != null)
            {
                return(GetLCSMatrix(firstSeg.StartPoint, firstSeg.EndPoint, pointInPlane, Plane.XY));
            }

            return(new Matrix44());
        }
コード例 #2
0
        /// <summary>
        /// creates a polyline from another polyline
        /// </summary>
        /// <param name="source">Source polyline</param>
        public PolyLine3D(IPolyLine3D source)
        {
            if (source != null)
            {
                Name     = (source as ElementBase).Name;
                segments = new List <ISegment3D>();

                if (source.Segments != null)
                {
                    IPoint3D point = null;
                    foreach (ISegment3D segment in source.Segments)
                    {
                        ISegment3D seg = segment.CloneSegment();
                        if (point != null)
                        {
                            seg.StartPoint = point;
                        }

                        point = seg.EndPoint;
                        Add(seg);
                    }

                    if (source.IsClosed && segments.Count > 0)
                    {
                        segments[segments.Count - 1].EndPoint = segments[0].StartPoint;
                    }
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Removes a specific segment from the polyline, adaptes shorter segment
        /// </summary>
        /// <param name="segment">The object to remove from the polyline.</param>
        /// <returns>Index of the removed segment</returns>
        public int RemoveAdaptShorter(ISegment3D segment)
        {
            UnsubscribeEventsFromSegment(segment);
            int indexOfDelSegment = segments.IndexOf(segment);

            RemoveAtAdaptShorter(indexOfDelSegment);
            return(indexOfDelSegment);
        }
コード例 #4
0
        public static ISegment2D ConvertTo2D(ISegment3D segment3D, IMatrix44 lcs)
        {
            var segmentCopy = segment3D.CloneSegment();

            GeomOperation.TransformToLCS(lcs, segmentCopy);
            var segment2D = ConvertTo2D(segmentCopy);

            return(segment2D);
        }
コード例 #5
0
        /// <summary>
        /// Gets direction of the begin and end point of the segment (normalized)
        /// </summary>
        /// <param name="src">Segment</param>
        /// <returns>Direction</returns>
        public static WM.Vector3D GetDirection(this ISegment3D src)
        {
            var temp = new WM.Vector3D(src.EndPoint.X - src.StartPoint.X,
                                       src.EndPoint.Y - src.StartPoint.Y,
                                       src.EndPoint.Z - src.StartPoint.Z);

            temp.Normalize();
            return(temp);
        }
コード例 #6
0
 /// <summary>
 /// Create a segment as a copy of another
 /// </summary>
 /// <param name="source">Source segment</param>
 public Segment3D(ISegment3D source)
 {
     if (source != null)
     {
         startPoint = new Point3D(source.StartPoint.X, source.StartPoint.Y, source.StartPoint.Z);
         endPoint   = new Point3D(source.EndPoint.X, source.EndPoint.Y, source.EndPoint.Z);
         (source as Segment3D).LocalCoordinateSystem.CopyTo(ref localCoordinateSystem);
         SubscribePointEvents();
     }
 }
コード例 #7
0
        /// <summary>
        /// Unsubscribe Events From given segment
        /// </summary>
        /// <param name="segment"></param>
        protected void UnsubscribeEventsFromSegment(ISegment3D segment)
        {
            //ElementBase elementSegment = segment as ElementBase;
            //if (elementSegment == null)
            //{
            //  return;
            //}

            ////elementSegment.ObjectChanged -= new ObjectChangedEventHandler(OnGeometryChanged);
            ////elementSegment.ObjectLinked -= new ObjectLinkedEventHandler(OnObjectLinked);
            //PropertyChangedEventManager.RemoveListener(elementSegment, this);
        }
コード例 #8
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);
        }
コード例 #9
0
        /// <summary>
        /// Inserts <paramref name="segmentToInsert"/> after <paramref name="baseSegment"/>.
        /// If <paramref name="baseSegment"/> in not in the polyline exception is thrown.
        /// </summary>
        /// <param name="baseSegment"></param>
        /// <param name="segmentToInsert"></param>
        public void InsertSegmentAfterSegment(ISegment3D baseSegment, ISegment3D segmentToInsert)
        {
            int baseSegmentIndex = segments.IndexOf(baseSegment);

            if (baseSegmentIndex == -1)
            {
                throw new ArgumentException("PolyLine3D InsertAfter : Segment not found");
            }

            baseSegment.EndPoint = segmentToInsert.StartPoint;

            segments.Insert(baseSegmentIndex + 1, segmentToInsert);
            SubscribeEventsFromSegment(segmentToInsert);
        }
コード例 #10
0
        private static ISegment2D ConvertTo2D(ISegment3D segment3D)
        {
            if (segment3D.SegmentType == SegmentType.Line)
            {
                LineSegment2D lineSegment2D = new LineSegment2D(new Point(segment3D.EndPoint.X, segment3D.EndPoint.Y));
                return(lineSegment2D);
            }
            else if (segment3D.SegmentType == SegmentType.CircularArc)
            {
                CircularArcSegment2D arcSegment2D = new CircularArcSegment2D(new Point(segment3D.EndPoint.X, segment3D.EndPoint.Y), new Point((segment3D as IArcSegment3D).IntermedPoint.X, (segment3D as IArcSegment3D).IntermedPoint.Y));
                return(arcSegment2D);
            }

            return(null);
        }
コード例 #11
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);
        }
コード例 #12
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);
        }
コード例 #13
0
        /// <summary>
        /// Convert the points of segment based on baseGeometry
        /// </summary>
        /// <param name="matrix">LCS matrix of baseGeometry</param>
        /// <param name="baseGeometry">Based on this region, the given segment is modifed</param>
        /// <param name="segment">Input segment object</param>
        /// <param name="isIndependent">Segment is independent</param>
        /// <param name="modifyInput">If true, given segment object is modified. Otherwise prepare new segment object</param>
        /// <returns>Segment object which is based on baseGeometry</returns>
        public static ISegment3D GetSegmentOnRegion(IMatrix44 matrix, IRegion3D baseGeometry, ISegment3D segment, bool isIndependent = true, bool modifyInput = true)
        {
            if (baseGeometry == null || segment == null)
            {
                return(null);
            }

            if (matrix == null)
            {
                matrix = GetMatrixPlane(baseGeometry);
            }

            if (!modifyInput)
            {
                segment = segment.CloneSegment();
            }

            ILineSegment3D line = segment as ILineSegment3D;

            if (line != null)
            {
                if (isIndependent)
                {
                    line.StartPoint = GetPointOnRegion(matrix, baseGeometry, line.StartPoint);
                }

                line.EndPoint = GetPointOnRegion(matrix, baseGeometry, line.EndPoint);
                return(line);
            }

            IArcSegment3D arc = segment as IArcSegment3D;

            if (arc != null)
            {
                if (isIndependent)
                {
                    arc.StartPoint = GetPointOnRegion(matrix, baseGeometry, arc.StartPoint);
                }

                arc.IntermedPoint = GetPointOnRegion(matrix, baseGeometry, arc.IntermedPoint);
                arc.EndPoint      = GetPointOnRegion(matrix, baseGeometry, arc.EndPoint);
                return(arc);
            }

            throw new NotSupportedException();
        }
コード例 #14
0
 /// <summary>
 /// Insert a segment to the collection at the specified index
 /// </summary>
 /// <param name="index">The zero based index at which item should be inserted</param>
 /// <param name="item">The segment to insert into the collection</param>
 public void Insert(int index, ISegment3D item)
 {
     segments.Insert(index, item);
     SubscribeEventsFromSegment(item);
 }
コード例 #15
0
 /// <summary>
 /// Add a segment to polyline
 /// </summary>
 /// <param name="segment">New segment to be added</param>
 public void Add(ISegment3D segment)
 {
     segments.Add(segment);
     SubscribeEventsFromSegment(segment);
 }
コード例 #16
0
 /// <summary>
 /// Get StraightLine which connects start and end point of the <paramref name=""/>
 /// </summary>
 /// <param name="seg"></param>
 /// <returns>StraightLine</returns>
 public static StraightLine GetStraightLine(this ISegment3D seg)
 {
     return(new StraightLine(seg.StartPoint, seg.EndPoint));
 }