Ejemplo n.º 1
0
        private IntersectionInfo CreateRealIntersectionInfo(BspSplitInfo info, Point2d point, ObjectId targetId, HashSet <CurveVertex> vertexIntersects)
        {
            var extendType = CurveIntersectUtils.ParamToExtendTypeForLine(info.SourceParam);

            if (extendType != ExtendType.None)
            {
                return(null);
            }

            // Self intersection
            if ((info.SourceParam.EqualsWithTolerance(0.0) || info.SourceParam.EqualsWithTolerance(1.0)) &&
                info.SourceSegment.EntityId == targetId)
            {
                // Need to take care of a special case:
                // Polyline AEB and CED intersect at E point
                //     A\  D
                //       \ |
                //        \|_________B
                //      C / E

                var vertexIntersect = new CurveVertex(new Point3d(point.X, point.Y, 0.0), info.SourceSegment.EntityId);
                // More than two intersects, then it's a self intersection.
                if (vertexIntersects.Contains(vertexIntersect))
                {
                    var intersection = new IntersectionInfo(info.SourceSegment.EntityId, ExtendType.None, targetId,
                                                            ExtendType.None, new Point3d(point.X, point.Y, 0.0));

                    return(intersection);
                }

                vertexIntersects.Add(vertexIntersect);
                return(null);
            }
            else
            {
                var intersection = new IntersectionInfo(info.SourceSegment.EntityId, ExtendType.None, targetId,
                                                        ExtendType.None, new Point3d(point.X, point.Y, 0.0));

                return(intersection);
            }
        }
Ejemplo n.º 2
0
        private void SplitSegment(BspSegment sourceSegment, BspSegment targetSegment,
                                  out BspSegment left, out BspSegment right, out BspSegment inline,
                                  out double startVal, out double endVal)
        {
            left     = null;
            right    = null;
            inline   = null;
            startVal = 0.0;
            endVal   = 0.0;

            var sourceStart = sourceSegment.LineSegment.StartPoint;
            var sourceEnd   = sourceSegment.LineSegment.EndPoint;

            var targetStart = targetSegment.LineSegment.StartPoint;
            var targetEnd   = targetSegment.LineSegment.EndPoint;

            // We need to make sure targetSegment is not a point
            if (targetStart == targetEnd)
            {
                return;
            }

            // Allan: I found IsLeft is not good to determine whether a point is left or right
            // if the segment is too long, so divide it by length.
            var sourceLength = sourceSegment.LineSegment.Length;
            var targetLength = targetSegment.LineSegment.Length;
            var length       = sourceLength + targetLength;

            startVal = IsLeft(sourceStart, sourceEnd, targetStart) / length;
            endVal   = IsLeft(sourceStart, sourceEnd, targetEnd) / length;

            //// For fixing some error by small values.
            //using (var switcher = new SafeToleranceOverride(0.0005, 0.0005))
            //{
            //    if (targetStart.IsEqualTo(sourceStart) || targetStart.IsEqualTo(sourceEnd))
            //        startVal = 0.0;
            //    if (targetEnd.IsEqualTo(sourceStart) || targetEnd.IsEqualTo(sourceEnd))
            //        endVal = 0.0;
            //}

            // Left
            if (startVal.EqualsWithTolerance(0.0) && endVal.EqualsWithTolerance(0.0))
            {
                inline = targetSegment;
            }
            else if (startVal.Larger(0.0) && endVal.Larger(0.0))
            {
                left = targetSegment;
            }
            else if (startVal.Smaller(0.0) && endVal.Smaller(0.0))
            {
                right = targetSegment;
            }
            else if (startVal.EqualsWithTolerance(0.0))
            {
                var sourceParam = sourceSegment.LineSegment.GetParameterOf(targetStart);
                var splitInfos  = new List <BspSplitInfo>();
                if (targetSegment.StartSplitInfos != null && targetSegment.StartSplitInfos.Any())
                {
                    splitInfos.AddRange(targetSegment.StartSplitInfos);
                }

                splitInfos.Add(new BspSplitInfo()
                {
                    IsSplitted    = false,
                    SourceSegment = sourceSegment,
                    SourceParam   = sourceParam
                });
                targetSegment.StartSplitInfos = splitInfos.ToArray();

                if (endVal.Larger(0.0))
                {
                    left = targetSegment;
                }
                else
                {
                    right = targetSegment;
                }
            }
            else if (endVal.EqualsWithTolerance(0.0))
            {
                var sourceParam = sourceSegment.LineSegment.GetParameterOf(targetEnd);
                var splitInfos  = new List <BspSplitInfo>();
                if (targetSegment.EndSplitInfos != null && targetSegment.EndSplitInfos.Any())
                {
                    splitInfos.AddRange(targetSegment.EndSplitInfos);
                }

                splitInfos.Add(new BspSplitInfo()
                {
                    IsSplitted    = false,
                    SourceSegment = sourceSegment,
                    SourceParam   = sourceParam
                });
                targetSegment.EndSplitInfos = splitInfos.ToArray();

                if (startVal.Larger(0.0))
                {
                    left = targetSegment;
                }
                else
                {
                    right = targetSegment;
                }
            }
            else
            {
                // Split
                var line2d = new Line2d(sourceStart, sourceEnd);
                var points = line2d.IntersectWith(targetSegment.LineSegment);
                if (points != null && points.Length > 0)
                {
                    // Only one intersect point here.
                    var intersect    = points[0];
                    var segmentStart = new LineSegment2d(targetStart, intersect);
                    var segmentEnd   = new LineSegment2d(intersect, targetEnd);
                    // 如果segmentStart过短,就认为交点是targetStart。
                    // 否则在计算过程中就会矫枉过正,导致本不是相交点的地方成为相交点
                    if (segmentStart.Length.SmallerOrEqual(DoubleExtensions.STolerance))
                    {
                        if (endVal.EqualsWithTolerance(0.0))
                        {
                            inline = targetSegment;
                        }
                        else if (endVal.Larger(0.0))
                        {
                            left = targetSegment;
                        }
                        else if (endVal.Smaller(0.0))
                        {
                            right = targetSegment;
                        }
                    }
                    else if (segmentEnd.Length.SmallerOrEqual(DoubleExtensions.STolerance))
                    {
                        if (startVal.EqualsWithTolerance(0.0))
                        {
                            inline = targetSegment;
                        }
                        else if (startVal.Larger(0.0))
                        {
                            left = targetSegment;
                        }
                        else if (startVal.Smaller(0.0))
                        {
                            right = targetSegment;
                        }
                    }
                    else
                    {
                        var sourceParam = sourceSegment.LineSegment.GetParameterOf(intersect);
                        var splitInfo   = new BspSplitInfo()
                        {
                            SourceSegment = sourceSegment,
                            SourceParam   = sourceParam
                        };

                        BspSegment templeft = null;
                        if (segmentStart.Length.Larger(0.0))
                        {
                            templeft = new BspSegment()
                            {
                                LineSegment     = segmentStart,
                                EntityId        = targetSegment.EntityId,
                                StartSplitInfos = targetSegment.StartSplitInfos,
                                EndSplitInfos   = new BspSplitInfo[] { splitInfo },
                                OriginalSegment = targetSegment
                            };
                        }

                        BspSegment tempRight = null;
                        if (segmentEnd.Length.Larger(0.0))
                        {
                            tempRight = new BspSegment()
                            {
                                LineSegment     = segmentEnd,
                                EntityId        = targetSegment.EntityId,
                                StartSplitInfos = new BspSplitInfo[] { splitInfo },
                                EndSplitInfos   = targetSegment.EndSplitInfos,
                                OriginalSegment = targetSegment
                            };
                        }

                        if (startVal.LargerOrEqual(0.0))
                        {
                            left  = templeft;
                            right = tempRight;
                        }
                        else
                        {
                            left  = tempRight;
                            right = templeft;
                        }
                    }
                }
                else
                {
                    // 如果没有任何交点,我们就认为它是inline的,因为往往因为计算精度,
                    // 导致startVal和endVal的值在0.001左右,但是用IntersectWith计算不出任何交点
                    inline = targetSegment;
                }
            }
        }