; Draw a fractal tree recursively ; This is an example of doing recursion with local per-call state that has to ; be preserved across recursive calls, as opposed to queens.p8 where the ; recursive function only modifies global state. ; ; Note: this program can be compiled for multiple target systems. %import floats %import graphics %zeropage basicsafe main { ; Adjust these parameters to change the appearance of the tree: ; 1. the angle of each branch away from its parent (left and right) const float delta_theta = floats.π / 6 ; 2. the size of each branch relative to its parent const float shrink_factor = 2.0 / 3.0 ; 3. the size of the smallest branch (in pixels) const float minimum_branch = 1.0 ; These stacks hold copies of the parameters during recursive calls uword[11] x ubyte[11] y float[11] theta float[11] length ; This points to the current level of stack in use ubyte stack_pointer ; draw a branch starting at (x1, y1) at angle th1 with length len1 ; recurses if length is large enough sub draw_branch(uword x1, ubyte y1, float th1, float len1) { uword x2 = (x1 as float + len1 * floats.cos(th1)) as uword ubyte y2 = (y1 as float - len1 * floats.sin(th1)) as ubyte graphics.line(x1, y1, x2, y2) if len1 >= minimum_branch { ; push parameters onto stacks x[stack_pointer] = x1 y[stack_pointer] = y1 theta[stack_pointer] = th1 length[stack_pointer] = len1 stack_pointer += 1 draw_branch(x2, y2, th1 - delta_theta, len1 * shrink_factor) ; recover parameters after recursive call x1 = x[stack_pointer - 1] y1 = y[stack_pointer - 1] th1 = theta[stack_pointer - 1] len1 = length[stack_pointer - 1] x2 = (x1 as float + len1 * floats.cos(th1)) as uword y2 = (y1 as float - len1 * floats.sin(th1)) as ubyte draw_branch(x2, y2, th1 + delta_theta, len1 * shrink_factor) ; pop stack level stack_pointer -= 1 } } sub start() { graphics.enable_bitmap_mode() draw_branch(graphics.WIDTH / 2, graphics.HEIGHT - 1, floats.π / 2, graphics.HEIGHT / 2 * shrink_factor) ; done rendering; wait for a key before exiting do { ubyte key = cbm.GETIN2() } until key != 0 graphics.disable_bitmap_mode() } }