LISP Advice

LISP Advice

mjshaffer117
Enthusiast Enthusiast
1,057 Views
12 Replies
Message 1 of 13

LISP Advice

mjshaffer117
Enthusiast
Enthusiast

 

 

(defun c:divline ( / pt1 pt2 div ang maths ent)
  (setq pt1 (getpoint "Select first point: "))
  (setq pt2 (getpoint "Select end point: "))
  (setq div (getint "Enter number of segments to divide line: "))
  (setq ang (angle pt1 pt2))
  (entmake (list
	     '(0 . "LINE")
	     '(8 . "0")
	     (cons 10 (polar pt1 (angle pt1 pt2) 0))
	     (cons 11 (polar pt2 (angle pt1 pt2) 0))
	     )
	   )
  (setq maths (/ (distance pt1 pt2) div))
  (entmake (list
	     '(0 . "LINE")
	     '(8 . "CX-TEXT")
	     (cons 10 (polar pt1 (+ ang (/ pi 2)) 0.25))
	     (cons 11 (polar pt1 (- ang (/ pi 2)) 0.25))
	     )
	   )
  (repeat div
    (setq ent (entlast))
    (command "._offset" maths ent pt2 "")
    )
(princ)
  )

 

 

 

Hello all!

 

I'm still learning LISP and I'm looking to try and take more advance approaches on my writing. The attached code works fine, but I'm curious to see if there is a more logical approach that I may not be thinking of. Any advice on how I can write more logically or any outside of the box approaches using different functions would be great! Looking forward to continuously improving!

 

Thanks in advance! 😁

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

Kent1Cooper
Consultant
Consultant
Accepted solution

I suggest you go to the >Customization Forum< where AutoLisp is the lingua franca.

Kent Cooper, AIA
0 Likes
Message 3 of 13

ВeekeeCZ
Consultant
Consultant
Accepted solution

Check the user input. Can the code handle if div is zero, neg or nil without crash?

 

(defun c:divline ( / pt1 pt2 div ang maths ent)
  
  (if (and (setq pt1 (getpoint "Select first point: "))
	   (setq pt2 (getpoint "Select end point: "))
	   (or (not (equal pt1 pt2))
	       (prompt "Error: Wrong input. Points can't be equal."))
	   (not (initget (+ 1 2 3)))
	   (setq div (getint "Enter number of segments to divide line: "))
	   )
    (progn
      (setq ang (angle pt1 pt2))
      (entmake (list
		 '(0 . "LINE")
		 '(8 . "0")
		 (cons 10 (polar pt1 (angle pt1 pt2) 0))
		 (cons 11 (polar pt2 (angle pt1 pt2) 0))
		 )
	       )
      (setq maths (/ (distance pt1 pt2) div))
      (entmake (list
		 '(0 . "LINE")
		 '(8 . "CX-TEXT")
		 (cons 10 (polar pt1 (+ ang (/ pi 2)) 0.25))
		 (cons 11 (polar pt1 (- ang (/ pi 2)) 0.25))
		 )
	       )
      (repeat div
	(setq ent (entlast))
	(command "._offset" maths ent "_non" pt2 "") ; make sure that OSNAPS are OFF when you supply a point within the commmand func.
	)
      ))
  (princ)
  )

 

0 Likes
Message 4 of 13

CodeDing
Advisor
Advisor

@mjshaffer117 ,

 

How do you feel about (command ...) calls? Lol

(defun c:DIVLINE ( / )
  (command "_.LINE" pause pause "")
  (command "_.DIVIDE" (entlast) pause)
  (princ)
);defun

Best,

~DD

0 Likes
Message 5 of 13

pbejse
Mentor
Mentor
Accepted solution

@mjshaffer117 wrote:

I'm still learning LISP..

Good for you.

Here's another

(defun c:divline ( / pt1 pt2 _line div ang maths )
(defun _line (p1 p2 lay)
  (entmake (list
	     (cons 0 "LINE") (cons 8  lay )
	     (cons 10 p1) (cons 11 p2)
	     		)
		)	   
	)
(initget 6)  
(if
  (and
        (setq div (getint "Enter number of segments to divide line: "))
  	(setq pt1 (getpoint "Select first point: "))
  	(setq pt2 (getpoint pt1 "Select end point: "))	  	
	)
	(progn
  		(setq ang (angle pt1 pt2))
	        (setq maths (/ (distance pt1 pt2) div))	  	
	        (_line pt1 pt2 "0")
	  	(setq pt1 (polar pt1 (+ ang (/ pi 2)) 0.25))
	        (setq pt2 (polar pt1 (- ang (/ pi 2)) 0.50))
	  	(repeat (1+ div)
		  (_line pt1 pt2 "CX-TEXT")
		  (setq pt1 (polar pt1 ang maths))
		  (setq pt2 (polar pt2 ang maths))
		 )
	  )
	  (princ (strcat "\nInvalid or null"
	    (cond
	      ((null div) " number of segments")
	      ((or (null pt1)(null pt2)) " point value")
	      		)
		)	    
	  )
  )
(princ)
  )

You may also want to ask for the length of the divider.

0 Likes
Message 6 of 13

john.uhden
Mentor
Mentor
Accepted solution

Along with the required improvements that @ВeekeeCZ and @pbejse showed you, rather than

(if
  (and ...)
  (progn ...)
)

the long (and ...), as taught to me by Stephan Koster, might condense the code...

(and
  (setq ...)
  (setq ...)
  (entmakex ...)
  (not (initget ...))
  ;; etc.
)

It works because AutoCAD will continue evaluating each expression until one returns nil, then it stops evaluating what's inside the (and).

John F. Uhden

0 Likes
Message 7 of 13

ВeekeeCZ
Consultant
Consultant

I've missed this one.... what's the logic of these again?

 

		 (cons 10 (polar pt1 (angle pt1 pt2) 0))
		 (cons 11 (polar pt2 (angle pt1 pt2) 0))

Which reminds me... consider that (getpoint) returns coordinates in UCS while (entmake) needs coords in WCS.

 

0 Likes
Message 8 of 13

Kent1Cooper
Consultant
Consultant

@ВeekeeCZ wrote:
....
	   (not (initget (+ 1 2 3)))
....

That should be:

  (not (initget (+ 1 2 4)))

[The 1 prevents the User from pressing Enter, the 2 forbids zero, the 4 forbids negative input.]

Kent Cooper, AIA
0 Likes
Message 9 of 13

john.uhden
Mentor
Mentor
It appears to be an exercise to be sure that pt1 is exactly at pt1 and that
pt2 is exactly at pt2. Sorta like (setq T (not nil)).☺
Then again there may be a difference for large values of 0.😂

John F. Uhden

0 Likes
Message 10 of 13

Kent1Cooper
Consultant
Consultant

@CodeDing wrote:

....

(defun c:DIVLINE ( / )
  (command "_.LINE" pause pause "")
  (command "_.DIVIDE" (entlast) pause)
  (princ)
);defun

....


That would put POINT objects along the Line, rather than the perpendicular LINE markers they apparently want [I haven't tried it].  And it would not put them at the ends as they apparently want.

Kent Cooper, AIA
0 Likes
Message 11 of 13

CodeDing
Advisor
Advisor

@Kent1Cooper ,

 

Ahhhh, yes I was zoomed out VERY far hahah, I assumed they were 0 length lines. Didn't look into it as far as I should have. Shame

 

Thanks

0 Likes
Message 12 of 13

Sea-Haven
Mentor
Mentor

Ucs ob line, array perp line ?? Not sure how much code saved. Just a different way to do it.

0 Likes
Message 13 of 13

mjshaffer117
Enthusiast
Enthusiast

Sorry for the late reply! Thanks all for the advice and feedback! This was more of a practice kind of thing to get better with LISP.

@ВeekeeCZ & @john.uhden I tend to forget having error handlers in stuff like this, thanks for the reminder! I'll be sure to be more mindful when writing my future routines!

@pbejse I appreciate the route using a function within a function! Definitely would like to get more familiar with implementing that as much as possible since it's a frequent thing! Seems like the next step for me!