private IntersectionInfo IntersectLineAndCurve(Line line, Curve curve, Point3d sorucePoint, ExtendType desireExtendType)
        {
            var points = new Point3dCollection();

            line.IntersectWith(curve, Intersect.ExtendThis, points, IntPtr.Zero, IntPtr.Zero);
            if (points.Count == 0)
            {
                return(null);
            }

            // NOTE: Use Line's GetParameterAtPoint will throw exception if the intersect point is
            // on the line's extension, but LineSegment3d.GetParameterOf is available, so I convert
            // the Line to LineSegment3d here.
            var     lineSegment  = new LineSegment3d(line.StartPoint, line.EndPoint);
            Point3d?nearestPoint = null;
            double? nearestDist  = null;

            foreach (Point3d point in points)
            {
                var param      = lineSegment.GetParameterOf(point);
                var extendType = CurveIntersectUtils.ParamToExtendTypeForLine(param);
                if (extendType != desireExtendType)
                {
                    continue;
                }

                var dist = (point - sorucePoint).LengthSqrd;
                if (nearestDist == null || dist < nearestDist.Value)
                {
                    nearestDist  = dist;
                    nearestPoint = point;
                }
            }

            IntersectionInfo result = null;

            if (nearestPoint != null)
            {
                result = new IntersectionInfo(desireExtendType, ExtendType.None, nearestPoint.Value);
            }
            return(result);
        }
        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);
            }
        }
        private IntersectionInfo IntersectArcAndCurve(Arc arc, Curve curve, Point3d point, ExtendType?coerceArcExtendType)
        {
            var points = new Point3dCollection();

            arc.IntersectWith(curve, Intersect.ExtendThis, points, IntPtr.Zero, IntPtr.Zero);
            if (points.Count <= 0)
            {
                return(null);
            }

            // Get the nearest point
            var nearsetPoint = points[0];
            var dist         = (point - nearsetPoint).LengthSqrd;

            for (int i = 1; i < points.Count; i++)
            {
                var newDist = (points[i] - point).LengthSqrd;
                if (newDist < dist)
                {
                    nearsetPoint = points[i];
                    dist         = newDist;
                }
            }

            // Calculate extend type
            if (coerceArcExtendType == null)
            {
                var circularArc = new CircularArc3d(arc.Center, arc.Normal, arc.Normal.GetPerpendicularVector(), arc.Radius,
                                                    arc.StartAngle, arc.EndAngle);
                var arcParam = circularArc.GetParameterOf(nearsetPoint);
                coerceArcExtendType = CurveIntersectUtils.ParamToExtendTypeForArc(circularArc, arcParam, null);
            }

            var result = new IntersectionInfo(coerceArcExtendType.Value, ExtendType.None, nearsetPoint);

            return(result);
        }
        private IntersectionInfo CalcApparentIntersection(CurveVertex source, CurveVertex target, Transaction transaction)
        {
            var sourceEntity = transaction.GetObject(source.Id, OpenMode.ForRead);
            var targetEntity = transaction.GetObject(target.Id, OpenMode.ForRead);

            // Source curve
            var desiredSourceExtend = CurveUtils.GetExtendType((Curve)sourceEntity, source.Point);
            var sourceLine          = sourceEntity as Line;
            var sourceArc           = sourceEntity as Arc;
            var sourcePolyline      = sourceEntity as Autodesk.AutoCAD.DatabaseServices.Polyline;
            var sourcePolyline2d    = sourceEntity as Polyline2d;

            if (sourcePolyline != null)
            {
                sourceLine = CurveUtils.CutOutLineFromPolyLine(sourcePolyline, source.Point);
            }
            else if (sourcePolyline2d != null)
            {
                sourceLine = CurveUtils.CutOutLineFromPolyline2d(sourcePolyline2d, source.Point, transaction);
            }

            // Target curve
            var desiredTargetExtend = CurveUtils.GetExtendType((Curve)targetEntity, target.Point);
            var targetLine          = targetEntity as Line;
            var targetArc           = targetEntity as Arc;
            var targetPolyline      = targetEntity as Autodesk.AutoCAD.DatabaseServices.Polyline;
            var targetPolyline2d    = targetEntity as Polyline2d;

            if (targetPolyline != null)
            {
                targetLine = CurveUtils.CutOutLineFromPolyLine(targetPolyline, target.Point);
            }
            else if (targetPolyline2d != null)
            {
                targetLine = CurveUtils.CutOutLineFromPolyline2d(targetPolyline2d, target.Point, transaction);
            }

            // Calculate intersection.
            var results = new List <IntersectionInfo>();

            if (sourceLine != null && targetLine != null)
            {
                // Line && Line
                var info = CurveIntersectUtils.InsersectLines(sourceLine, targetLine);
                if (info != null)
                {
                    info.SourceId = source.Id;
                    info.TargetId = target.Id;
                    results.Add(info);
                }
            }
            else if (sourceLine != null && targetArc != null)
            {
                // Line && Arc
                var infos = CurveIntersectUtils.IntersectLineArc(sourceLine, targetArc, coerceArcExtendType: desiredTargetExtend);
                foreach (var info in infos)
                {
                    info.SourceId = source.Id;
                    info.TargetId = target.Id;
                }
                results.AddRange(infos);
            }
            else if (sourceArc != null && targetLine != null)
            {
                // Arc && Line
                var infos = CurveIntersectUtils.IntersectLineArc(targetLine, sourceArc, coerceArcExtendType: desiredSourceExtend);
                foreach (var info in infos)
                {
                    // Exchange entend type.
                    var newInfo = new IntersectionInfo(source.Id, info.TargetExtendType, target.Id,
                                                       info.SourceExtendType, info.IntersectPoint);

                    results.Add(newInfo);
                }
            }
            else if (sourceArc != null && targetArc != null)
            {
                // Arc && Arc
                var infos = CurveIntersectUtils.IntersectArcs(sourceArc, desiredSourceExtend, targetArc,
                                                              desiredTargetExtend);
                foreach (var info in infos)
                {
                    info.SourceId = source.Id;
                    info.TargetId = target.Id;
                }

                results.AddRange(infos);
            }

            IntersectionInfo result = null;

            foreach (var info in results)
            {
                var valid = CheckIntersectionInfo(info, desiredSourceExtend, source.Point, desiredTargetExtend, target.Point, _tolerance);
                if (valid)
                {
                    result = info;
                    break;
                }
            }
            return(result);
        }
        private IEnumerable <IntersectionInfo> GetUnderShootIntersections2(IEnumerable <ObjectId> selectedObjectIds,
                                                                           IEnumerable <CurveVertex> danglingVertices, double tolerance, Transaction transaction)
        {
            if (danglingVertices == null || !danglingVertices.Any())
            {
                return(new List <IntersectionInfo>());
            }

            var intersectMap      = new Dictionary <CurveVertex, List <CurveVertex> >();
            var desireExtendTypes = new Dictionary <CurveVertex, ExtendType>();

            foreach (var vertex in danglingVertices)
            {
                var curve         = transaction.GetObject(vertex.Id, OpenMode.ForRead);
                var desiredExtend = CurveUtils.GetExtendType((Curve)curve, vertex.Point);
                desireExtendTypes[vertex] = desiredExtend;
            }

            // 创建一个kdtree
            var kdTree = new CurveVertexKdTree <CurveVertex>(danglingVertices, it => it.Point.ToArray(), ignoreZ: true);

            foreach (var objectId in selectedObjectIds)
            {
                var curve = transaction.GetObject(objectId, OpenMode.ForRead) as Curve;
                if (curve == null)
                {
                    continue;
                }

                // 预检
                var curveExtents = curve.GeometricExtents;
                var vertices     = kdTree.BoxedRange(curveExtents.MinPoint.ToArray(), curveExtents.MaxPoint.ToArray());
                if (vertices == null || !vertices.Any())
                {
                    continue;
                }

                var segments             = CurveUtils.GetSegment2dsOfCurve(curve, transaction);
                var segmentsForCollision = segments.Select(it => new CurveSegmentForCollision()
                {
                    LineSegment     = it,
                    EntityId        = objectId,
                    MiniBoundingBox = CurveSegmentForCollision.CreateCollisionBoundingBox(it, tolerance)
                });
                foreach (var curveSegmentForCollision in segmentsForCollision)
                {
                    var extents = curveSegmentForCollision.GetExtents();
                    if (extents == null)
                    {
                        continue;
                    }
                    var minPoint     = extents.Value.MinPoint;
                    var maxPoint     = extents.Value.MaxPoint;
                    var nearVertices = kdTree.BoxedRange(new double[] { minPoint.X, minPoint.Y, 0.0 },
                                                         new double[] { maxPoint.X, maxPoint.Y, 0.0 });

                    if (!nearVertices.Any())
                    {
                        continue;
                    }

                    var boundingBox = curveSegmentForCollision.MiniBoundingBox.ToList();
                    boundingBox.Add(curveSegmentForCollision.MiniBoundingBox[0]);
                    foreach (var curveVertex in nearVertices)
                    {
                        if (!ComputerGraphics.IsInPolygon(boundingBox.ToArray(), new Point2d(curveVertex.Point.X, curveVertex.Point.Y), 4))
                        {
                            continue;
                        }

                        var danglingCurve   = (Curve)transaction.GetObject(curveVertex.Id, OpenMode.ForRead);
                        var danglingSegment = GetExtendLineSegment(danglingCurve, curveVertex.Point, transaction);
                        var danglineLine    = new Line2d(danglingSegment.StartPoint, danglingSegment.EndPoint);
                        var intersectPoints = danglineLine.IntersectWith(curveSegmentForCollision.LineSegment);
                        if (intersectPoints == null || intersectPoints.Length <= 0)
                        {
                            continue;
                        }

                        var intersectPoint2D = intersectPoints[0];
                        var param            = danglingSegment.GetParameterOf(intersectPoint2D);
                        var extendType       = CurveIntersectUtils.ParamToExtendTypeForLine(param);
                        if (extendType != desireExtendTypes[curveVertex])
                        {
                            continue;
                        }

                        var intersectPoint = new Point3d(intersectPoint2D.X, intersectPoint2D.Y, 0);
                        var dist           = (intersectPoint - curveVertex.Point).Length;
                        if (dist.Larger(tolerance))
                        {
                            continue;
                        }

                        List <CurveVertex> intersectList;
                        intersectMap.TryGetValue(curveVertex, out intersectList);
                        if (intersectList == null)
                        {
                            intersectList             = new List <CurveVertex>();
                            intersectMap[curveVertex] = intersectList;
                        }

                        intersectList.Add(new CurveVertex(intersectPoint, curveSegmentForCollision.EntityId));
                    }
                }
            }

            // 分析交点
            var result = new List <IntersectionInfo>();

            foreach (var pair in intersectMap)
            {
                var vertex         = pair.Key;
                var extendVertices = pair.Value;
                var nearest        = extendVertices[0];
                var nearsetDist    = (nearest.Point - vertex.Point).Length;
                for (int i = 1; i < extendVertices.Count; i++)
                {
                    var dist = (extendVertices[i].Point - vertex.Point).Length;
                    if (dist < nearsetDist)
                    {
                        nearsetDist = dist;
                        nearest     = extendVertices[i];
                    }
                }

                result.Add(new IntersectionInfo(vertex.Id, desireExtendTypes[vertex], nearest.Id, ExtendType.None, nearest.Point));
            }
            return(result);
        }
Exemple #6
0
        void SearchNearSegmentsSegmentsOfNode(CurveBspNode node, HashSet <KeyValuePair <BspSegment, BspSegment> > result)
        {
            var segments = node.Segments;

            foreach (var bspSegment in segments)
            {
                var originalestTarget = GetOriginalSourceBspSegment(bspSegment);
                if (bspSegment.StartSplitInfos != null)
                {
                    foreach (var splitInfo in bspSegment.StartSplitInfos)
                    {
                        // Self intersect is ignored.
                        if (splitInfo.SourceSegment.EntityId == bspSegment.EntityId)
                        {
                            continue;
                        }

                        // If not real intersection.
                        var extendType = CurveIntersectUtils.ParamToExtendTypeForLine(splitInfo.SourceParam);
                        if (extendType != ExtendType.None)
                        {
                            continue;
                        }

                        var originalestSource = GetOriginalSourceBspSegment(splitInfo.SourceSegment);
                        if (result.Contains(new KeyValuePair <BspSegment, BspSegment>(originalestSource, originalestTarget)) ||
                            result.Contains(new KeyValuePair <BspSegment, BspSegment>(originalestTarget, originalestSource)))
                        {
                            continue;
                        }

                        result.Add(new KeyValuePair <BspSegment, BspSegment>(originalestSource, originalestTarget));
                    }
                }
                if (bspSegment.EndSplitInfos != null)
                {
                    foreach (var splitInfo in bspSegment.EndSplitInfos)
                    {
                        // Self intersect is ignored.
                        if (splitInfo.SourceSegment.EntityId == bspSegment.EntityId)
                        {
                            continue;
                        }

                        // If not real intersection.
                        var extendType = CurveIntersectUtils.ParamToExtendTypeForLine(splitInfo.SourceParam);
                        if (extendType != ExtendType.None)
                        {
                            continue;
                        }

                        var originalestSource = GetOriginalSourceBspSegment(splitInfo.SourceSegment);
                        if (result.Contains(new KeyValuePair <BspSegment, BspSegment>(originalestSource, originalestTarget)) ||
                            result.Contains(new KeyValuePair <BspSegment, BspSegment>(originalestTarget, originalestSource)))
                        {
                            continue;
                        }

                        result.Add(new KeyValuePair <BspSegment, BspSegment>(originalestSource, originalestTarget));
                    }
                }
            }

            if (node.LeftChild != null)
            {
                SearchNearSegmentsSegmentsOfNode(node.LeftChild, result);
            }

            if (node.RightChild != null)
            {
                SearchNearSegmentsSegmentsOfNode(node.RightChild, result);
            }
        }