Jump to content

Recommended Posts

Posted

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

Posted

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.

Posted

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

Posted

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]

Posted

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

Posted
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

Posted

I'll try to put an example together this weekend.

Posted

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

Posted

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

Posted

'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

Posted

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. :)

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...