mirror of
https://github.com/irmen/prog8.git
synced 2024-11-28 10:51:14 +00:00
80 lines
2.5 KiB
Plaintext
80 lines
2.5 KiB
Plaintext
|
; 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()
|
||
|
}
|
||
|
}
|