clean up lisp code

clean up lisp code

AcmeMfgEng
Contributor Contributor
562 Views
7 Replies
Message 1 of 8

clean up lisp code

AcmeMfgEng
Contributor
Contributor

Group,

 

When programming cnc lathes I sometimes layout the shape of the cutting insert in my drawing to ensure it will have the appropriate clearances to turn a particular feature. I got tired of drawing the inserts "long hand", so I cobbled together this basic lisp which works for me. The lisp is currently limited to diamond shaped inserts.

I have little experience with lisp programming, and am interested in how the code can be cleaned up a little. Any direction you may provide would be appreciated!

 

BTW, if you test run the lisp, common inserts that I use typically have:

IC: Ø.375, Ø.500, or Ø.625

Insert angle: 35°, 55°, or 80°

Corner radius: .008", .016", .031", .047", or .062"

 

Best regards,

Chris

 

(defun c:nmg ()
	(setq InsertIC (getreal "\nEnter IC radius :"))
	(setq InsertAng (getreal "\nEnter insert angle :"))
	(setq InsertRad (getreal "\nEnter corner radius :"))
	(setq StartPt (getpoint "\nStart Point corner of insert: "))
	(setvar "ORTHOMODE" 1)
	(setq AlignIns (getpoint "\nPick Direction: "))
	;divide angle by 2
	(setq HalfAng (/ InsertAng 2))
	;get radians of angle
	(setq HalfAngRdn (dtr HalfAng))
	;get tangent of angle
	(setq HalfAngTan (tan HalfAngRdn))
	;calculate length of side
	(setq SideLen (+ (* InsertIC HalfAngTan) (/ InsertIC HalfAngTan)))
	;define insert corner points
	(setq pt2 (polar StartPt 0 SideLen))
	(setq pt3 (polar pt2 (dtr InsertAng) SideLen))
	(setq pt4 (polar pt3 (dtr 180) SideLen))
	(command "pline" StartPt pt2 pt3 pt4 StartPt "")
	(command "._FILLET" "P" "R" InsertRad "L")
	(setvar 'OSMODE 4)
	(command "ROTATE" "L" "" "APP" StartPt AlignIns "R" "APP" StartPt AlignIns StartPt AlignIns)
	(setvar 'OSMODE 39)
)
;; Tangent  -  Lee Mac
;; Args: x - real
(defun tan (x)
    (if (not (equal 0.0 (cos x) 1e-10))
        (/ (sin x) (cos x))
    )
)
;;
;This function converts Degrees to Radians.
(defun dtr (dr)
	;define degrees to radians function
	(* pi (/ dr 180.0))
	;divide the angle by 180 then
	;multiply the result by the constant PI
)

 

 

0 Likes
Accepted solutions (1)
563 Views
7 Replies
Replies (7)
Message 2 of 8

komondormrex
Mentor
Mentor

hth

(defun c:diamond ()
  (setq inscribed_circle_radius (getreal "\nEnter inscribed circle radius: ")
      diamond_half_inner_angle (* 0.5 (getreal "\Enter inner angle: ") (/ pi 180))
      half_diagonal (/ inscribed_circle_radius (sin diamond_half_inner_angle))
      diamond_vertex_point (getpoint "\nPick diamond vertex point: ")
      diamond_incline_angle (getangle diamond_vertex_point "\Enter diamond incline angle: ")
      diamond_fillet_radius (getreal "\nEnter diamond fillet radius: ")
  )
  (vla-put-closed
    (vla-addlightweightpolyline (vla-get-block (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object))))
       (vlax-safearray-fill (vlax-make-safearray vlax-vbdouble (cons 0 7))
          (apply 'append (mapcar '(lambda (vertex) (mapcar '+ '(0 0) vertex))
                      (list diamond_vertex_point
                        (polar diamond_vertex_point (+ diamond_incline_angle diamond_half_inner_angle) (/ half_diagonal (cos diamond_half_inner_angle)))
                        (polar diamond_vertex_point diamond_incline_angle (* 2 half_diagonal))
                        (polar diamond_vertex_point (- diamond_incline_angle diamond_half_inner_angle) (/ half_diagonal (cos diamond_half_inner_angle)))
                      )
                 )
          )
       )
    )
    :vlax-true
  )
  (command "_fillet" "_p" "_r" diamond_fillet_radius (entlast))
)
0 Likes
Message 3 of 8

paullimapa
Mentor
Mentor
Accepted solution

This is pretty good already but I would do the following:

Localize all variables & functions like tan & dtr in case they're defined differently by other lisp routines.

(defun c:nmg 
 (/ AlignIns dtr HalfAng HalfAngRdn HalfAngTan 
    initgetdyn InsertAng InsertIC InsertRad 
    orthomode osmode
    pt2 pt3 pt4 rtd SideLen StartPt tan
 ) ; alphabetically localize variables and functions
;; Tangent  -  Lee Mac
;; Args: x - real
(defun tan (x)
    (if (not (equal 0.0 (cos x) 1e-10))
        (/ (sin x) (cos x))
    )
)
;;
;This function converts Degrees to Radians.
(defun dtr (dr)
	;define degrees to radians function
	(* pi (/ dr 180.0))
	;divide the angle by 180 then
	;multiply the result by the constant PI
)
; This function converts Radians to Degrees  
(defun rtd (radians)
  (* (/ radians pi) 180)
)  

Save current environment at start:

  ;; save current settings
  (setq orthomode (getvar 'orthomode)
        osmode (getvar 'osmode)
  )

So you can restore at end of routine:

  ;; restore original settings
  (setvar 'orthomode orthomode)
  (setvar 'osmode osmode)
  (princ) ; clean exit

Since you have some set common insert values I added function initgetdyn so you can make these selections:

paullimapa_1-1746560384060.png

  (setq InsertIC (initgetdyn "0.375 0.500 0.625 Other" "0.375" "Enter IC radius:"))
  (if (eq InsertIC "Other")
   (progn
    (setq InsertIC nil)
    (while (not InsertIC) 
      (setq InsertIC (getreal "\nEnter IC radius :"))
    )
   )
   (setq InsertIC (atof InsertIC)) ; convert string to real
  )
	(setq InsertAng (initgetdyn "35 55 80 Other" "35" "Enter insert angle:"))
  (if (eq InsertAng "Other")
   (progn
    (setq InsertAng nil)
    (while (not InsertAng) 
    	(setq InsertAng (getreal "\nEnter insert angle :"))
    )
   )
   (setq InsertAng (atof InsertAng)) ; convert string to real
  )
	(setq InsertRad (initgetdyn "0.008 0.016 0.031 0.047 0.062 Other" "0.008" "Enter corner radius:"))
  (if (eq InsertRad "Other")
   (progn
    (setq InsertRad nil)
    (while (not InsertRad) 
    	(setq InsertRad (getreal "\nEnter corner radius :"))
    )
   )
   (setq InsertRad (atof InsertRad)) ; convert string to real
  )

Precede commands & prompts with underscore to execute the english language command version regardless of what AutoCAD language version user is running & precede a command with a period incase it's undefined:

;	(command "pline" StartPt pt2 pt3 pt4 StartPt "")
	(command "_.Pline" StartPt pt2 pt3 pt4 StartPt "") ; precede command with underscore & period
;	(command "._FILLET" "P" "R" InsertRad "L")
	(command "._FILLET" "_P" "_R" InsertRad "_L") ; precede prompts with underscore

Since there's an error shown with your Rotate command sequence:

paullimapa_0-1746560266394.png

I changed it to this:
;	(setvar 'OSMODE 4)
;	(command "ROTATE" "L" "" "APP" StartPt AlignIns "R" "APP" StartPt AlignIns StartPt AlignIns)
	(command "_.ROTATE" "_L" "" StartPt "_R" "0" (rtd (angle StartPt AlignIns))) ; use 0 as current angle
;	(setvar 'OSMODE 39)

Let me know what you think.


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 4 of 8

AcmeMfgEng
Contributor
Contributor

Paul,

Thank you for providing explanations in regards to the changes you made. Your detailed comments provide a great baseline for me to study.

There are further enhancements I want to add, such as provision for triangle shaped inserts. I will try my hand at adding the code to accomplish this.

I am accepting your solution.

-Chris

0 Likes
Message 5 of 8

AcmeMfgEng
Contributor
Contributor

komondormex,

Thank you for providing the visual lisp example for my request. I'm not ready to go there yet, and sticking with "regular" lisp for now.

-Chris

0 Likes
Message 6 of 8

paullimapa
Mentor
Mentor

you are welcome...cheers!!!


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 7 of 8

Sea-Haven
Mentor
Mentor

@paullimapa has provided you a great answer, one of the other things you can do with a custom dcl is answer all the questions visually then press OK. You could add the diamond, triangle etc also.

This is just an example it uses a Library lisp for 3 column radio buttons. Just ask.

SeaHaven_0-1746583447788.png

 

0 Likes
Message 8 of 8

ВeekeeCZ
Consultant
Consultant

Since you are changing several system variables in the code, the *error* function should be part of the code. At this point, even canceling the function by ESC cause that changed sysvars are not restored.
Another thing is that it would certainly be useful to wrap the entire function in one undo step.
An unmentioned but implemented modification is to turn off OSMODE when inserting points within a (command) function. Osnaps are active by default (see OSNAPCOORD sysvar) and could be "snapped" at any time unpredictably. Very frequent issue.

0 Likes