;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; ;;;; Copyright (c) Feb. 1997 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 Feb 2, 1997 by TN ;;;; ; This file defines functions to draw 2 dimentional tree elevation ; using a recursive algorithm. ; Use of functions ; ; (branch x y length min_length angle_start angle_inc ratio) ; (c:demo) ; First, I set up the 2 layers I need. These 2 lines will be ; processed only once when this file is loaded. (command "layer" "new" "flower" "color" "yellow" "flower" "") (command "layer" "new" "branch" "color" "white" "branch" "") ; A utility to convert an angle from degree to radia. (defun deg2rad (deg) (/ (* deg pi) 180)) ; Main recursive function. Notice that this function calls itself ; twice inside its own definition. This uses a tail recursion but ; not aimed at maximum optimization... (defun branch (x y length min_length angle_start angle_inc ratio / ang1 ang2 x1 y1 x2 y2 dx1 dy1 dx2 dy2 next_length) ;first, check the specified length against the minimum length of a branch (if (<= length min_length) ;1) if the length is too small, then draw a yellow flower ; and terminate (progn (command "layer" "set" "flower" "") (command "circle" (list x y) (* 0.3 length)) ) ;2) if the length is large enough, draw a pair of v-shaped branch ; and recurse to the next. (progn ;2-1) calculate endpoints of new branches (setq ang1 (- angle_start angle_inc)) (setq ang2 (+ angle_start angle_inc)) (setq dx1 (* length (cos (deg2rad ang1)))) (setq dy1 (* length (sin (deg2rad ang1)))) (setq dx2 (* length (cos (deg2rad ang2)))) (setq dy2 (* length (sin (deg2rad ang2)))) (setq x1 (+ x dx1)) (setq y1 (+ y dy1)) (setq x2 (+ x dx2)) (setq y2 (+ y dy2)) ;2-2) draws a pair of white v-shaped branches (command "layer" "set" "branch" "") (command "line" (list x1 y1) (list x y) (list x2 y2) "") ;2-3) ; next branches are shorter, by the factor of 'ratio (setq next_length (* length ratio)) ;2-4) ; recurse to the next branch (branch x1 y1 next_length min_length ang1 angle_inc ratio) (branch x2 y2 next_length min_length ang2 angle_inc ratio) ); progn ) ; if ) ; end of defun ; Now I test the function defined above with various ; parameter values. ; You can call this function from Autocad command line prompt, too. (defun c:demo () (untrace branch) ; just in case (command "plan" "") (command "zoom" (list -26 -10) (list 170 90)) (branch 75 0 20 12 95 10 0.9) (branch 105 0 15 4 85 15 0.6) (branch 145 0 15 4 85 30 0.6) (redraw) ) (command "cmdecho" 0) ; when this file is loaded, I will print its usage for the users. (prompt "(branch x y length start_angle angle minimum ratio) (c:demo)") (princ)