;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; ;;;; Copyright (c) Jun. 1996 by Takehiko Nagakura. ;;;; ;;;; All rights reserved. ;;;; ;;;; ;;;; ;;;; Do not copy, use, modify or distribute this software ;;;; ;;;; without written permission by Nagakura. Nagakura will ;;;; ;;;; not be responsible for any consequence of its use. ;;;; ;;;; ;;;; ;;;; Takehiko Nagakura (e-mail: takehiko@mit.edu) ;;;; ;;;; Massachusetts Institute of Technology ;;;; ;;;; 77 Massachusetts Ave. 10-472M, Cambridge, MA 02139 ;;;; ;;;; ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Last updated Jan 1, 1997 by TN ;;This program demonstrates the use of AutoCAD commands, ;; car cdr append cons foreach mapcar apply ;; ;;It provides a function to draw a parabolic arch, which is ;;given by a simple formula, ;; ;; Y = - a XX + h ;; Functions and arguments ;; ;; (pline_from_points_1 point_list) ;; (pline_from_points_2 point_list) ;; (pline_from_points_3 point_list) ;; (get_coefficient wide high) ;; (draw_parabola wide high num_div) ;; (c:demo) ;; ; (defun c:r () (load "list_01.lsp")) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Sets up layers (command "cmdecho" 0) (command "layer" "make" "connect" "color" 8 "connect" "") ; color 8 is gray (command "layer" "make" "outline" "color" "white" "outline" "") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; The following 3 functions draw a pline from the give list of ; 2D points. ; The first version uses the AutoLISP function, 'repeat. (defun pline_from_points_1 (point_list / num_pts counter) (setq num_pts (length point_list)) ; total number of points (setq counter 0) ; resets the counter (command "pline") ; starts pline command (repeat num_pts (command (nth counter point_list)) ; extract the nth point (setq counter (+ counter 1)) ; increment the counter ) ; end of repeat (command "") ; finish the pline command ) ; (setq pl '((-5.0 0.0) (-2.5 15.0) (0.0 20.0) (2.5 15.0) (5.0 0.0))) ; (pline_from_points_1 pl) ; use this for test ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Another way of doing the same thing as 'pline_from_points_1. ; This time, I will use WHILE and a diminishing point list. (defun pline_from_points_2 (point_list) (command "pline") ; starts pline command (while point_list (command (car point_list)) ; always extract the first point (setq point_list (cdr point_list)) ; get rid of the first point from the list ) (command "") ) ; (pline_from_points_2 pl) ; use this for test ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Yet another way of doing the same thing as 'pline_from_points_1. ; It demonstrates the use of AutoLISP functions, 'apply and 'append. (defun pline_from_points_3 (point_list / arg_list) ; arg_list is a list looking like ("pline" '(x1 y1) '(x2 y2) ..... "") ; this is the arguments required for "command" command next. (setq arg_list (append (list "pline") point_list (list ""))) ; this does the same thing as (command pline" '(x1 y1) '(x2 y2) ..... "") (apply 'command arg_list) ) ; (pline_from_points_3 pl) ; use this for test ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;This computes the parabola's coefficient values from the given ;wide and high of the parabola ; formula is Y = - a XX + h ; when X=0, Y = high ; when X=w/2, Y = 0 (defun get_coefficient (wide high / h a) (setq h high) (setq a (/ (* 4.0 high) (* wide wide))) (list a h) ; returns a list whose first item is a's value and second is h's. ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;This draws the parabola of the given width and height. It has ;num_div points on the upper and lower outlines connected by ;lines. ;This function demostrates the use of AutoLISP functions, ; mapcar, foreach, nth (defun draw_parabola (wide high num_div / a h upper_points lower_points double_points x_inc x y pt ) (command "layer" "set" "outline" "") ;1] get the coefficient values for the equation (setq coef (get_coefficient wide high)) ; this returns a list of a and h's values (setq a (nth 0 coef)) ; takes out the first value for a (setq h (nth 1 coef)) ; takes out the second value for h ;2] resets some local variables (setq counter 0) (setq upper_points nil) (setq lower_points nil) ;3] repeat to create a series of points on the parabola ; points are stored in 'upper_points ; First, computes the increment for x (setq wide (* wide 1.0)) ; make sure this is a real number and ; not an integer before division below (setq x_inc (/ wide (* num_div))) ; Then, repeat to make the series of points on the parabola (repeat (+ 1 num_div) (setq x (- (/ wide 2.0) (* counter x_inc))) ; x decrements by x_inc in each loop (setq y (+ (* (- a) x x) h)) ; formula is Y = - a XX + h (setq pt (list x y)) (setq upper_points (cons pt upper_points)) ; this list grows in each loop (setq counter (+ 1 counter)) ) ;end repeat (pline_from_points_1 upper_points) ;draw lines between the upper points ;4] make the points on the lower side of the arch by ; scaling the y-coordinates of the upper points by 0.85 (setq lower_points (mapcar '(lambda (pt) ; this keeps x and scales the y of a point (list (nth 0 pt) (* 0.85 (nth 1 pt)))) upper_points) ) (pline_from_points_1 lower_points) ;draw lines between the lower points ;5] connect the upper points and lower points (setq double_points (mapcar '(lambda (pt_u pt_l) (list pt_u pt_l)) upper_points lower_points)) (command "layer" "set" "connect" "") (foreach 2pts double_points (command "line" (nth 0 2pts) (nth 1 2pts) "")) upper_points ; returns the points on the parabola ) ; end defun ;(draw_parabola 10 20 4) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun c:demo () (command "ucs" "world") (command "plan" "") (command "zoom" "window" (list -10 -5) (list 35 20)) ;(command "ucs" "origin" (list 0 0)) (draw_parabola 5 7 20) (command "ucs" "origin" (list 8 0)) (draw_parabola 5 7 4) (command "ucs" "origin" (list 8 0)) (draw_parabola 5 15 20) (command "ucs" "origin" (list 10 0)) (draw_parabola 10 6 20) (command "ucs" "world") (command "regen") )