Jump to content

First Lisp Written Solo!


tomhamlet

Recommended Posts

I have been getting back into lisp, after I had a class that scratched the surface of lisp, I never looked back on it until now. This is my first lisp command written without copying it from a book!

(defun c:ibeamp()
(setq pw (getdist "\nEnter Beam Width: "))
(setq ih (getdist "\nEnter Inner Height: "))
(setq pt (getdist "\nEnter Plate Thickness: "))
(setq po (getdist "\nEnter Overhang Distance: "))
(setq ip (getpoint "\nInsertion point: "))
(setq p2 (polar ip (dtr 180.0) (/ pw 2)))
(setq p3 (polar p2 (dtr 270.0) pt))
(setq p4 (polar p3 (dtr 0.0) po))
(setq p5 (polar p4 (dtr 270.0) ih))
(setq p6 (polar p5 (dtr 180.0) po))
(setq p7 (polar p6 (dtr 270.0) pt))
(setq p8 (polar p7 (dtr 0.0) pw))
(setq p9 (polar p8 (dtr 90.0) pt))
(setq p10 (polar p9 (dtr 180.0) po))
(setq p11 (polar p10 (dtr 90.0) ih))
(setq p12 (polar p11 (dtr 0.0) po))
(setq p13 (polar p12 (dtr 90.0) pt))
(command "line" ip p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 "c"
)
(princ)
)
(defun dtr (x)
(* pi (/ x 180.0))
)
(princ)

 

this draws a very general I-beam. Any feedback is appreciated, constructive more so :)

Link to comment
Share on other sites

  • Replies 21
  • Created
  • Last Reply

Top Posters In This Topic

  • tomhamlet

    9

  • Lee Mac

    6

  • BlackBox

    5

  • MSasu

    1

Top Posters In This Topic

Some observations:

 

  • To make sure that avoid any interference with current auto Osnap mode, you need to disable it when call the command - check the OSMODE system variable. Also, a good programming practice is to retain the user environment and restore it at the end.

(setq oldOsmode (getvar "OSMODE"))
(setvar "OSMODE" 0)
;call commands
(setvar "OSMODE" oldOsmode)

  • In order to avoid interference with other routines you should use local variables:

(defun c:ibeamp( / [color=red]pv ih pt po ...[/color])

  • To ensure that your code works well with localized versions of AutoCAD (that it, in languages other than English) use an uderscore when call commands and options:

(command "[color=red]_.[/color]LINE" ... "[color=red]_[/color]C")

 

  • Not less important is to get used to add comments to your code; it will be very useful when decide to review it later.

Link to comment
Share on other sites

great!

(defun c:ibeamp(pw ih pt po ip)
(setq pw (getdist "\nEnter Beam Width: "))
(setq ih (getdist "\nEnter Inner Height: "))
(setq pt (getdist "\nEnter Plate Thickness: "))
(setq po (getdist "\nEnter Overhang Distance: "))
(setq ip (getpoint "\nInsertion point: "))
(setq p2 (polar ip (dtr 180.0) (/ pw 2)))
(setq p3 (polar p2 (dtr 270.0) pt))
(setq p4 (polar p3 (dtr 0.0) po))
(setq p5 (polar p4 (dtr 270.0) ih))
(setq p6 (polar p5 (dtr 180.0) po))
(setq p7 (polar p6 (dtr 270.0) pt))
(setq p8 (polar p7 (dtr 0.0) pw))
(setq p9 (polar p8 (dtr 90.0) pt))
(setq p10 (polar p9 (dtr 180.0) po))
(setq p11 (polar p10 (dtr 90.0) ih))
(setq p12 (polar p11 (dtr 0.0) po))
(setq p13 (polar p12 (dtr 90.0) pt))
(command "line" ip p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 "c"
)
(princ)
)
(defun dtr (x)
(* pi (/ x 180.0))
)
(princ)

is this what you mean?

Link to comment
Share on other sites

First, congrats on writing your first LISP. :beer:

 

... One thing to beware, if you prompt the user for input and they do not enter a valid response, you need to account for that rather than allowing the code to progress as this may cause an error.

 

As an example, consider pw = nil. :thumbsup:

 

One common way of mitigating this is to use an IF statement, and in your case an AND statement may also be helpful.

Link to comment
Share on other sites

First, congrats on writing your first LISP. :beer:

 

... One thing to beware, if you prompt the user for input and they do not enter a valid response, you need to account for that rather than allowing the code to progress as this may cause an error.

 

As an example, consider pw = nil. :thumbsup:

 

One common way of mitigating this is to use an IF statement, and in your case an AND statement may also be helpful.

I do want to get into the IF and And commands soon. but im making sure I know what these routine do first. Thank you!

Link to comment
Share on other sites

I do want to get into the IF and And commands soon. but im making sure I know what these routine do first. Thank you!

 

In an attempt to give you an example that does not remove the excitement from having written your first routine, please take from this pseudo code example what you like (building on multiple comments):

 

(defun c:FOO ( / ;|localVariables|; pw ih pt po ip)

 ;; If, the user enters all of the necessary criteria
 (if (and (setq pw (getdist "\nEnter Beam Width: "))
          (setq ih (getdist "\nEnter Inner Height: "))
          (setq pt (getdist "\nEnter Plate Thickness: "))
          (setq po (getdist "\nEnter Overhang Distance: "))
          (setq ip (getpoint "\nInsertion point: "))
     )

   ;; Then, continue the routine
   (prompt
     "\nThanks for entering all of the necessary criteria. "
   )

   ;; Else, tell the user what they failed to specify
   (cond (po (prompt "\n** Insertion point required ** "))
         (pt (prompt "\n** Overhang distance required ** "))
         (ih (prompt "\n** Plate thickness required ** "))
         (pw (prompt "\n** Inner height required ** "))
         ((prompt "\n** Beam width required ** "))
   )
 )
 (princ)
)

Edited by BlackBox
Link to comment
Share on other sites

In an attempt to give you an example that does not remove the excitement from having written your first routine, please take from this pseudo code example what you like (building on multiple comments):

 

thanks. I will definately give it a shot!

Link to comment
Share on other sites

(defun c:FOO ([color=red];|globalVariables|;[/color] / ;|localVariables|; pw ih pt po ip)

 

The above highlighted section should instead read 'function parameters', as global variables are not declared in the defun expression. ;)

Link to comment
Share on other sites

The above highlighted section should instead read 'function parameters', as global variables are not declared in the defun expression. ;)

 

Good catch, Lee; code corrected (oops).

Link to comment
Share on other sites

The above highlighted section should instead read 'function parameters', as global variables are not declared in the defun expression. ;)

 

Good catch, Lee; code corrected (oops).

 

... Actually no, that shouldn't be there either (in this instance).

 

Your correction and reference to the Defun function are correct, it's just that as this is a c: prefixed symbol, the function parameters are not used.

Link to comment
Share on other sites

Another suggestion rather than use Dtr 180 why not pid, dtr 270 pil, your already using the defun Dtr so why not add a couple more, you can take the lisp value of PI and divide it etc

 

(setq Pil (* pi() 1.5))
(setq pid pi() )
(setq piu (* 0.5 pi() ))
remember pir is 0.0 in radians to right you may want this for consistancy

Link to comment
Share on other sites

Another suggestion rather than use Dtr 180 why not pid, dtr 270 pil, your already using the defun Dtr so why not add a couple more, you can take the lisp value of PI and divide it etc

 

I have gotten so far as to know what pid, pil, piu, and pir is yet! thanks for the help guys. An extra thanks to Lee Mac, as his sight and tutorials were a big part, along with afralisp, of helping me understand the functions that went into this first lisp.

Link to comment
Share on other sites

An extra thanks to Lee Mac, as his sight and tutorials were a big part, along with afralisp, of helping me understand the functions that went into this first lisp.

 

You're very welcome - I'm delighted that my tutorials were helpful in your learning.

 

Here are my suggestions for your program:

([color=BLUE]defun[/color] c:ibeamp ( [color=BLUE]/[/color] 3pi/2 cm ih ip os p10 p11 p12 p13 p2 p3 p4 p5 p6 p7 p8 p9 pi/2 po pt pw )
   [color=GREEN];; Define function and declare local variables[/color]
   [color=GREEN];; Localising Variables: http://lee-mac.com/localising.html[/color]

   [color=GREEN];; If the following expression returns a non-nil value[/color]
   ([color=BLUE]if[/color]
       [color=GREEN];; All of the following expressions must return a non-nil[/color]
       [color=GREEN];; value for AND to return T[/color]
       ([color=BLUE]and[/color]
           [color=GREEN];; Prompt user for I-Beam parameters[/color]
           ([color=BLUE]setq[/color] ip ([color=BLUE]getpoint[/color] [color=MAROON]"\nInsertion Point: "[/color]))
           ([color=BLUE]setq[/color] pw ([color=BLUE]getdist[/color] ip [color=MAROON]"\nSpecify Beam Width: "[/color]))
           ([color=BLUE]setq[/color] ih ([color=BLUE]getdist[/color] ip [color=MAROON]"\nSpecify Inner Height: "[/color]))
           ([color=BLUE]setq[/color] pt ([color=BLUE]getdist[/color] ip [color=MAROON]"\nSpecify Plate Thickness: "[/color]))
           ([color=BLUE]setq[/color] po ([color=BLUE]getdist[/color] ip [color=MAROON]"\nSpecify Overhang Distance: "[/color]))
       ) [color=GREEN];; end AND[/color]

       ([color=BLUE]progn[/color]
           [color=GREEN];; Wrap the following expressions within a PROGN expression.[/color]
           [color=GREEN];; PROGN will simply evaluate every enclosed expression in turn[/color]
           [color=GREEN];; and will return the result of the last evaluated expression.[/color]
           [color=GREEN];;[/color]
           [color=GREEN];; By enclosing the expressions within the PROGN function, we[/color]
           [color=GREEN];; can pass the *single* PROGN expression to the IF function[/color]
           [color=GREEN];; to constitute the 'then' argument of the IF function.[/color]

           [color=GREEN];; Store some convenient multiples of pi:[/color]
           ([color=BLUE]setq[/color]  pi/2 ([color=BLUE]*[/color] [color=BLUE]pi[/color] 0.5)
                 3pi/2 ([color=BLUE]*[/color] [color=BLUE]pi[/color] 1.5)
           
           [color=GREEN];; Calculate the necessary points:[/color]
                    p2 ([color=BLUE]polar[/color] ip [color=BLUE]pi[/color] ([color=BLUE]/[/color] pw 2.0))
                    p3 ([color=BLUE]polar[/color] p2 3pi/2 pt)
                    p4 ([color=BLUE]polar[/color] p3 0.0 po)
                    p5 ([color=BLUE]polar[/color] p4 3pi/2 ih)
                    p6 ([color=BLUE]polar[/color] p5 [color=BLUE]pi[/color] po)
                    p7 ([color=BLUE]polar[/color] p6 3pi/2 pt)
                    p8 ([color=BLUE]polar[/color] p7 0.0 pw)
                    p9 ([color=BLUE]polar[/color] p8 pi/2 pt)
                   p10 ([color=BLUE]polar[/color] p9 [color=BLUE]pi[/color] po)
                   p11 ([color=BLUE]polar[/color] p10 pi/2 ih)
                   p12 ([color=BLUE]polar[/color] p11 0.0 po)
                   p13 ([color=BLUE]polar[/color] p12 pi/2 pt)
           ) [color=GREEN];; end SETQ[/color]

           [color=GREEN];; Store Object Snap setting[/color]
           ([color=BLUE]setq[/color] os ([color=BLUE]getvar[/color] 'osmode)
           [color=GREEN];; Store CMDECHO setting[/color]
                 cm ([color=BLUE]getvar[/color] 'cmdecho)
           )            
           [color=GREEN];; Disable Object Snap[/color]
           ([color=BLUE]setvar[/color] 'osmode ([color=BLUE]logior[/color] os 16384))
           [color=GREEN];; Turn off CMDECHO[/color]
           ([color=BLUE]setvar[/color] 'cmdecho 0)

           [color=GREEN];; Construct a Polyline[/color]
           [color=GREEN];; "_"    = Accounts for other languages of AutoCAD[/color]
           [color=GREEN];; "."    = Use in-built command, not a redefinition[/color]
           ([color=BLUE]command[/color] [color=MAROON]"_.pline"[/color] ip p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 [color=MAROON]"_C"[/color])

           [color=GREEN];; Reset CMDECHO[/color]
           ([color=BLUE]setvar[/color] 'cmdecho cm)
           [color=GREEN];; Reset Object Snap setting[/color]
           ([color=BLUE]setvar[/color] 'osmode os)
           
       ) [color=GREEN];; end PROGN[/color]

       [color=GREEN];; If we had an 'else' expression for the IF function, it would go here.[/color]
       
   ) [color=GREEN];; end IF[/color]
   
   [color=GREEN];; Suppress the return of the last evaluated expression[/color]
   ([color=BLUE]princ[/color])
) [color=GREEN];; end DEFUN[/color]

I have tried not to deviate too far from your original code to keep the program clear and comprehensible for you to learn from, but please ask if you have any questions about any of my modifications or comments.

Link to comment
Share on other sites

You're very welcome - I'm delighted that my tutorials were helpful in your learning.

 

Here are my suggestions for your program:

 

please, deviate as much as you can, the more you deviate, the more things i will see that I haven't before, so i will be forced to ask more questions and learn! Here are 2 that I have from your code:

1. could you explain this line;(setvar 'osmode (logior os 16384)). I am not sure I am familiar with logior or the code 16384.

2. what control is cmdecho?

Link to comment
Share on other sites

please, deviate as much as you can, the more you deviate, the more things i will see that I haven't before, so i will be forced to ask more questions and learn! Here are 2 that I have from your code:

1. could you explain this line;(setvar 'osmode (logior os 16384)). I am not sure I am familiar with logior or the code 16384.

2. what control is cmdecho?

 

I will not answer for Lee, but in anticipation of his response I would simply offer the suggestion that when curious about a function, feel free to look it up in the Developer Documentation. :thumbsup:

Link to comment
Share on other sites

once again dooped by my own tendancy to go straight to the web, rather than use the autocad help right under my nose. thanks RenderMan, i will definately look into it.

Link to comment
Share on other sites

please, deviate as much as you can, the more you deviate, the more things i will see that I haven't before, so i will be forced to ask more questions and learn!

 

True - but equally you don't want to be overwhelmed with information when you are just starting out; by keeping close to your original code, you can follow and understand my alterations without feeling that I have simply written the program for you ;)

 

1. could you explain this line;(setvar 'osmode (logior os 16384)). I am not sure I am familiar with logior or the code 16384.

 

The 16384 bit-code disables Object Snap whilst retaining the various Object Snap settings (such as endpoint / midpoint / intersection etc.) - setting the 16384 bit-code in the OSMODE System Variable is the equivalent of the user toggling the Object Snap off using the F3 key.

 

The full list of bit-codes for the OSMODE System Variable is as follows (this list can be found by listing the OSMODE System Variable in the sysvdlg command):

 

0       NONe
1       ENDpoint
2       MIDpoint
4       CENter
8       NODe
16      QUAdrant
32      INTersection
64      INSertion
128     PERpendicular
256     TANgent
512     NEArest
1024    QUIck
2048    APParent Intersection
4096    EXTension
8192    PARallel
16384   Disable Object Snap

As for logior, now we are entering the realm of bitwise logic - logior returns the bitwise inclusive OR (as opposed to the exclusive XOR) of two or more integers. If you need more information about bitwise logic, there are a plethora of examples on the web, as bitwise values are used extensively in many programming languages.

 

2. what control is cmdecho?

 

CMDECHO

 

Or look it up using sysvdlg

Link to comment
Share on other sites

Thanks again Lee. If you get a chance, I could really use your help on a new thread i posted http://www.cadtutor.net/forum/showthread.php?74733-New-Challenge!-Lisp-for-Tags.

 

You're welcome; but please understand that my time here is voluntary and without remuneration, I'm sure other members can offer some you some assistance. ;)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...