(defun c:myfirstprogram
( / a b c d e f ang 90d pt1 pt2 pt3 pt4 pt5 pt6 pt7 pt8
) ;; Define function & declare local variables
;; To understand why the declaration of local
;; variables is an important practice, see http://bit.ly/15Qw104
;; Define some local variables for later use in the program
;; These values are arbitrary and are just based on the image provided.
b 10
c 10
d 30
e 10
f 10
) ;; end SETQ
;; If the following test expression returns a non-nil value
;; Note that the term 'non-nil' is used as opposed to
;; strictly 'T' since any value not equal to nil will
;; validate the IF test expression.
;; AND will continue to evaluate the enclosed
;; expressions until either no expressions remain
;; or an expression returns nil.
;;
;; In short, all of the enclosed expressions must
;; return a non-nil value for AND to return T
;; Bound the value returned by the following
;; expression to the symbol 'pt1'
;; Prompt the user to specify a point or pick a point on screen.
;; If the user fails to provide a point (e.g. by pressing
;; 'Enter' at the prompt), GETPOINT will return nil, causing
;; the SETQ expression to return nil, causing AND to return nil,
;; which invalidates the IF test expression, causing the 'else'
;; argument to be evaluated.
) ;; end SETQ
;; Bound the value returned by the following
;; expression to the symbol 'pt2'
(getpoint "\nSpecify the 2nd point: " pt1
) ;; As above, however the second argument for GETPOINT
;; is provided to display a 'rubber band' to the first point
;; specified.
;;
;; We know that the local variable 'pt1' must contain a valid
;; point, as otherwise the first GETPOINT expression would
;; have returned nil, causing the AND function to cease
;; evaluation of the expressions passed to it
;; (this is the beauty of Special Forms in LISP).
) ;; end SETQ
) ;; end AND
;; End of test expression.
;; The following is now the 'then' expression for the IF function
;; PROGN simply evaluates all supplied expressions and
;; returns the value returned by the last evaluated expression.
;; This may seem redundant, but it means that we can evaluate
;; multiple expressions within the PROGN expression and pass
;; the PROGN expression as a single argument to the IF function
;; Calculate the angle (in radians) between the x-axis
;; and a line/vector spanning pt1 to pt2.
90d (/ pi 2.0)
;; pi/2 radians is equal to 90 degrees
;; I have defined this as a local variable as we will use
;; this value repeatedly and I wanted it to be clearer as to how
;; it is used in the code.
;; Calculate the coordinates of 'pt3':
;; This point lies a distance 'a' from 'pt1' at an
;; angle parallel to the angle between 'pt1' & 'pt2'
pt4
(polar pt3
(- ang 90d
) c
) ;; Calculate the coordinates of 'pt4':
;; This point lies a distance 'c' from 'pt3' at an
;; angle perpendicular to the angle between 'pt1' & 'pt2'
;; Since POLAR measures angle in a counter-clockwise direction
;; with zero radians at the x-axis, subtracting an angle will
;; turn us in a clockwise direction about 'pt3'
pt5
(polar pt3
(+ ang 90d
) b
) ;; Calculate the coordinates of 'pt5':
;; As above, however, since we are now adding the angle,
;; we are turning in a counter-clockwise direction about
;; the base point argument 'pt3'
;; Calculate the coordinates of 'pt6':
;; Point 'pt6' is a distance 'd' from 'pt3' along the
;; same angle as 'pt1' to 'pt2'.
pt7
(polar pt6
(- ang 90d
) f
) ;; Calculate the coordinates of 'pt7':
;; ( As 'pt4' )
pt8
(polar pt6
(+ ang 90d
) e
) ;; Calculate the coordinates of 'pt8':
;; ( As 'pt5' )
) ;; end SETQ
;; Now to construct some lines/polylines
;; Here we could store the value of the CMDECHO system variable
;; and set this variable to zero so that the following is
;; not printed to the command-line, but as this is a beginner's
;; program it might be worth seeing what is being issued to the
;; command-line.
;; Issue the following statements at the AutoCAD command-line:
"_.line"
;; Invoke the AutoCAD LINE command
;; To understand why "_." is used, see http://bit.ly/1d2jfB3
"_non"
;; Ignore any active Object Snap modes when issuing the next point
;; We could alternatively store the value of the OSMODE
;; system variable and temporarily set this system variable to
;; zero, however, we would then also need to include an error handler
;; to ensure the system variable is reset to its original value
pt1
;; Line start point (in UCS)
"_non"
;; As above
pt2
;; Line end point (in UCS)
""
;; End the LINE command
;; ("" is equivalent to the user pressing ENTER)
"_.pline"
;; Invoke the AutoCAD PLINE command
"_non" pt4 "_non" pt7 "_non" pt8 "_non" pt5
;; Issue the calculated points in the appropriate order
"_C"
;; Close the polyline
) ;; end COMMAND
) ;; end PROGN
;; End of 'then' expression
;; The following is where we would place the 'else' expression for the IF function
;; however an else argument is not necessary in this case (unless perhaps the
;; user should be notified that they have not specified two points)
) ;; end IF
;; Suppress the return of the last evaluated expression
) ;; end DEFUN