russell84 Posted April 9, 2009 Posted April 9, 2009 im using the following code to get the closest point on a curve along a given vector [size=2] EndPt1 = Curve1.GetClosestPointTo(StartPt1, vector1perp, [/size][size=2][color=#0000ff]False[/color][/size][size=2]) [/size] But it is not getting the closest point on the curve if there is more than one intersect of this vector with the curve. It seems that the code just extends along the vector until it hits the last intersection of curve1 & vector1Perp I thouht the "False" in this code was meant to stop the extention. How can i solve this problem? Its driving me nuts Quote
SEANT Posted April 9, 2009 Posted April 9, 2009 Are you using Curve.GetClosestPointTo Method (Point3d, Vector3d, [MarshalAs(UnmanagedType.U1)] bool)? If so, that vector is used to create a plane on which to project “Curve”. That projected geometry is then processed to find its closet point to “Point3d”. I think the best bet to find the closest point between database resident curve (DBCurve) and a non resident, bounded vector would be: 1. Create an Autodesk.AutoCAD.Geometry.Curve3d based on the DBCurve. * 2. Create an Autodesk.AutoCAD.Geometry.LineSegment3d using the desired properties of the Vector in question. 3. Then use Curve3d.GetClosestPointTo Method (Curve3d), with the LineSegment3d as the passed in parameter. The returned array, PointOnCurve3d[] , will hold one or more objects that can be queried for point locations based on the original DBCurve. * I posted the start of a DBCurve to Geometry Curve class (there are some curve types not yet implemented) on Post #22 of this thread. http://www.cadtutor.net/forum/showthread.php?t=33523 It seems to work well enough though could still use plenty of testing. Quote
russell84 Posted April 13, 2009 Author Posted April 13, 2009 Thanks for the quick reply Seant - i've been trying to do what you have told me but i haven't been able to make it work. Here is the test code that ive written - would you be able to have a look and give me any pointers please. It would be very much appreciated - because as you know i am only recently new to vb.net and am trying to learn with the limited sources available. [size=2][color=#008000] [size=2][color=#008000]'[/color][/size] [/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Option[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Explicit[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]On[/color][/size] [/color][/size][size=2][color=#008000][size=2][color=#008000]'Microsoft Namespaces[/color][/size] [/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Imports[/color][/size][/color][/size][size=2] System.Runtime.InteropServices[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Imports[/color][/size][/color][/size][size=2] System.Runtime.InteropServices.Marshal[/size] [size=2][color=#008000][size=2][color=#008000]'AutoCad Namespaces - pure NET based[/color][/size] [/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Imports[/color][/size][/color][/size][size=2] AcadNet = Autodesk.AutoCAD[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Imports[/color][/size][/color][/size][size=2] AcadNetRuntime = Autodesk.AutoCAD.Runtime[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Imports[/color][/size][/color][/size][size=2] AcadNetAppServices = Autodesk.AutoCAD.ApplicationServices[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Imports[/color][/size][/color][/size][size=2] AcadNetDbServices = Autodesk.AutoCAD.DatabaseServices[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Imports[/color][/size][/color][/size][size=2] AcadNetDBTransman = Autodesk.AutoCAD.DatabaseServices.TransactionManager[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Imports[/color][/size][/color][/size][size=2] AcadNetGeometry = Autodesk.AutoCAD.Geometry[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Imports[/color][/size][/color][/size][size=2] AcadNetEditorInput = Autodesk.AutoCAD.EditorInput[/size] [size=2][color=#008000][size=2][color=#008000]'Civil 3D (related) Namespaces - COM based[/color][/size] [size=2][color=#008000]'Imports AcadCom = Autodesk.AutoCAD.interop[/color][/size] [size=2][color=#008000]'Imports AcadComCommon = autodesk.AutoCAD.interop.common[/color][/size] [/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Imports[/color][/size][/color][/size][size=2] Civil3DCom = Autodesk.AECC.Interop.Land[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Imports[/color][/size][/color][/size][size=2] Civil3DComUI = Autodesk.AECC.Interop.UiLand[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Public[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Class[/color][/size][/color][/size][size=2] NewClass[/size] [size=2]<acadnetruntime.CommandMethodAttribute([/size][size=2][color=#a31515][size=2][color=#a31515]"test"[/color][/size][/color][/size][size=2])> _[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Public[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Sub[/color][/size][/color][/size][size=2] test()[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] DB [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetDbServices.Database = AcadNetDbServices.HostApplicationServices.WorkingDatabase[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] ED [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetEditorInput.Editor = AcadNetAppServices.Application.DocumentManager.MdiActiveDocument.Editor[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] ActiveDoc [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetAppServices.Document = AcadNetAppServices.Application.DocumentManager.MdiActiveDocument[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] Trans2 [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetDbServices.Transaction = DB.TransactionManager.StartTransaction()[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] TopCurve [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetDbServices.Curve[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] BottomCurve [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetDbServices.Curve[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Try[/color][/size] [/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] PDO [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetEditorInput.PromptDoubleOptions = [/size][size=2][color=#0000ff][size=2][color=#0000ff]New[/color][/size][/color][/size][size=2] AcadNetEditorInput.PromptDoubleOptions(vbCr & [/size][size=2][color=#a31515][size=2][color=#a31515]"Specify distance between lines: "[/color][/size][/color][/size][size=2])[/size] [size=2]PDO.AllowNegative = [/size][size=2][color=#0000ff][size=2][color=#0000ff]False[/color][/size] [/color][/size][size=2]PDO.AllowZero = [/size][size=2][color=#0000ff][size=2][color=#0000ff]False[/color][/size] [/color][/size][size=2]PDO.AllowArbitraryInput = [/size][size=2][color=#0000ff][size=2][color=#0000ff]False[/color][/size] [/color][/size][size=2]PDO.AllowNone = [/size][size=2][color=#0000ff][size=2][color=#0000ff]False[/color][/size] [/color][/size][size=2]PDO.DefaultValue = 5[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] PDR [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetEditorInput.PromptDoubleResult = ED.GetDouble(PDO)[/size] [size=2][color=#0000ff][size=2][color=#0000ff]If[/color][/size][/color][/size][size=2] PDR.Status <> AcadNetEditorInput.PromptStatus.OK [/size][size=2][color=#0000ff][size=2][color=#0000ff]Then[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Exit[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Sub[/color][/size] [/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] PEO1 [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetEditorInput.PromptEntityOptions = [/size][size=2][color=#0000ff][size=2][color=#0000ff]New[/color][/size][/color][/size][size=2] AcadNetEditorInput.PromptEntityOptions(vbCr & [/size][size=2][color=#a31515][size=2][color=#a31515]"Select top Curve: "[/color][/size][/color][/size][size=2])[/size] [size=2]PEO1.SetRejectMessage([/size][size=2][color=#a31515][size=2][color=#a31515]" Invalid entity! Select LWPoly, 2DPoly, 3DPoly, Line, Arc, Circle or Spline only!"[/color][/size][/color][/size][size=2])[/size] [size=2]PEO1.AddAllowedClass([/size][size=2][color=#0000ff][size=2][color=#0000ff]GetType[/color][/size][/color][/size][size=2](AcadNetDbServices.Curve), [/size][size=2][color=#0000ff][size=2][color=#0000ff]False[/color][/size][/color][/size][size=2])[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] PER1 [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetEditorInput.PromptEntityResult = ED.GetEntity(PEO1)[/size] [size=2][color=#0000ff][size=2][color=#0000ff]If[/color][/size][/color][/size][size=2] PER1.Status <> AcadNetEditorInput.PromptStatus.OK [/size][size=2][color=#0000ff][size=2][color=#0000ff]Then[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Exit[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Sub[/color][/size] [/color][/size][size=2]TopCurve = Trans2.GetObject(PER1.ObjectId, AcadNetDbServices.OpenMode.ForRead)[/size] [size=2][/size] As you will see if you test the code the lines don't get the closest intersection point on the curve. would you be able to show me what you meant in terms of coding?? Thank you very much Quote
russell84 Posted April 13, 2009 Author Posted April 13, 2009 Second part of code from above [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] PEO2 [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetEditorInput.PromptEntityOptions = [/size][size=2][color=#0000ff][size=2][color=#0000ff]New[/color][/size][/color][/size][size=2] AcadNetEditorInput.PromptEntityOptions(vbCr & [/size][size=2][color=#a31515][size=2][color=#a31515]"Select bottom Curve: "[/color][/size][/color][/size][size=2])[/size] [size=2]PEO2.SetRejectMessage([/size][size=2][color=#a31515][size=2][color=#a31515]" Invalid entity! Select LWPoly, 2DPoly, 3DPoly, Line, Arc, Circle or Spline only!"[/color][/size][/color][/size][size=2])[/size] [size=2]PEO2.AddAllowedClass([/size][size=2][color=#0000ff][size=2][color=#0000ff]GetType[/color][/size][/color][/size][size=2](AcadNetDbServices.Curve), [/size][size=2][color=#0000ff][size=2][color=#0000ff]False[/color][/size][/color][/size][size=2])[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] PER2 [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetEditorInput.PromptEntityResult = ED.GetEntity(PEO2)[/size] [size=2][color=#0000ff][size=2][color=#0000ff]If[/color][/size][/color][/size][size=2] PER2.Status <> AcadNetEditorInput.PromptStatus.OK [/size][size=2][color=#0000ff][size=2][color=#0000ff]Then[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Exit[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Sub[/color][/size] [/color][/size][size=2]BottomCurve = Trans2.GetObject(PER2.ObjectId, AcadNetDbServices.OpenMode.ForRead)[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] TopCurveLen [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Double[/color][/size][/color][/size][size=2] = TopCurve.GetDistanceAtParameter(TopCurve.EndParam)[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] DistBetween [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Double[/color][/size][/color][/size][size=2] = PDR.Value[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] Divstep [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Double[/color][/size][/color][/size][size=2] = PDR.Value[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] StepLength1 [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Double[/color][/size][/color][/size][size=2] = 0[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] Toolong1 [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Boolean[/color][/size][/color][/size][size=2] = [/size][size=2][color=#0000ff][size=2][color=#0000ff]False[/color][/size] [/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]While[/color][/size][/color][/size][size=2] Toolong1 = [/size][size=2][color=#0000ff][size=2][color=#0000ff]False[/color][/size] [/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] Trans3 [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetDbServices.Transaction = DB.TransactionManager.StartTransaction()[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] AcadBT [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetDbServices.BlockTable[/size] [size=2]AcadBT = Trans3.GetObject(DB.BlockTableId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead)[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] BTRSpace [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetDbServices.BlockTableRecord = Trans3.GetObject(DB.CurrentSpaceId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] AcadBTR [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetDbServices.BlockTableRecord[/size] [size=2][color=#008000][size=2][color=#008000]''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''[/color][/size] [/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]If[/color][/size][/color][/size][size=2] StepLength1 <= TopCurveLen [/size][size=2][color=#0000ff][size=2][color=#0000ff]Then[/color][/size] [/color][/size][size=2][color=#008000][size=2][color=#008000]''''''''''''''''''''''''''''''''''''''''''''''''''''''''''[/color][/size] [/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] StartPt1 [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetGeometry.Point3d = TopCurve.GetPointAtDist(StepLength1)[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] Vector1 [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetGeometry.Vector3d = TopCurve.GetFirstDerivative(StartPt1)[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] Vector1Perp [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetGeometry.Vector3d = Vector1.GetPerpendicularVector()[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] Vector1PerpNeg [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetGeometry.Vector3d = Vector1Perp.Negate()[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] EndPt1 [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetGeometry.Point3d = BottomCurve.GetClosestPointTo(StartPt1, Vector1Perp, [/size][size=2][color=#0000ff][size=2][color=#0000ff]False[/color][/size][/color][/size][size=2])[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Dim[/color][/size][/color][/size][size=2] Line1 [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] AcadNetDbServices.Line = [/size][size=2][color=#0000ff][size=2][color=#0000ff]New[/color][/size][/color][/size][size=2] AcadNetDbServices.Line()[/size] [size=2]Line1.StartPoint = StartPt1[/size] [size=2]Line1.EndPoint = EndPt1[/size] [size=2]BTRSpace.AppendEntity(Line1)[/size] [size=2]Trans3.AddNewlyCreatedDBObject(Line1, [/size][size=2][color=#0000ff][size=2][color=#0000ff]True[/color][/size][/color][/size][size=2])[/size] [size=2]StepLength1 = StepLength1 + Divstep[/size] [size=2]Line1.Dispose()[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Else[/color][/size] [/color][/size][size=2]Toolong1 = [/size][size=2][color=#0000ff][size=2][color=#0000ff]True[/color][/size] [/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]End[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]If[/color][/size] [/color][/size][size=2]Trans3.Commit()[/size] [size=2][color=#0000ff][size=2][color=#0000ff]End[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]While[/color][/size] [/color][/size][size=2]Trans2.Commit()[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Catch[/color][/size][/color][/size][size=2] ex [/size][size=2][color=#0000ff][size=2][color=#0000ff]As[/color][/size][/color][/size][size=2] Autodesk.AutoCAD.Runtime.Exception[/size] [size=2]MsgBox([/size][size=2][color=#a31515][size=2][color=#a31515]"error"[/color][/size][/color][/size][size=2])[/size] [size=2][/size][size=2]MsgBox([/size][size=2][color=#a31515][size=2][color=#a31515]"Error during execution! "[/color][/size][/color][/size][size=2] & ex.Message)[/size] [size=2][color=#0000ff][size=2][color=#0000ff]Finally[/color][/size] [/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]End[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Try[/color][/size] [/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]End[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Sub[/color][/size] [size=2][color=#0000ff]End[/color][/size][/color][/size][size=2][color=#0000ff][size=2][color=#0000ff]Class[/color][/size] [/color][/size] Quote
SEANT Posted April 13, 2009 Posted April 13, 2009 I can’t tell exactly what the end result should be. The modified code below would draw a line from points (default) at 5 unit intervals on TopCurve to the closest point on BottomCurve. If the line needs to be perpendicular to TopCurve at that 5 unit interval then the routine would need to use the Vector1Perp to create a line, then use it to .IntersectWith(BottomCurve). With: Imports Autodesk.AutoCAD.Runtime Imports AcadNetAppServices = Autodesk.AutoCAD.ApplicationServices Imports AcadNetDbServices = Autodesk.AutoCAD.DatabaseServices Imports AcadNetDBTransman = Autodesk.AutoCAD.DatabaseServices.TransactionManager Imports AcadNetGeometry = Autodesk.AutoCAD.Geometry Imports AcadNetEditorInput = Autodesk.AutoCAD.EditorInput Public Sub Test() Dim DB As AcadNetDbServices.Database = AcadNetDbServices.HostApplicationServices.WorkingDatabase Dim ED As AcadNetEditorInput.Editor = AcadNetAppServices.Application.DocumentManager.MdiActiveDocument.Editor Dim ActiveDoc As AcadNetAppServices.Document = AcadNetAppServices.Application.DocumentManager.MdiActiveDocument Dim Trans2 As AcadNetDbServices.Transaction = DB.TransactionManager.StartTransaction() Dim TopCurve As AcadNetDbServices.Curve Dim BottomCurve As AcadNetDbServices.Curve Try Dim PDO As AcadNetEditorInput.PromptDoubleOptions = New AcadNetEditorInput.PromptDoubleOptions(vbCr & "Specify distance between lines: ") PDO.AllowNegative = False PDO.AllowZero = False PDO.AllowArbitraryInput = False PDO.AllowNone = False PDO.DefaultValue = 5 Dim PDR As AcadNetEditorInput.PromptDoubleResult = ED.GetDouble(PDO) If PDR.Status <> AcadNetEditorInput.PromptStatus.OK Then Exit Sub Dim PEO1 As AcadNetEditorInput.PromptEntityOptions = New AcadNetEditorInput.PromptEntityOptions(vbCr & "Select top Curve: ") PEO1.SetRejectMessage(" Invalid entity! Select LWPoly, 2DPoly, 3DPoly, Line, Arc, Circle or Spline only!") PEO1.AddAllowedClass(GetType(AcadNetDbServices.Curve), False) Dim PER1 As AcadNetEditorInput.PromptEntityResult = ED.GetEntity(PEO1) If PER1.Status <> AcadNetEditorInput.PromptStatus.OK Then Exit Sub TopCurve = Trans2.GetObject(PER1.ObjectId, AcadNetDbServices.OpenMode.ForRead) PEO1.Message = vbCr & "Select top Curve: " PER1 = ED.GetEntity(PEO1) If PER1.Status <> AcadNetEditorInput.PromptStatus.OK Then Exit Sub BottomCurve = Trans2.GetObject(PER1.ObjectId, AcadNetDbServices.OpenMode.ForRead) Dim TopCurveLen As Double = TopCurve.GetDistanceAtParameter(TopCurve.EndParam) Dim DistBetween As Double = PDR.Value Dim Divstep As Double = PDR.Value Dim StepLength1 As Double = 0 Dim Toolong1 As Boolean = False Dim AcadBT As AcadNetDbServices.BlockTable AcadBT = Trans2.GetObject(DB.BlockTableId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead) Dim BTRSpace As AcadNetDbServices.BlockTableRecord = Trans2.GetObject(DB.CurrentSpaceId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite) While Toolong1 = False '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' If StepLength1 <= TopCurveLen Then '''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Dim StartPt1 As AcadNetGeometry.Point3d = TopCurve.GetPointAtDist(StepLength1) 'Dim Vector1 As AcadNetGeometry.Vector3d = TopCurve.GetFirstDerivative(StartPt1) ''''''If dealing strictly with flat WCS geometry, this line would suffice'''''' Dim EndPt1 As AcadNetGeometry.Point3d = BottomCurve.GetClosestPointTo(StartPt1, False) ''''''If dealing with 3D geometry but requiring spacing as projected to WCS'''''' 'Dim Vector1Perp As AcadNetGeometry.Vector3d = New AcadNetGeometry.Vector3d(0.0, 0.0, 1.0) 'project to WCS 'Dim EndPt1 As AcadNetGeometry.Point3d = BottomCurve.GetClosestPointTo(StartPt1, Vector1Perp, False) Dim Line1 As AcadNetDbServices.Line = New AcadNetDbServices.Line() Line1.StartPoint = StartPt1 Line1.EndPoint = EndPt1 BTRSpace.AppendEntity(Line1) Trans2.AddNewlyCreatedDBObject(Line1, True) StepLength1 = StepLength1 + Divstep Else Toolong1 = True End If End While Trans2.Commit() Catch ex As Autodesk.AutoCAD.Runtime.Exception MsgBox("error") MsgBox("Error during execution! " & ex.Message) Finally Trans2.Dispose() End Try End Sub Quote
russell84 Posted April 16, 2009 Author Posted April 16, 2009 If the line needs to be perpendicular to TopCurve at that 5 unit interval then the routine would need to use the Vector1Perp to create a line, then use it to .IntersectWith(BottomCurve). Thats entirely what im trying to do - but cant get it to work through code. Would you be able to show me how to create a xline along the Vector1Perp then get the closest intersection point along BottomCurve? Because i'm still far behind with this transaction vb.net stuff Thank you again Quote
SEANT Posted April 17, 2009 Posted April 17, 2009 I'll try to put an example together this weekend. Quote
russell84 Posted April 17, 2009 Author Posted April 17, 2009 No enjoy your weekend mate - im in no rush with this - its just something that i want to get done eventually. When ever you can. Cheers Quote
SEANT Posted April 20, 2009 Posted April 20, 2009 Here is an example routine that draws a line perpendicular to a “Top Curve” from the closest point on a “Bottom Curve”. The need to find an intersection of two curves, closest to a particular point, seemed common enough to warrant an extended “Code Reuse” effort. Consequently, I made a ClosestIntersToPt class to make the process more user friendly. This “future user friendliness” does add a bit of complexity to the code as it stands. Let me know if some additional code commenting would make the code more decipherable. Incidentally, the class still needs to implement a “Projected Intersection” method to stay in line with the current Entity.IntersectWith method. Importing: Imports Autodesk.AutoCAD.Runtime Imports AcadNetAppServices = Autodesk.AutoCAD.ApplicationServices Imports AcadNetDbServices = Autodesk.AutoCAD.DatabaseServices Imports AcadNetDBTransman = Autodesk.AutoCAD.DatabaseServices.TransactionManager Imports AcadNetGeometry = Autodesk.AutoCAD.Geometry Imports AcadNetEditorInput = Autodesk.AutoCAD.EditorInput Imports System.Collections.Generic <CommandMethod("P2C")> _ Public Sub Perp2Curve() Dim DB As AcadNetDbServices.Database = AcadNetDbServices.HostApplicationServices.WorkingDatabase Dim ED As AcadNetEditorInput.Editor = AcadNetAppServices.Application.DocumentManager.MdiActiveDocument.Editor Dim ActiveDoc As AcadNetAppServices.Document = AcadNetAppServices.Application.DocumentManager.MdiActiveDocument Dim Trans2 As AcadNetDbServices.Transaction = DB.TransactionManager.StartTransaction() Dim TopCurve As AcadNetDbServices.Curve Dim VectZ As AcadNetGeometry.Vector3d = New AcadNetGeometry.Vector3d(0.0, 0.0, 1.0) Dim pln As AcadNetGeometry.Plane = New AcadNetGeometry.Plane() Dim lnList As List(Of AcadNetDbServices.Line) = New List(Of AcadNetDbServices.Line) Dim Line1 As AcadNetDbServices.Line = New AcadNetDbServices.Line() Try Dim PDO As AcadNetEditorInput.PromptDoubleOptions = New AcadNetEditorInput.PromptDoubleOptions(vbCr & "Specify distance between lines: ") PDO.AllowNegative = False PDO.AllowZero = False PDO.AllowArbitraryInput = False PDO.AllowNone = False PDO.DefaultValue = 5 Dim PDR As AcadNetEditorInput.PromptDoubleResult = ED.GetDouble(PDO) If PDR.Status <> AcadNetEditorInput.PromptStatus.OK Then Exit Sub Dim PEO1 As AcadNetEditorInput.PromptEntityOptions = New AcadNetEditorInput.PromptEntityOptions(vbCr & "Select top Curve: ") PEO1.SetRejectMessage(" Invalid entity! Select LWPoly, 2DPoly, 3DPoly, Line, Arc, Circle or Spline only!") PEO1.AddAllowedClass(GetType(AcadNetDbServices.Curve), False) Dim PER1 As AcadNetEditorInput.PromptEntityResult = ED.GetEntity(PEO1) If PER1.Status <> AcadNetEditorInput.PromptStatus.OK Then Exit Sub TopCurve = Trans2.GetObject(PER1.ObjectId, AcadNetDbServices.OpenMode.ForRead) PEO1.Message = vbCr & "Select bottom curve: " PER1 = ED.GetEntity(PEO1) If PER1.Status <> AcadNetEditorInput.PromptStatus.OK Then Exit Sub Dim objCloseInt As ClosestIntersToPt = New ClosestIntersToPt() objCloseInt.ArgumentCurve = CType(Trans2.GetObject(PER1.ObjectId, AcadNetDbServices.OpenMode.ForRead), AcadNetDbServices.Curve) Dim TopCurveLen As Double = TopCurve.GetDistanceAtParameter(TopCurve.EndParam) Dim DistBetween As Double = PDR.Value Dim Divstep As Double = PDR.Value Dim StepLength1 As Double = 0 Dim StartPt1 As AcadNetGeometry.Point3d Dim Vector1 As AcadNetGeometry.Vector3d While StepLength1 <= TopCurveLen StartPt1 = TopCurve.GetPointAtDist(StepLength1) Vector1 = TopCurve.GetFirstDerivative(StartPt1) Vector1 = Vector1.RotateBy(Math.PI / 2, VectZ) Line1.StartPoint = StartPt1 Line1.EndPoint = StartPt1.Add(Vector1) objCloseInt.ThisCurve = Line1 objCloseInt.BasePoint = StartPt1 objCloseInt.Update() If objCloseInt.Intersects Then lnList.Add(New AcadNetDbServices.Line(StartPt1, objCloseInt.ClosestPt)) End If StepLength1 = StepLength1 + Divstep End While Dim AcadBT As AcadNetDbServices.BlockTable AcadBT = Trans2.GetObject(DB.BlockTableId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead) Dim BTRSpace As AcadNetDbServices.BlockTableRecord = Trans2.GetObject(DB.CurrentSpaceId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite) For Each line As AcadNetDbServices.Line In lnList line.SetDatabaseDefaults() BTRSpace.AppendEntity(line) Trans2.AddNewlyCreatedDBObject(line, True) Next Trans2.Commit() Catch ex As Autodesk.AutoCAD.Runtime.Exception MsgBox("error") MsgBox("Error during execution! " & ex.Message) Finally Trans2.Dispose() End Try End Sub End Class 'New Class ************************ 'The requirements of this class mimick those of the Entity.IntersectWith method. The on additional trequirement is the '"ClosestPt". Public Class ClosestIntersToPt 'Fields Public Intersects As Boolean Public ClosestPt As AcadNetGeometry.Point3d Public BasePoint As AcadNetGeometry.Point3d Private m_thsCurve As AcadNetDbServices.Curve Private m_argCurve As AcadNetDbServices.Curve Private m_plane As AcadNetGeometry.Plane Private m_basePt As AcadNetGeometry.Point3d Private m_projectGeom As Boolean 'Constructors Public Sub ClosestIntersToPt() End Sub Public Sub ClosestIntersToPt(ByVal ThisCurve As AcadNetDbServices.Curve, _ ByVal ArgCrv As AcadNetDbServices.Curve, _ ByVal BasePt As AcadNetGeometry.Point3d, _ ByVal ProjectedPlane As AcadNetGeometry.Plane) m_thsCurve = ThisCurve m_argCurve = ArgCrv BasePoint = BasePt m_plane = ProjectedPlane GetClosestInt() End Sub 'Methods Public Sub Update() GetClosestInt() End Sub 'Properties Public Property ThisCurve() As AcadNetDbServices.Curve Get Return m_thsCurve End Get Set(ByVal value As AcadNetDbServices.Curve) m_thsCurve = value End Set End Property Public Property ArgumentCurve() As AcadNetDbServices.Curve Get Return m_argCurve End Get Set(ByVal value As AcadNetDbServices.Curve) m_argCurve = value End Set End Property Public Property ProjectionPlane() As AcadNetGeometry.Plane Get Return m_plane End Get Set(ByVal value As AcadNetGeometry.Plane) m_plane = value End Set End Property Public WriteOnly Property ProjectGeometry() As Boolean Set(ByVal value As Boolean) m_projectGeom = value End Set End Property 'Internal Private Sub GetClosestInt() Dim p3dc As AcadNetGeometry.Point3dCollection = New AcadNetGeometry.Point3dCollection() Dim lstPt As AcadNetGeometry.Point3d Dim i As Integer m_thsCurve.IntersectWith(m_argCurve, Autodesk.AutoCAD.DatabaseServices.Intersect.ExtendThis, p3dc, 0, 0) Dim Ubound As Integer = p3dc.Count If Ubound > 0 Then lstPt = p3dc(0) Dim minLen As Double = p3dc(0).DistanceTo(BasePoint) Dim tempLen As Double ClosestPt = p3dc(0) If Ubound > 1 Then For i = 1 To p3dc.Count - 1 tempLen = p3dc(i).DistanceTo(BasePoint) If tempLen < minLen Then ClosestPt = p3dc(i) minLen = tempLen End If Next End If Intersects = True Else Intersects = False End If End Sub Quote
russell84 Posted April 21, 2009 Author Posted April 21, 2009 'future user friendliness' is great. That actually works perfect thank you. It is definatly a common task to get the closest perp point.- i owe you some beers after that one haha No need for the commenting for the code - i do understand what you have done basically at a glance but i will go over it further and if i get stuck i will give you a yell I'll also forward on my completed code to you once i finish so if you find it useful for any reason what so ever i'll feel better Good class - should have been a standard class really i think - but here it is i suppose. Thanks Quote
SEANT Posted April 21, 2009 Posted April 21, 2009 I'm glad it was helpful. And, yes, please do upload the completed code. Due to the relative scarcity of .NET examples, this newsgroup and I will appreciate every one we can get. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.