Jump to content

VB.net: Perpendicular lines to a polyline


Jozi68

Recommended Posts

I use vb.net. I work in 2D.

I have a certain point (Point3D). I have a certain polyline. I need to draw a perpendicular line from the point to the polyline. Any ideas on how to do that??

Link to comment
Share on other sites

This is typically done with Curve.GetClosestPointTo(). The point returned from that method can be combined with the input point to create a line.

Link to comment
Share on other sites

There may be a detail or two overlooked in this sample, but it shows the general idea.

 

   Public Sub Per2Poly()
       Dim db As Database = HostApplicationServices.WorkingDatabase
       Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
       db.Pdmode = 66 'just to make the points more visible
       Dim tr As Transaction = db.TransactionManager.StartTransaction()
       Dim peo As PromptEntityOptions = New PromptEntityOptions(vbCr & "Select a lwpline: ")
       peo.SetRejectMessage(vbCr & "Please select lightweight polyline only! ")
       peo.AddAllowedClass(GetType(Polyline), True)
       Try
           Dim per As PromptEntityResult = ed.GetEntity(peo)
           If per.Status <> PromptStatus.OK Then Exit Sub
           Dim mat As Matrix3d = ed.CurrentUserCoordinateSystem
           Dim pl As Polyline = tr.GetObject(per.ObjectId, OpenMode.ForRead)

           Dim ppo As PromptPointOptions = New PromptPointOptions(vbCr & "Select point from which to strike a perpendicular: " & vbLf)
           ppo.AllowNone = True

           Dim ppr As PromptPointResult = ed.GetPoint(ppo)
           If ppr.Status <> PromptStatus.OK Then Exit Sub
           Dim basePt As Point3d = ppr.Value.TransformBy(mat)
           Dim pt As Point3d = pl.GetClosestPointTo(basePt, False) 'crux of the process

           Dim v3d As Vector3d = basePt.GetVectorTo(pt)       'Test if closest point is indeed perpendicular.
           Dim derV3d As Vector3d = pl.GetFirstDerivative(pt) '
           If v3d.IsPerpendicularTo(derV3d) Then              '
               Dim ln As Line = New Line(basePt, pt)
               Dim btr As BlockTableRecord = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)
               ln.SetDatabaseDefaults()
               btr.AppendEntity(ln)
               tr.AddNewlyCreatedDBObject(ln, True)
               tr.Commit()
           Else
               ed.WriteMessage(vbCr & "Perpendicular not found!")
           End If
       Catch ex As Exception
           tr.Abort()
           ed.WriteMessage("Error during execution! " & ex.Message)
       Finally
           tr.Dispose()
       End Try

   End Sub

Link to comment
Share on other sites

  • 3 years later...

Hi Seant,

I tried to to used part of your code...but i am planning to replace the PPR value input with loop of point3d in the point3dcollection but it gives me an error. I would like to ask how to do it correctly.

 

 

 

For Each vx As Point3d In VertexPts

Dim basept As Point3d = vx.TransformBy(mat)

Dim pt As Point3d = poly2.GetClosestPointTo(basept, False)

Dim v3d As Vector3d = basept.GetVectorTo(pt)

Dim derv3d As Vector3d = poly2.GetFirstDerivative(pt)

 

If v3d.IsPerpendicularTo(derv3d) Then

Dim ln As Line = New Line(basept, pt)

Dim btr As BlockTableRecord = trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)

ln.SetDatabaseDefaults()

btr.AppendEntity(ln)

trans.AddNewlyCreatedDBObject(ln, True)

trans.Commit()

Else

ed.WriteMessage(vbCr & "Perpendicular not found!")

End If

Next

Link to comment
Share on other sites

At which line of code does the error occur?

 

the error message point the error to this line

 

Dim btr As BlockTableRecord = trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)

 

during the program execution it only creates one line to the first point point3d which is perpendicular to the polyline the rest does not...

Link to comment
Share on other sites

Oops! I guess I should have seen that as a problem.

 

These line really need to be on the outside of the For Loop.

 

Dim btr As BlockTableRecord = trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)
For Each vx As Point3d In VertexPts
   Dim basept As Point3d = vx.TransformBy(mat)
   Dim pt As Point3d = poly2.GetClosestPointTo(basept, False)
   Dim v3d As Vector3d = basept.GetVectorTo(pt)
   Dim derv3d As Vector3d = poly2.GetFirstDerivative(pt)
   If v3d.IsPerpendicularTo(derv3d) Then
       Dim ln As Line = New Line(basept, pt)
       ln.SetDatabaseDefaults()
       btr.AppendEntity(ln)
       trans.AddNewlyCreatedDBObject(ln, True)
   End If
Next
trans.Commit()

 

It might also make sense to "Dim" all the variable prior to the for loop - just assign them within the loop.

Link to comment
Share on other sites

It might also make sense to "Dim" all the variable prior to the for loop - just assign them within the loop.

 

That's only necessary if the variables are going to be used outside of the FOR loop's scope (before, or after)... i.e., if one needs to further manipulate a variable's Object, or use as Returned value.

Link to comment
Share on other sites

I agree. It is absolutely necessary for referencing outside of the “For” loop. My statement addresses something more subtle –the reason I used the wording that I did.

 

 

 

A line:

 

Dim ThisVariable AsThatObject

 

Instructs the OS to set aside a certain chunk of memory to contain the object. There is no reason to keep making that assessment/setting within the loop. Even if the actual Object or Structure will not be needed from on loop to the next, the same memory address (size and location) can be re-used and avoid repeated Garbage Collections.

Link to comment
Share on other sites

... My statement addresses something more subtle...

 

Well said, and something that I should have picked up on initially... Something which seems so obvious after reading your clarification.

 

Cheers

Link to comment
Share on other sites

The loop would have to be very prolific for these subtleties to make a noticeable difference. I think it is a good habit to employ none the less.

Link to comment
Share on other sites

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