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); }
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); } }