select lwpolyline then move to next vertex to get the angle

Discussion in 'AutoCAD' started by Bill Schooler, Jun 8, 2004.

  1. I have select a lwpolyline by using GetSubEntity. This lwpolyline could
    have an arc in them. I would like get next vertex after the location I
    have selected. I did use the IntersectWith but I have to draft a dumbing
    line. Is there a better way?
     
    Bill Schooler, Jun 8, 2004
    #1
  2. Bill,

    Here's a little trick for adding a vertex at given point (or before/after
    given vertex) along the pline:

    1) Turn on OSNAP=Nearest to prevent picking a point outside a pline
    2) Find all distances between picked point (or vertex) and every pline's
    vertice
    3) Assign an index to some variable during iterating the vertices
    4) Compare them all to each other and find the shortest one - an index
    assigned to that specific distance is a vertex _nearest_ to the given point.

    Now, for finding if adding a vertex is supposed to happen "before" or
    "after" a found one, do the following:

    1) Calculate the original pline's length
    2) Add a vertex "after" the found one using above described function
    3) If new pline's length is different than the original one, then undo step
    2) and add a vertex "before" the calculated one.

    Regards,
    Maksim Sestic



    ----- Original Message -----
    From: "Bill Schooler" <>
    Newsgroups: autodesk.autocad.customization.vba
    Sent: Tuesday, June 08, 2004 18:42
    Subject: select lwpolyline then move to next vertex to get the angle
     
    Maksim Sestic, Jun 8, 2004
    #2
  3. Bill Schooler

    wivory Guest

    Hmmm...how are you proposing that the distance be measured? If it is linear then wouldn't a polyline that turns back toward the selected spot potentially give a false answer?
    [pre]
    |____.____a
    b____|
    |
    [/pre]
    In the above example the next vertex from the selected point "." should be "a" but the closest is "b".

    Regards

    Wayne Ivory
    IT Analyst Programmer
    Wespine Industries Pty Ltd
     
    wivory, Jun 9, 2004
    #3
  4. True... I've been working with more or less "straight" polylines that don't
    "bend" much toward one of it's vertices. There must be some more universal
    solution to this... probably relying on measuring a PolarPoint between two
    neighbouring vertices and comapring it to a given point along a pline...

    Most of my time I spent solving similar things in VBA, so I wondered if some
    of the solutions might be of interest to the wider auditorium. Maybe I
    publish them on a Web site, as I certainly need assurance regarding
    implemented approach and correctness (I'm a big fan of "universal"
    solutions) :)

    Regards,
    Maksim Sestic

    linear then wouldn't a polyline that turns back toward the selected spot
    potentially give a false answer?
     
    Maksim Sestic, Jun 9, 2004
    #4
  5. I would loop through the poly's segments, and just check which segment the
    picked point is on (assuming the osnap was used). This should only give
    ambiguous results when the user picks exactly at an intersection, or picks
    overlapping segments, which are both ambiguous situations, anyways. If you
    don't want to use snap, change the FUZZ loop to instead track the minimum
    distance from the pick pt to each segment, and call that the picked segment.

    HTH,
    James


    [pseudocode]
    'coords() = polyline vertices
    'pickPt = variant holding picked point
    dim x() as double, y() as double, z() as double
    numPts = ((UBound(coords) + 1) / 3) 'assumes 0-bounded array of 3-D
    points
    ReDim x(0 To numPts - 1)
    ReDim y(0 To numPts - 1)
    ReDim z(0 To numPts - 1)
    For i = 0 To numPts - 1
    x(i) = coords(3 * i)
    y(i) = coords(3 * i + 1)
    z(i) = coords(3 * i + 2)
    Next 'i

    '
    const FUZZ as double = 0.001
    dim dist_pt_to_seg as double
    for i = 0 to numpts-2 'different for closed pline's ?
    dist_pt_to_seg = Dist_Pt_Ln (pickpt, acPoint3D(x(i),y(i),z(i)),
    acPoint3D(x(i+1),y(i+1),z(i+1)))
    if abs(dist_pt_to_seg) < FUZZ then
    'insert new vertex after i'th vertex and stop checking
    exit for
    endif
    next 'i
    [/pseudocode]


    Code:
    Function Dist_Pt_Ln(Pt As Variant, EndA As Variant, EndB As Variant) As
    Double
    
    'courtesy http://softsurfer.com/Archive/algorithm_0102/algorithm_0102.htm
    'cross-product formulation used
    
    Dim w(0 To 2) As Double
    Dim u(0 To 2) As Double
    Dim v(0 To 2) As Double
    Dim UxW(0 To 2) As Double
    Dim len_v As Double, w_dot_u As Double
    
    v(0) = EndB(0) - EndA(0)
    v(1) = EndB(1) - EndA(1)
    v(2) = EndB(2) - EndA(2)
    w(0) = Pt(0) - EndA(0)
    w(1) = Pt(1) - EndA(1)
    w(2) = Pt(2) - EndA(2)
    len_v = Sqr(v(0) ^ 2 + v(1) ^ 2 + v(2) ^ 2)
    
    u(0) = v(0) / len_v:  u(1) = v(1) / len_v
    u(2) = v(2) / len_v
    
    UxW(0) = u(1) * w(2) - u(2) * w(1)
    UxW(1) = u(2) * w(0) - u(0) * w(2)
    UxW(2) = u(0) * w(1) - u(1) * w(0)
    
    Dist_Pt_Ln = Sqr(UxW(0) ^ 2 + UxW(1) ^ 2 + UxW(2) ^ 2)
    
    End Function
    
    
    
    Public Function acPoint3D(x As Double, y As Double, Optional z As Double =
    0) As Variant
    ' courtesy www.acadx.com
    Dim retVal(0 To 2) As Double
    retVal(0) = x: retVal(1) = y: retVal(2) = z
    acPoint3D = retVal
    End Function
    
    
     
    James Belshan, Jun 9, 2004
    #5
  6. James,

    What I had in mind is function that adds a vertex at picked point along the
    polyline. Like BREAK and PLJOIN functions incombined. ACAD is generally
    missing such generic function, while PEDIT is the only possible (but by far
    complicated) exit. Many users I've been working with are mainly switching
    from other vector-based applications (Corel, Visio...) to ACAD and they
    usually miss some sort of Add-Vertex-At-Picked-Point functionality.

    As I'm in development of tools that immitate Autodesk's MAP ones, I'm fully
    aware of ACAD's backdraws when we talk about
    precision/exactness/ease-of-use. There's also Autodesk's lean towards GIS
    implementation, and it has a lot to do with it, but I guess this reply is
    way way out of topic this time... :)

    Regards,
    Maksim Sestic


     
    Maksim Sestic, Jun 10, 2004
    #6
  7. OOPS... BIG ERROR...(but simple fix)... I used a "Distance from Point to
    Line" function, when I needed to use a "Distance from Point to Line SEGMENT"
    function.... I believe that same website had an algorithm for this function,
    too. I don't have one coded.
     
    James Belshan, Jun 10, 2004
    #7
  8. Maksim,
    Yes, my reply was attempting to do the same thing that you are, "Add a New
    Vertex" functionality. Maybe my explanation paragraph was not all that
    great. (Also, see my other reply for an error I just saw). As you
    suggested, if the OSNAP NEAREST was used, you know that the picked point
    would lie on the PLINE. All I was trying to add was a good way to figure
    out which segment was clicked on. The answer was that the segment that was
    clicked should have near-zero distance between the point and the segment,
    measured perpendicular.

    From here, the options are endless... if you don't want to use OSNAP, you
    can just iterate all the segments and use the minimum distance as the picked
    segment... very user-friendly and forgiving in case the user changes the
    OSNAP manually or doesn't pick close enough to the PLINE to make the OSNAP
    happen. You can also have a tolerance similar to the PICK WINDOW size -- if
    the closest segment is further away than this distance, then the user didn't
    get close enough to any segments.... so return nothing. Also, not forcing
    OSNAPS allows you to add the vertex away from the PLINE and add shape.


    James
     
    James Belshan, Jun 10, 2004
    #8
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.