select lwpolyline then move to next vertex to get the angle

select lwpolyline then move to next vertex to get the angle

Anonymous
Not applicable
602 Views
7 Replies
Message 1 of 8

select lwpolyline then move to next vertex to get the angle

Anonymous
Not applicable
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?
0 Likes
603 Views
7 Replies
Replies (7)
Message 2 of 8

Anonymous
Not applicable
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 > 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" wrote in message news:40c5ec8c_1@newsprd01... > 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?
0 Likes
Message 3 of 8

Anonymous
Not applicable
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
0 Likes
Message 4 of 8

Anonymous
Not applicable
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 "wivory" wrote in message news:[email protected]... > 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
0 Likes
Message 5 of 8

Anonymous
Not applicable
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 [/code]
0 Likes
Message 6 of 8

Anonymous
Not applicable
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 "James Belshan" wrote in message news:40c708b5$1_3@newsprd01... > > 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 > > [/code] > >
0 Likes
Message 7 of 8

Anonymous
Not applicable
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. > 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 >
0 Likes
Message 8 of 8

Anonymous
Not applicable
"Maksim Sestic" wrote in message news:40c86e8f_1@newsprd01... > James, > > What I had in mind is function that adds a vertex at picked point along the > polyline. Like BREAK and PLJOIN functions incombined. > > ... some sort of Add-Vertex-At-Picked-Point functionality. > 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
0 Likes