Arrow Leader LISP

Arrow Leader LISP

ensomoran
Contributor Contributor
1,542 Views
12 Replies
Message 1 of 13

Arrow Leader LISP

ensomoran
Contributor
Contributor

This was my first attempt at making a LISP routine for myself.  Everything works fine except for the fact that when I use a "Clockwise" motion to draw the arch the arrow comes in 180 degrees in the wrong direction.  Everything works fine when I draw it with a counter-clock wise motion.

 

I'm pretty sure this is a funky geometry thing but can any one help me troubleshoot this/improve what I have so far?

 

Any comments about syntax and best practices would also be appreciated.

0 Likes
Accepted solutions (2)
1,543 Views
12 Replies
Replies (12)
Message 2 of 13

ВeekeeCZ
Consultant
Consultant

Did not test it  but it seem that wrong type parentheses could be the culprit.

 

[setq ar_ang (- ang 1.57)]

 

Also, instead of 1.57 I would use (/ pi 2)

0 Likes
Message 3 of 13

ensomoran
Contributor
Contributor

While this was a mistake it seems to have not resolved the issue

0 Likes
Message 4 of 13

ВeekeeCZ
Consultant
Consultant

An arc is tricky, how about to use a polyline?

 

(vl-load-com)

(defun c:artic nil

  (command "_pline" pause "_a" "_s" pause pause ""
	   "_.insert" "arrow" "_s" 1
	   "_r" (angtos (+ (/ pi 2) (angle (vlax-curve-getsecondderiv (entlast) (vlax-curve-getendparam (entlast))) '(0 0 0))) 0 6)
	   "_non" (getvar 'lastpoint))
  (princ)
  )

 

0 Likes
Message 5 of 13

Kent1Cooper
Consultant
Consultant

Just in terms of format:

....
(if (<= ang 1.57); parentheses issues; not ar_ang
  (setq ar_ang (+ ang 1.57)); then
  (setq ar_ang (- ang 1.57)); else -- parentheses, not brackets
)
....

 

But I don't think what you really want to test is whether the angle from the center to an end is <= 90°.

 

And I agree, (/ pi 2) is better than 1.57, however small the difference.

Kent Cooper, AIA
0 Likes
Message 6 of 13

ВeekeeCZ
Consultant
Consultant

...or the arc version with your/Kent's ang calculation.

 

(vl-load-com)

(defun c:artic ( / ang)

  (command "_.arc" pause pause pause)
  (setq ang (angle (vlax-curve-getsecondderiv (entlast) (vlax-curve-getparamatpoint (entlast) (getvar 'lastpoint))) '(0 0 0))
	ang (+ ang pi (/ pi (if (<= ang (/ pi 2)) 2 -2))))
  (command "_.insert" "arrow" "_s" 1
	   "_r" (angtos ang 0 6)
	   "_non" (getvar 'lastpoint))
  (princ)
  )

 

0 Likes
Message 7 of 13

ensomoran
Contributor
Contributor

Yeah I know the Pline would be easier but the standard we use at my company is an arch for the end of branch circuits on drawings.  When the arrows are not tangent to the end of the arch it pisses some people off.

0 Likes
Message 8 of 13

ВeekeeCZ
Consultant
Consultant

See THIS how to use a VLIDE for debugging.

0 Likes
Message 9 of 13

ensomoran
Contributor
Contributor

I think this one better than my code because it lets me see the arch before its placed but I have not idea how this one works.  It also still has the same issues as my original code, the arrow is 180 degrees off of when you draw it clockwise.

0 Likes
Message 10 of 13

ВeekeeCZ
Consultant
Consultant
Accepted solution

I see... I did not test it well. 

 

So lets get back to a pline which... does not require that silly ang calculation.

 

(vl-load-com)

(defun c:artic (/ ent)

  (command "_pline" pause "_a" "_s" pause pause ""
	   "_.insert" "arrow" "_s" 1
	   "_r" (angtos (+ (/ pi 2) (angle (vlax-curve-getsecondderiv (setq ent (entlast)) (vlax-curve-getendparam (entlast))) '(0 0 0))) 0 6)
	   "_non" (getvar 'lastpoint)
	   "._explode" ent)
  (princ)
  )

 

0 Likes
Message 11 of 13

Kent1Cooper
Consultant
Consultant
Accepted solution

@Kent1Cooper wrote:

....

But I don't think what you really want to test is whether the angle from the center to an end is <= 90°.

....


If you're willing to be restricted to drawing the Arc by 3 points [not some of the other optional ways, which could involve different numbers of inputs, or result in a different ending direction], you can avoid the need to check for the angle, and the problem of the Arc's information always being stored as if it was drawn CCW, and which way you actually drew it, and finding its center, and saving points to variables, and all that, by using the LASTANGLE System Variable.  Try this:

 

(defun C:ARTIC ()

  (prompt "\nDraw 3-point Arc:\n")

  (command

    "_.arc" pause pause pause

    "_.insert" "ARROW" "@" "" "" (cvunit (getvar 'lastangle) "radian" "degree")

  )

)

 

Kent1Cooper_0-1679588397715.png

 

Kent Cooper, AIA
Message 12 of 13

ensomoran
Contributor
Contributor

@Kent1Cooper @ВeekeeCZ Thank you both of these work just fine, I need to study these a little to really understand whats going on but this helps a lot.  

0 Likes
Message 13 of 13

Kent1Cooper
Consultant
Consultant

The LASTANGLE approach will also work after drawing it as a Polyline of one arc segment, rather than calculating angles by derivatives and parameters in (vlax-curve....) functions, etc.  But if it's going to be drawn by 3 points, and end up Exploded into a regular Arc anyway, it doesn't seem worth drawing it as a Polyline in the first place.

Kent Cooper, AIA
0 Likes