Author Topic: Closest Endpoint of a Selected Line  (Read 2073 times)

0 Members and 1 Guest are viewing this topic.

surveyor_randy

  • Guest
Closest Endpoint of a Selected Line
« on: November 11, 2007, 10:28:31 AM »
Is there any way to get the closest point (start or end) of a line or 2-vertex polyline of a selected line?  Right now, I am having the user select the entity, then drawing a marker on one of the endpoints and prompting the user if this is the correct point, if not, it selects the other.  What I would like to do, is have the user click on the line closest to the endpoint they want to work with.  Is this even possible?  Thanks for any input/suggestions.

SomeCallMeDave

  • Guest
Re: Closest Endpoint of a Selected Line
« Reply #1 on: November 11, 2007, 11:13:10 AM »
Yes, it is possilbe.  The ThisDrawing.Utility.GetEntity function will return the entity selected (the line/pline) and the point that was picked to select the entity.

You could then test the distances from the end points to the 'pick point' and return the closest end point.  It would be a bit tougher if you didnt limit it to a 2 vertex pline.

I have some proto-type code if you care to see it

surveyor_randy

  • Guest
Re: Closest Endpoint of a Selected Line
« Reply #2 on: November 11, 2007, 12:06:56 PM »
I have some proto-type code if you care to see it

Sure!  That'd be great!  I have an idea if the user selected a polyline with more then 2 vertexes.  First, find the vertex closest to where the user selected the pline.  Determine what vertex number that is in the pline and then sum the distances of the segments up to that vertex, then get the sum of the remaining segments.  Which ever is shorter, select either the first vertex or the last vertex based on that.

I ended up finishing my stationing routine and just set the OSMODE and made them pick the start and end points.  I still am interested in them just selecting the line they want to station closest to the point they want to begin stationing at.

SomeCallMeDave

  • Guest
Re: Closest Endpoint of a Selected Line
« Reply #3 on: November 11, 2007, 12:31:13 PM »
Here is the rough code.  It needs error checking, entity type testing, etc

But I think it gets the idea across (if I interpreted you first post correctly).

Code: [Select]
Public Sub testGetClosestEndpoint()
    Dim oEnt As AcadEntity
    Dim vPickedPoint As Variant
    Dim vPoint As Variant
    Dim vResult As Variant
   
    ThisDrawing.Utility.GetEntity oEnt, vPickedPoint, "Pick (p)Line: "
   
    vResult = GetClosestEndPt(oEnt, vPickedPoint, False)
    Debug.Print vResult(0), vResult(1), vResult(2)
End Sub
Public Function GetClosestEndPt(pLineEnt As AcadEntity, pPoint As Variant, p3dIfTrue As Boolean) As Variant
    Dim vTemp1 As Variant
    Dim oLine As AcadLine
    Dim oLwPline As AcadLWPolyline
    Dim oPline As AcadPolyline
    Dim o3dPline As Acad3DPolyline
    Dim maxVert As Integer
   
    Dim dist1 As Double
    Dim dist2 As Double
    Dim retVal As Variant
   
    If TypeOf pLineEnt Is AcadLine Then
        Set oLine = pLineEnt
        dist1 = CalcDist(oLine.StartPoint, pPoint, p3dIfTrue)
        dist2 = CalcDist(oLine.EndPoint, pPoint, p3dIfTrue)
        If dist1 <= dist2 Then
            retVal = oLine.StartPoint
        Else
            retVal = oLine.EndPoint
        End If
    ElseIf TypeOf pLineEnt Is AcadLWPolyline Then
        Set oLwPline = pLineEnt
        maxVert = (UBound(oLwPline.Coordinates) - 1) / 2
        dist1 = CalcDist(oLwPline.Coordinate(0), pPoint, p3dIfTrue)
        dist2 = CalcDist(oLwPline.Coordinate(maxVert), pPoint, p3dIfTrue)
        If dist1 <= dist2 Then
            retVal = oLwPline.Coordinate(0)
        Else
            retVal = oLwPline.Coordinate(maxVert)
        End If
    ElseIf TypeOf pLineEnt Is AcadPolyline Then
        Set oPline = pLineEnt
        maxVert = (UBound(oPline.Coordinates) - 2) / 3
        dist1 = CalcDist(oPline.Coordinate(0), pPoint, p3dIfTrue)
        dist2 = CalcDist(oPline.Coordinate(maxVert), pPoint, p3dIfTrue)
        If dist1 <= dist2 Then
            retVal = oPline.Coordinate(0)
        Else
            retVal = oPline.Coordinate(maxVert)
        End If
    ElseIf TypeOf pLineEnt Is Acad3DPolyline Then
        Set o3dPline = pLineEnt
        maxVert = (UBound(o3dPline.Coordinates) - 2) / 3
        dist1 = CalcDist(o3dPline.Coordinate(0), pPoint, p3dIfTrue)
        dist2 = CalcDist(o3dPline.Coordinate(maxVert), pPoint, p3dIfTrue)
        If dist1 <= dist2 Then
            retVal = o3dPline.Coordinate(0)
        Else
            retVal = o3dPline.Coordinate(maxVert)
        End If
    End If
   
    GetClosestEndPt = retVal
   
   


End Function
Public Function CalcDist(pPt1 As Variant, pPt2 As Variant, p3dIfTrue As Boolean) As Double
    Dim temp As Double
   
    If p3dIfTrue Then
        temp = Sqr((pPt1(0) - pPt2(0)) ^ 2 + (pPt1(1) - pPt2(1)) ^ 2 + (pPt1(2) - pPt2(2)) ^ 2)
    Else
       temp = Sqr((pPt1(0) - pPt2(0)) ^ 2 + (pPt1(1) - pPt2(1)) ^ 2)
    End If
   
    CalcDist = temp

End Function


The LISP vlax-curve-* functions would probably be helpful to you for determining stationing.  They can probably be accessed in VBA using the VL Active X module and/or through Frank O's VLAX class.

surveyor_randy

  • Guest
Re: Closest Endpoint of a Selected Line
« Reply #4 on: November 11, 2007, 03:37:36 PM »
Thanks for the code snippet!  As far as the stationing routines, I will look into the VL active X module.  To be honest, I was unaware of such a thing even existing.  There are tons of VL routines that I'd love to access!  Do you know where I can find documentation on this module.

I already have most of my stationing functions written.  The only one left to do is the stationing for a horizontal curve which should be no biggie!  Thanks again for the help!