/// <summary> /// Calculate intersection point of two line. /// </summary> /// <param name="source"></param> /// <param name="target"></param> /// <returns></returns> public static IntersectionInfo InsersectLines(Line source, Line target) { var points = new Point3dCollection(); source.IntersectWith(target, Intersect.ExtendBoth, 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 intersectPoint = points[0]; var sourceLineSegment = new LineSegment3d(source.StartPoint, source.EndPoint); var targetLineSegment = new LineSegment3d(target.StartPoint, target.EndPoint); var sourceParam = sourceLineSegment.GetParameterOf(intersectPoint); var sourceExtendType = ParamToExtendTypeForLine(sourceParam); var targetParam = targetLineSegment.GetParameterOf(intersectPoint); var targetExtendType = ParamToExtendTypeForLine(targetParam); var result = new IntersectionInfo(sourceExtendType, targetExtendType, intersectPoint); return(result); }
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 bool CheckIntersectionInfo(IntersectionInfo info, ExtendType desiredSourceExtendType, Point3d sourcePoint, ExtendType desiredTargetExtendType, Point3d targetPoint, double tolerance) { if (info.SourceExtendType != desiredSourceExtendType) { return(false); } if (info.TargetExtendType != desiredTargetExtendType) { return(false); } var dist = (sourcePoint - info.IntersectPoint).Length; if (dist.Larger(tolerance)) { return(false); } dist = (targetPoint - info.IntersectPoint).Length; if (dist.Larger(tolerance)) { return(false); } return(true); }
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 IntersectionInfo GetUnderShootIntersection(CurveVertex vertex, Transaction transaction, double tolerance) { var curve = transaction.GetObject(vertex.Id, OpenMode.ForRead); var desiredExtend = CurveUtils.GetExtendType((Curve)curve, vertex.Point); var line = curve as Line; var arc = curve as Arc; var polyline = curve as Polyline; var polyline2d = curve as Polyline2d; if (polyline != null) { line = CurveUtils.CutOutLineFromPolyLine(polyline, vertex.Point); } else if (polyline2d != null) { line = CurveUtils.CutOutLineFromPolyline2d(polyline2d, vertex.Point, transaction); } // Construct a polygon to get adjacent entities. Point3dCollection polygon = null; if (line != null) { var direction = line.EndPoint - line.StartPoint; if (desiredExtend == ExtendType.ExtendStart) { direction = -1.0 * direction; } polygon = BuildSelectionPolygonForLine(vertex.Point, direction, tolerance); } else if (arc != null) { polygon = BuildSelectionPolygonForArc(vertex.Point, tolerance); } // Zoom window var minPt = new Point3d(vertex.Point.X - tolerance, vertex.Point.Y - tolerance, 0.0); var maxPt = new Point3d(vertex.Point.X + tolerance, vertex.Point.Y + tolerance, 0.0); var extents = new Extents3d(minPt, maxPt); Editor.ZoomToWin(extents, factor: 2.0); var selectionResult = Editor.SelectCrossingPolygon(polygon, SelectionFilterUtils.OnlySelectCurve()); if (selectionResult.Status != PromptStatus.OK || selectionResult.Value == null) { return(null); } // Check each adjacent entity whether they are intersected. var intersectionInfos = new List <IntersectionInfo>(); var adjacentIds = selectionResult.Value.GetObjectIds(); foreach (ObjectId objId in adjacentIds) { var targetCurve = transaction.GetObject(objId, OpenMode.ForRead) as Curve; if (targetCurve == null) { continue; } // Calculate the intersection IntersectionInfo info = null; if (line != null) { info = IntersectLineAndCurve(line, targetCurve, vertex.Point, desiredExtend); } else if (arc != null) { info = IntersectArcAndCurve(arc, targetCurve, vertex.Point, desiredExtend); } if (info != null && info.SourceExtendType == desiredExtend) { info.SourceId = vertex.Id; info.TargetId = objId; intersectionInfos.Add(info); } } // Get nearest point. if (intersectionInfos.Count <= 0) { return(null); } var nearest = intersectionInfos[0]; var nearsetDist = (intersectionInfos[0].IntersectPoint - vertex.Point).Length; for (int i = 1; i < intersectionInfos.Count; i++) { var dist = (intersectionInfos[i].IntersectPoint - vertex.Point).Length; if (dist < nearsetDist) { nearsetDist = dist; nearest = intersectionInfos[i]; } } if (nearsetDist.Larger(tolerance)) { return(null); } return(nearest); }