TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: jaydee on August 23, 2011, 12:44:48 AM

Title: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: jaydee on August 23, 2011, 12:44:48 AM
Hi.
I couldn't find anything about returning the vertex angle of a multi-vertices polyline/mline
What i could think of is to compare the picked point with a set vertex points

What i would like to know which 2 points in the list "Lst" is my picked point "PP1" sit in between, then work out the angle from here?

Code: [Select]
(setq a (entsel))
(setq PP1 (car (cdr  a)))
==>(4255.76 23382.0 0.0)

(setq c (entget (car a)))

(setq lst (massoc 10 c))    ;;;for lwpolyline
==>((-1389.12 21356.8) (1946.27 24398.4) (3218.53 21477.1) (4972.19 24484.3)
(7447.94 21374.0) (9682.99 24312.5))

(setq lst (massoc 11 c))    ;;;for Mline

(defun massoc (key alist / x nlist)          ; Jaysen Long
  (foreach x alist
    (if
      (eq key (car x))
      (setq nlist (cons (cdr x) nlist))
      )
    )
  (reverse nlist)
  )

What i have been using to get the angle is via the osnap option. I could be wrong about the osnap option is, if the selected polyline sitting on top of a very crowded background(xref) with lots of lines underneath, then I believe the result could be inconsistent.

Code: [Select]
(setvar "osmode" 512)  ;;;NEArest
(setq a (getpoint))
(setq midpt (osnap a "mid"))
(setq endpt (osnap a "end"))
(setq plang (angle midpt endpt))

Thankyou
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: Jeff_M on August 23, 2011, 02:26:18 AM
Look into the (vlax-curve-*) functions. (vlax-curve-paramatpoint will give you the segment the point is on (4.23 would mean the point is 23% along the 5th segment). SO from this you can get the PointAtParam for Params 3.0 (the 4th vertex) and 4.0 (the 5th vertex) and 5.0 (the 6th vertex). From those 3 points you can get the angle. The Params are 0 based with 0.0 usually being the startparam (Usually = almost always...Owen Wengard pointed out specific circumstances whereby programmers could alter this, but in my 20+ years working in Autocad I have yet to see it in my everyday use).
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: kruuger on August 23, 2011, 06:51:46 AM
Code: [Select]
(defun c:TEST ( / OB EN PT SEG PRE_SEG POST_SEG)
  (setq OB (entsel "\nSelect polyline segment: "))
  (setq EN (car OB))
  (setq PT (cadr OB))
  (setq PT (vlax-Curve-GetClosestPointTo EN PT))
  (princ
    (strcat
      "\n-> Point on line: ("
      (vl-String-Trim "()" (vl-Princ-To-String PT))
      ")"
    )
  )
  (princ
    (strcat
      "\n-> Segment:       "
      (itoa (fix (setq SEG (vlax-curve-getParamAtPoint EN PT))))
    )
  )
  (princ
    (strcat
      "\n-> Start vertex:  "
      (itoa (setq PRE_SEG (fix SEG))) " | Coord.: ("
      (vl-String-Trim "()" (vl-Princ-To-String (vlax-Curve-GetPointAtParam EN PRE_SEG)))
      ")"
    )
  )
  (princ
    (strcat
      "\n-> End vertex:    "
      (itoa (setq POST_SEG (1+ PRE_SEG))) " | Coord.: ("
      (vl-String-Trim "()" (vl-Princ-To-String (vlax-Curve-GetPointAtParam EN POST_SEG)))
      ")"
    )
  )
  (textscr)
  (princ)
)
it will be useful ?
kruuger
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: jaydee on August 23, 2011, 08:05:37 AM
Thankyou Jeff and kruuger for the code and advice. and CAB for links, will read into it
Time to rework and finetune some of my codes.
Cheers
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: CAB on August 23, 2011, 08:12:54 AM
http://www.theswamp.org/index.php?topic=6068.msg74059#msg74059
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: CAB on August 23, 2011, 08:15:35 AM
;;  get all the angles by  Lee Mac
;;  http://www.theswamp.org/index.php?topic=36124.msg412421#msg412421

;;  Evgeniy
;;  http://www.theswamp.org/index.php?topic=36124.msg412442#msg412442
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: Lee Mac on August 23, 2011, 09:39:20 AM
For a polyline, I would agree to use the vlax-curve-* functions, however, since an MLine is not a Curve Object, one cannot use the vlax-curve-* functions with it.

Below is an example to return the interior & exterior angles of the selected segment of an MLine, the returned angles are formatted using the angtos function so that you can see which angles are being calculated, but in practice, radians would be returned.

Code: [Select]
(defun c:test ( / e l p )
    (if
        (and
            (setq e (entsel "\nSelect MLine: "))
            (setq p (trans (cadr e) 1 0))
            (eq "MLINE" (cdr (assoc 0 (setq e (entget (car e))))))
        )
        (progn
            (setq l (LM:mAssoc 11 e))
            (setq p
                (car
                    (vl-sort-i
                        (mapcar
                            (function
                                (lambda ( a b )
                                    (distance p (LM:ProjectPointToLine p a b))
                                )
                            )
                            l (append (cdr l) (list (car l)))
                        )
                        '<
                    )
                )
            )
            (
                (lambda ( a ) (mapcar 'angtos (list a (- (+ pi pi) a))))
                (cond
                    (   (zerop p)
                        (LM:GetLeftAngle (last l) (car l) (cadr l))
                    )
                    (   (= p (1- (length l)))
                        (LM:GetLeftAngle (nth (1- p) l) (last l) (car l))
                    )
                    (   t
                        (LM:GetLeftAngle (nth (1- p) l) (nth p l) (nth (1+ p) l))
                    )
                )
            )
        )
    )
)

(defun LM:mAssoc ( key lst / pair )
    (if (setq pair (assoc key lst))
        (cons (cdr pair) (LM:mAssoc key (cdr (member pair lst))))
    )
)

(defun LM:ProjectPointToLine ( pt p1 p2 / nm )
    (setq nm (mapcar '- p2 p1)
          p1 (trans p1 0 nm)
          pt (trans pt 0 nm)
    )
    (trans (list (car p1) (cadr p1) (caddr pt)) nm 0)
)

(defun LM:GetLeftAngle ( p1 p2 p3 )
    (rem (+ pi pi (- (angle p2 p1) (angle p2 p3))) (+ pi pi))
)

(vl-load-com) (princ)
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: jaydee on August 23, 2011, 07:31:55 PM
Hi Lee. Thankyou for the code.
Just tested on multi segment MLINE drawn zigzag @ 45deg.
The FIRST segment seems to return incorrect angles ("316.45198912" "43.54801088")
The others OK ("270.00000000" "90.00000000").

What i need is the angle of the straight segment, NOT the angles between 2 segments

Cheers
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: Lee Mac on August 23, 2011, 07:47:52 PM
The FIRST segment seems to return incorrect angles ("316.45198912" "43.54801088")

The first segment will return the interior/exterior angle between the start vertex and end vertex (undefined for open MLines, defined for closed MLines).

What i need is the angle of the straight segment, NOT the angles between 2 segments

It seems that I misunderstood the task - I saw CAB's links and thought that was what you were looking for  :oops:

Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: Lee Mac on August 23, 2011, 07:51:22 PM
Try this instead:

Code: [Select]
(defun c:test ( / e l p )
    (if
        (and
            (setq e (entsel "\nSelect MLine: "))
            (setq p (trans (cadr e) 1 0))
            (eq "MLINE" (cdr (assoc 0 (setq e (entget (car e))))))
        )
        (progn
            (setq l (LM:mAssoc 11 e))
            (setq p
                (car
                    (vl-sort-i
                        (mapcar
                            (function
                                (lambda ( a b )
                                    (distance p (LM:ProjectPointToLine p a b))
                                )
                            )
                            l (append (cdr l) (list (car l)))
                        )
                        '<
                    )
                )
            )
            (angtos
                (cond
                    (  (= p (1- (length l)))
                       (angle (last l) (car l))
                    )
                    (  t
                       (angle (nth p l) (nth (1+ p) l))
                    )
                )
            )
        )
    )
)

(defun LM:mAssoc ( key lst / pair )
    (if (setq pair (assoc key lst))
        (cons (cdr pair) (LM:mAssoc key (cdr (member pair lst))))
    )
)

(defun LM:ProjectPointToLine ( pt p1 p2 / nm )
    (setq nm (mapcar '- p2 p1)
          p1 (trans p1 0 nm)
          pt (trans pt 0 nm)
    )
    (trans (list (car p1) (cadr p1) (caddr pt)) nm 0)
)

(vl-load-com) (princ)
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: CAB on August 23, 2011, 07:57:38 PM
I was just opening doors, not serving the meal. 8-)
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: Lee Mac on August 23, 2011, 07:59:19 PM
I was just opening doors, not serving the meal. 8-)

Oh I wasn't blaming you, I should have read the thread a little more thoroughly  :ugly:
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: LE3 on August 23, 2011, 08:04:07 PM
I was just opening doors, not serving the meal. 8-)

Wonder what the OP it is doing.... well just eating  :roll:
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: jaydee on August 23, 2011, 08:10:02 PM
Lee. What amaze me is how do you manage to write a code so quickly. :blank: :blank:

I unserstand what CAB trying to say. I admit im a slow leaner and at the moment Im only capable of modding an existing code and scouge bits and pieces of scatter codes and trying to make it into a functional lisp.

Ta
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: LE3 on August 23, 2011, 08:21:14 PM
Lee. What amaze me is how do you manage to write a code so quickly. :blank: :blank:

I unserstand what CAB trying to say. I admit im a slow leaner and at the moment Im only capable of modding an existing code and scouge bits and pieces of scatter codes and trying to make it into a functional lisp.

Ta

Let me say this:

All here at theSwamp know about Lee's skills - He it is a master and apart likes to help without asking anything - no questions about it - Great guy indeed.

Now, me/and guess we, would like to see others putting more efforts, to show what the have done so far or what they can do, code skeletons, pseudo-code, ideas on how to solve things, etc...

TheSwamp have already a bunch of open-source code available to search and to put together - from simple routines to gems and why not to some day match Lee's code.

My 0.2 cts. 
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: jaydee on August 23, 2011, 08:31:44 PM
Hi. Just a matter of interest and curiosity on LM Reply #6

What is the potetial usage of returning the angles between 2 Pline/Mline segment when user select a segment. and returning the angles.

Take the zigzag pline for example, depending on where the start point of pline is being drawn from L-R, R-L, T-B, B-T.

Because of the uncertain angles return base on visual on screen.
ie. if i select a vertex and expect the return angles of the selected vertex and the next vertex on the right/top.
but without knowingly the pline was drawn from L-R or T-B, then the return angle is not what the user expected.

Just curious in a situation like this, how can user utilise the return angles.

Thankyou

Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: jaydee on August 24, 2011, 01:29:19 AM
Quote
Wonder what the OP it is doing.... well just eating

I didn't ask for this. Something like this not going to be appriciated. :-(
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: Lee Mac on August 24, 2011, 05:15:43 AM
Hi. Just a matter of interest and curiosity on LM Reply #6

What is the potetial usage of returning the angles between 2 Pline/Mline segment when user select a segment. and returning the angles.

I can't immediately think of use - I initially thought that was the result you were looking for and so put together an example to demonstrate one way to approach the problem.
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: Lee Mac on August 24, 2011, 05:22:19 AM
All here at theSwamp know about Lee's skills - He it is a master and apart likes to help without asking anything - no questions about it - Great guy indeed.

Now, me/and guess we, would like to see others putting more efforts, to show what the have done so far or what they can do, code skeletons, pseudo-code, ideas on how to solve things, etc...

TheSwamp have already a bunch of open-source code available to search and to put together - from simple routines to gems and why not to some day match Lee's code.

Many thanks Luis, I appreciate your kind comments :-) - although, I'll be the first to say that there are definitely others here much more knowledgeable than I, (you, for example  :wink: ) I'm still learning a lot myself.

Although, by providing complete program examples, I'm probably not helping to encourage others to learn to write such programs for themselves. But I do enjoy writing the code and sometimes it is easier to explain a method using the code as an example.
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: CAB on August 24, 2011, 09:07:02 AM
Hi. Just a matter of interest and curiosity on LM Reply #6

What is the potetial usage of returning the angles between 2 Pline/Mline segment when user select a segment. and returning the angles.

Take the zigzag pline for example, depending on where the start point of pline is being drawn from L-R, R-L, T-B, B-T.

Because of the uncertain angles return base on visual on screen.
ie. if i select a vertex and expect the return angles of the selected vertex and the next vertex on the right/top.
but without knowingly the pline was drawn from L-R or T-B, then the return angle is not what the user expected.

Just curious in a situation like this, how can user utilize the return angles.

Thankyou

Maybe if you want to bisect the angles between segments, but there are no way to guess the reasons for request
as evidenced by some of the posts this site.

FYI, Typically the multi segment pline directions are often referred to as clockwise or counter clockwise. CW or CCW

For more info on pline routines look here:
Code: [Select]
----------  Remove a LWpolyline Vertex  --------
http://www.theswamp.org/index.php?topic=19865.0
http://www.theswamp.org/index.php?topic=5251.0
http://www.theswamp.org/index.php?topic=10344

------------  Remove  Bulge  ---------------
http://www.theswamp.org/index.php?topic=34134.0  Tim Willey

-----------  Add a  LWpolyline Vertex  ------------
http://www.theswamp.org/index.php?topic=18720.0
http://www.theswamp.org/index.php?topic=30170

-----------  Polyline Reverse  -------------------
http://www.theswamp.org/index.php?topic=12618.msg155016#msg155016  gile
http://www.theswamp.org/Themes/oxygen11final/images/post/xx.gif Evgeniy
http://www.theswamp.org/index.php?topic=32603.0  alanjt
http://www.theswamp.org/index.php?topic=1116.msg14511#msg14511 CAB 2004
http://www.theswamp.org/index.php?topic=12618.msg198982#msg198982 CAB
http://www.theswamp.org/index.php?topic=1116.msg14514#msg14514

-----------  Point Inside Pline  -------------------
http://www.theswamp.org/index.php?topic=7785.0
http://groups.google.com/group/autodesk.autocad.customization/browse_thread/thread/6ec20cba1a1f9efe/79056df13e3f42b1?q=%40cv_inside+group:autodesk.autocad.customization#79056df13e3f42b1
http://groups.google.com/group/autodesk.autocad.customization/attach/42682170bb9ac419/%40cv_inside.lsp?part=2
Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: jaydee on August 24, 2011, 05:46:10 PM
Look into the (vlax-curve-*) functions. (vlax-curve-paramatpoint will give you the segment the point is on (4.23 would mean the point is 23% along the 5th segment). SO from this you can get the PointAtParam for Params 3.0 (the 4th vertex) and 4.0 (the 5th vertex) and 5.0 (the 6th vertex). From those 3 points you can get the angle. The Params are 0 based with 0.0 usually being the startparam (Usually = almost always...Owen Wengard pointed out specific circumstances whereby programmers could alter this, but in my 20+ years working in Autocad I have yet to see it in my everyday use).

Thankyou Lee and CAB pointing me to thr right direction.
To be frank, sometime i dont even know where to start looking. As suggested by Jeff_M about vlax-curve functions that i never come across them before, therefor even if i see something like that in the seach, it still might not click. IOU heaps

Title: Re: How to get the angle of the Picked vertex on multi-vertex polyline or Mline
Post by: CAB on August 25, 2011, 08:51:44 AM
More on the curve and angles.
;;  http://www.theswamp.org/index.php?topic=13545.msg163960#msg163960
;;  http://www.theswamp.org/index.php?topic=13613.msg165579#msg165579