Tuesday, 14 February 2012

nth function in Autolisp


nth  - This function returns the Nth item in a list. The first item in a list is item zero.  
          Syntax : (nth integer list)
          integer - Any valid integer.
          list - Any valid list.
      
                 (nth) returns "Error: Too Few Arguments"      [cons requires an item and a list]
                 (nth 2 1 2 3) returns "Error: Bad Argument Type" [nth requires an integer and a list]
                 (nth 2 (list "cde" "Jeff" "Sanders")) returns "Sanders"
                 (nth 0 (list 1 2 3)) returns 1
                 (nth 1 (list 1 2 3)) returns 2
                 (nth 2 (list 1 2 3)) returns 3
                 (nth 1 (list "a" (list "b" "c") "d"))  returns ("b" "c")
                 (nth 4 (list 1 2 3 5 6 7)) returns 6

Monday, 13 February 2012

AutoLISP "GETxxx" Functions



AutoLISP has many "GETxxx" functions that pause for user input of the indicated type and returns the value of the same type entered. This is the method used to allow users to input values as needed in programs.

Allowable input to the GETxxx user-input functions 
Function name
Type of user input
User presses ENTER, Returns
getint
An integer value on the command line
nil
getreal
A real or integer value on the command line
nil
getstring
A string on the command line
""
getpoint
A point value on the command line or selected from the screen
nil
getcorner
A point value (the opposite corner of a box) on the command line or 2 selected point from the screen
nil
getdist
A real or integer value (of distance) on the command line or determined by selecting 2 points on the screen
nil
getangle
An angle value (in the current angle format) on the command line or based on 2 selected points on the screen
nil
getorient
An angle value (in the current angle format) on the command line or based on 2 selected points on the screen
nil
getkword
A predefined keyword or its abbreviation on the command line
""

GETINT
Syntax - (getint [message])
Example -
    (setq Inum (getint "\nInput Integer ? "))    ;type at command prompt
    Input #1 -
        Command: Input Integer ? 25        ;integer input
        returns: 25
    Input #2 -
        Command: Input Integer ? 25.0     ;real number input
        Requires an integer value
        Input Integer ?                                  ;allows user to re-input integer
    Input #3 -
        Command: Input Integer ? S         ;non-numeric character entered
        Requires an integer value
        Input Integer ?                                 ;allows user to re-input integer

Note - Values passed to getint can range from -32,768 to +32,767. If the user enters any character other than a number character, then getint displays the message "Requires an integer value," and allows the user to try again.

GETREAL
Syntax - (getreal [message])
Example -
    (setq Rnum (getreal "\nInput Real Number ? "))    ;type at command prompt
    Input #1 -
        Command: Input Real Number ? 25.0     ;real number input
        returns: 25.0
    Input #2 -
        Command: Input Real Number ? 25        ;Integer input
        returns: 25.0
    Input #3 -
        Command: Input Real Number ? S         ;non-numeric character entered
        Requires a numeric value
        Input Real Number ?                                 ;allows user to re-input number

Note - Values passed to getreal are double-precision floating-point format. If the user enters any character other than a number character, then getrealdisplays the message "Requires a numeric value," and allows the user to try again. Real numbers between -1 and 1 must be contain a leading zero. Real numbers can also be expressed in scientific notation (example - 4.1e-6 equals 0.0000041).

GETSTRING
Syntax - (getstring [cr] [message])
    [cr] = If supplied and is not nil, this will allow the user to input spaces in their input string and must be terminated by pressing ENTER. Otherwise, the input string is terminated by pressing the SPACE or ENTER keys.

Example #1 -
    (setq Stir (getstring "\nInput String ? "))    ;type at command prompt
    Input #1 -
        Command: Input String ? test             ;String Input
        returns: "test"
    Input #2 -
        Command: Input String ? 25.0            ;Numeric Input
        returns: "25.0"
    Input #3 -
        Command: Input String ? 25               ;Numeric Input
        returns: "25"
    Input #4 -
        Command: Input String ? C:\temp\    ;folder path input
        returns: "C:\\temp\\"

Example #2 -
    (setq Stag (getstring T "\nInput String ? "))    ;type at command prompt
    Input #1 -
        Command: Input String ? this is a test             ;String Input
        returns: "this is a test"

Note - getstring will only return the first 132 characters in the input. If the input contains the backslash character "\", getstring converts it to two backslash characters "\\". This allows you to input folder paths.

GETPOINT
Syntax - (getpoint [pt] [message])
    [pt] = If supplied and is not nil, this will cause AutoCAD to show a rubberband from [pt] to current cursor location

Example #1 -
    (setq P1 (getpoint "\nInput Point ? "))    ;type at command prompt
    Input #1 -
        Command: Input Point ? pick point         ;Point Input
        returns: coordinates of picked point in list format
    Input #2 -
        Command: Input Point ? 25.0,25.0          ;Numeric Input
        returns: (25.0 25.0 0.0)
    Input #3 -
        Command: Input Point ? 25,25                 ;Numeric Input
        returns: (25.0 25.0 0.0)
    Input #4 -
        Command: Input Point ? S                        ;string input
        Invalid Point
        Input Point ?                                                ;allows user to re-input number

Example #2 -
    (setq P0 (list 0.0 0.0))
    (setq P1 (getpoint P0 "\nInput Point ? "))    ;type at command prompt
    Input #1 -
        Command: Input Point ? pick point             ;Point Input showing rubberband from P0
        returns: coordinates of picked point in list format

How to draw circle in Autolisp


 Command: CIRCLE
    Specify center point for circle or [3P/2P/Ttr (tan tan radius)]: 2P
    Specify first end point of circle's diameter: pick point
    Specify second end point of circle's diameter: pick point
LISP Program Example -
    (command "CIRCLE" "2P" PT1 PT2)    ;using previously set start and end points


Example:
(defun c:circle()
   (setq PT1(strcat "0" "," "0"))               ;set start point
    (setq PT2(strcat "2000" "," "0"))         ;set end point
    (command "LINE" PT1 PT2 "")             ;issue LINE command to AutoCAD, draw from PT1 to PT2
    (command "CIRCLE" "2P" PT1 PT2)      ;Specify center point for circle or [3P/2P/Ttr (tan tan radius)]: Pick center point 
                                                       ;issue the CIRCLE command to AutoCAD,Draw from PT1 to PT2 .
  )


Friday, 10 February 2012

Draw a beam using Autolisp


(defun c:beam()
  (setq x(getreal "Enter length of the beam: "))
  (setq y(getreal "Enter Height of the Beam: "))
  (setq sth(getreal "Enter Height of the Steel: "))
  (setq e(getstring 1 "Normal Steel: "))
  (setq ex(getstring 1 "Extra Steel: "))
  (setq c(strcat "0" "," (rtos (/ x 2)))) ;;0,2000
  (setq pdstl1(* 0.65 x))
  (setq pdstl(/ pdstl1 2)) ;;1300
  (setq m(- y sth)) ;;575
  (setq pt1(strcat "0" "," "0")) ;;0,0
  (setq pt2(strcat (rtos x) "," "0")) ;;4000,0
  (setq pt3(strcat "0" "," (rtos sth))) ;;0,25
  (setq pt4(strcat (rtos x) "," (rtos sth))) ;;4000,25
  (setq pt5(strcat "0" "," (rtos m))) ;;0,575
  (setq pt6(strcat (rtos x) "," (rtos m))) ;;4000,575
  (setq pt7(strcat "0" "," (rtos y))) ;;0,600
  (setq pt8(strcat (rtos x) "," (rtos y))) ;;4000,600
  (setq left(- (/ x 2) pdstl)) ;;700
  (setq pt9(strcat (rtos left) "," (rtos sth))) ;;700,25
  (setq pt10(strcat (rtos (- left (* sth 3))) ","  (rtos (* sth 3)))) ;;650,50
  (setq right(+ (/ x 2) pdstl)) ;;3300
  (setq righth(* sth 3)) ;;50
  (setq pt11(strcat (rtos right) ","  (rtos sth))) ;;3300,25
  (setq pt12(strcat (rtos (+ right righth)) "," (rtos righth))) ;;3350,50
  (setq top(* 0.3 x)) ;;1200
  (setq pt13(strcat (rtos top) "," (rtos m))) ;;1200,575
  (setq pt14(strcat (rtos (+ top righth)) "," (rtos (- y righth)))) ;;1250,550
  (setq pt15(strcat (rtos (- x top)) "," (rtos m))) ;;2800,575
  (setq pt16(strcat (rtos (- (- x top) righth)) "," (rtos (- y righth)))) ;;2750,550
  (setq c1(strcat (rtos (/ top 2)) "," (rtos m))) ;;600,575
  (setq c2(strcat (rtos (/ top 2)) "," (rtos (+ m 300)))) ;;600,875
  (setq c3(strcat (rtos (+ (/ top 2) 300)) "," (rtos (+ m 300)))) ;;900,875
  (setq c4(strcat (rtos (/ x 2)) "," (rtos m))) ;;2000,575
  (setq c5(strcat (rtos (/ x 2)) "," (rtos (+ m 300)))) ;;2000,875
  (setq c6(strcat (rtos (+ (/ x 2) 300)) "," (rtos (+ m 300)))) ;;2300,875
  (setq c7(strcat (rtos (+ (- x top) (/ top 2))) "," (rtos m))) ;;3400,575
  (setq s(+ (- x top) (/ top 2))) ;;3400
  (setq c8(strcat (rtos s) "," (rtos (+ m 300)))) ;;3400,875
  (setq c9(strcat (rtos (+ s 300)) "," (rtos (+ m 300)))) ;;3700,875
  (setq c10 (strcat (rtos (/ top 2) ) "," (rtos sth))) ;;600,25
  (setq c11(strcat (rtos (/ top 2)) "," (rtos (- sth 300)))) ;;600,-275
  (setq c12(strcat (rtos (+ (/ top 2) 300)) ","  (rtos (- sth 300)))) ;;900,-275
  (setq c13(strcat (rtos (/ x 2)) "," (rtos sth))) ;;2000,25
  (setq c14(strcat (rtos (/ x 2)) "," (rtos (- sth 300)))) ;;2000,-275
  (setq c15(strcat (rtos (+ (/ x 2) 300)) "," (rtos (- sth 300)))) ;;2300,-275
  (setq c16(strcat (rtos s) "," (rtos sth))) ;;3400,25
  (setq c17(strcat (rtos s) ","  (rtos (- sth 300)))) ;;3400,-275
  (setq c18(strcat (rtos (- s 300)) "," (rtos (- sth 300)))) ;;3100,-275
  (setq c2a(strcat (rtos (/ top 2)) "," (rtos (+ m 350))))
  (setq c5a(strcat (rtos (/ x 2)) "," (rtos (+ m 350))))
  (setq c8a(strcat (rtos s) "," (rtos (+ m 350))))
  (setq c11a(strcat (rtos (/ top 2)) "," (rtos (- sth 450))))
  (setq c14a(strcat (rtos (/ x 2)) "," (rtos (- sth 450))))
  (setq c18a(strcat (rtos (- s 300)) "," (rtos (- sth 450))))
  (command "line" pt1 pt2 "")
  (command "line" pt3 pt4 "")
  (command "line" pt5 pt6 "")
  (command "line" pt7 pt8 "")
  (command "line" pt9 pt10 "")
  (command "line" pt11 pt12 "")
  (command "line" pt13 pt14 "")
  (command "line" pt15 pt16 "")
  (command "line" c1 c2 "")
  (command "line" c2 c3 "")
  (command "line" c4 c5 "")
  (command "line" c5 c6 "")
  (command "line" c7 c8 "")
  (command "line" c8 c9 "")
  (command "line" c10 c11 "")
  (command "line" c11 c12 "")
  (command "line" c13 c14 "")
  (command "line" c14 c15 "")
  (command "line" c16 c17 "")
  (command "line" c17 c18 "")
  (command "text" c2a "100" "" ex)
  (command "text" c5a "100" "0" e)
  (command "text" c8a "100" "0" ex)
  (command "text" c11a "100" "0" e)
  (command "text" c14a "100" "0" ex)
  (command "text" c18a "100" "0" e)
  )

Thursday, 9 February 2012

Calculating Points (Polar) in Autolisp


The Polar function is defined in the AutoCAD Customization manual as follows :
POLAR : Returns the UCS 3D point at a specified angle and distance from a point.
(polar pt ang dist)
This, I believe, is one of the most useful functions in the AutoCAD stable.
In a nutshell, you feed it a point, tell it the angle and distance from that point that you want to be, and it will return the second point.
Can you imagine having to do that using car, cadr, etc.
First you would have to break the list down into each separate component, do all the calculations on each individual item, and then re-construct the list.
What a pain!!
Following is an example of how to use POLAR to construct a simple square or rectangle from values input by the user :
(defun DTR (a)    ;degrees to radians function

(* PI (/ a 180.0))
);defun
;=========================================
(defun C:BOX1 (/ IP P1 P2 P3 LENGTH HEIGHT ;define function and declare

  OLDSNAP OLDBLIP OLDLIGHT) ;variables as local

(setq OLDSNAP (getvar "OSMODE")   ;store system variables

      OLDBLIP (getvar "BLIPMODE")
     OLDLIGHT (getvar "HIGHLIGHT")
);setq

;=========================================
(setvar "CMDECHO" 0)    ;change system variables
(setvar "BLIPMODE" 0)

(setq IP (getpoint "\nInsertion Point: ")) ;get insertion point
(setvar "OSMODE" 0)    ;switch off snap

(setq LENGTH (getreal "\nEnter Length: ") ;get length of box
      HEIGHT (getreal "\nEnter Height: ") ;get height of box

);setq
;=========================================
(setq P1 (polar IP (DTR 0.0) LENGTH)  ;calculate first corner

      P2 (polar P1 (DTR 90.0) HEIGHT)  ;calculate second corner

      P3 (polar P2 (DTR 180.0) LENGTH)  ;calculate third corner

);setq
;=========================================
(command "PLINE" IP "W" "" ""
  P1 P2 P3 "C"

);command     ;draw the box
;=========================================
(prompt "\nRotation Angle: ")   ;prompt the user for rotation
(command "ROTATE" "LAST" "" IP pause)  ;rotate the box

;=========================================
(setvar "OSMODE" OLDSNAP)   ;reset system variables
(setvar "BLIPMODE" OLDBLIP)

(setvar "HIGHLIGHT" OLDLIGHT)
(princ)      ;exit quietly
);defun
To save you typing here's the source code : Box1 Lisp (1 Kb)
As you can see, we first need to write a function to convert radians to degrees. This is because when we deal with angles in AutoLISP they must be in Radians.
Hint : This could be a Global function loaded from your Acad Lisp file.
Now to our main routine.
The first thing that we do is define the function and declare all the variables as local. (Only used within this program.)
Then we save certain system variables, before changing them, so that we can reset them later.
Next we ask the user for Insertion Point, Length and Height of the box.
We then use the POLAR function to calculate the remaining 3 corners of the box. (PT1, PT2 and PT3).
Then, just to be kind, we allow the user to rotate the box.
(That's why we drew the box using a Pline.)
Lastly, we reset all the system variables that we changed back to their original state.