Community
Hi everyone. Is it possible in C# to find the intersection point of a spline with a surface in AutoCAD? The surface should be determined based on line in the x,y plane. Thanks in advance for any suggestions.
Hi @a_kloczewiak,
Try to use curve entity instead of spline and look at this post as an exemple :
Dim acCurve As Curve = TryCast(tr.GetObject(per.ObjectId, OpenMode.ForRead), Curve)
https://www.keanw.com/2015/09/intersecting-autocad-curves-with-a-plane-using-net.html
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.Runtime
Imports System
Imports System.Runtime.CompilerServices
Namespace EntityIntersections
Module Extensions
<Extension()>
Function ToArray(ByVal pts As Point3dCollection) As Point3d()
Dim res = New Point3d(pts.Count - 1) {}
pts.CopyTo(res, 0)
Return res
End Function
<Extension()>
Function IntersectWith(ByVal p As Plane, ByVal cur As Curve) As Point3d()
Dim pts = New Point3dCollection()
Dim gcur = cur.GetGeCurve()
Dim proj = TryCast(gcur.GetProjectedEntity(p, p.Normal), Curve3d)
If proj IsNot Nothing Then
Using gcur2 = Curve.CreateFromGeCurve(proj)
cur.IntersectWith(gcur2, Intersect.OnBothOperands, pts, IntPtr.Zero, IntPtr.Zero)
End Using
End If
Return pts.ToArray()
End Function
<Extension()>
Function IsOn(ByVal cv As Curve, ByVal pt As Point3d) As Boolean
Try
Dim p = cv.GetClosestPointTo(pt, False)
Return (p - pt).Length <= Tolerance.[Global].EqualPoint
Catch
End Try
Return False
End Function
End Module
Public Class Commands
<CommandMethod("CPI")>
Public Sub CurvePlaneIntersection()
Dim doc = Application.DocumentManager.MdiActiveDocument
If doc Is Nothing Then Return
Dim db = doc.Database
Dim ed = doc.Editor
Dim peo = New PromptEntityOptions(vbLf & "Select a curve")
peo.SetRejectMessage("Must be a curve.")
peo.AddAllowedClass(GetType(Curve), False)
Dim per = ed.GetEntity(peo)
If per.Status <> PromptStatus.OK Then Return
Dim curId = per.ObjectId
Dim peo2 = New PromptEntityOptions(vbLf & "Select plane surface")
peo.SetRejectMessage("Must be a planar surface.")
peo.AddAllowedClass(GetType(PlaneSurface), False)
Dim per2 = ed.GetEntity(peo2)
If per2.Status <> PromptStatus.OK Then Return
Dim planeId = per2.ObjectId
Using tr = doc.TransactionManager.StartTransaction()
Dim plane = TryCast(tr.GetObject(planeId, OpenMode.ForRead), PlaneSurface)
If plane IsNot Nothing Then
Dim p = plane.GetPlane()
Dim cur = TryCast(tr.GetObject(curId, OpenMode.ForRead), Curve)
If cur IsNot Nothing Then
Dim pts = p.IntersectWith(cur)
Dim ms = CType(tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForWrite), BlockTableRecord)
For Each pt As Point3d In pts
Dim dbp = New DBPoint(pt)
dbp.ColorIndex = 2
ms.AppendEntity(dbp)
tr.AddNewlyCreatedDBObject(dbp, True)
ed.WriteMessage(vbLf & "Point is {0} curve.", If(cur.IsOn(pt), "on", "off"))
Next
End If
End If
tr.Commit()
End Using
End Sub
End Class
End Namespace
Yoan AUBRY
Hi,
Try this way:
[CommandMethod("FindIntersection")]
public void FindIntersectionMethod()
{
var doc = Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
var peo = new PromptEntityOptions("\nSelect a line in the XY plane: ");
peo.SetRejectMessage("\nSelected object must be a line.");
peo.AddAllowedClass(typeof(Line), true);
var per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK)
return;
using (var tr = db.TransactionManager.StartTransaction())
{
var line = (Line)tr.GetObject(per.ObjectId, OpenMode.ForRead);
var direction = line.StartPoint.GetVectorTo(line.EndPoint);
if (direction.Z != 0.0)
{
ed.WriteMessage("\nSelected line is not parallel to XY plane.");
return;
}
peo.Message = "\nSelect a 3D spline: ";
peo.RemoveAllowedClass(typeof(Line));
peo.SetRejectMessage("\nSelected object must be a spline.");
peo.AddAllowedClass(typeof(Spline), true);
per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK)
return;
var spline = (Spline)tr.GetObject(per.ObjectId, OpenMode.ForRead);
var plane = new Plane(line.StartPoint, new Vector3d(-direction.Y, direction.X, 0.0));
var points = new Point3dCollection();
using (var projectedCurve = spline.GetOrthoProjectedCurve(plane))
{
spline.IntersectWith(projectedCurve, Intersect.OnBothOperands, points, IntPtr.Zero, IntPtr.Zero);
}
if (points.Count > 0)
{
foreach (Point3d point in points)
{
ed.WriteMessage($"\nIntersection point: X={point.X}, Y={point.Y}, Z={point.Z}");
}
}
else
{
ed.WriteMessage("\nNo intersection point found.");
}
tr.Commit();
}
}
Can't find what you're looking for? Ask the community or share your knowledge.