mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 15:33:02 +00:00
New example program: draw a fractal tree (#152)
* demo of prog8 recursion to draw a fractal tree * feat: comments * fix: comment formatting * feat: make minimum branch size a tunable parameter
This commit is contained in:
parent
3cf39e072e
commit
70a2b11271
79
examples/fractal-tree.p8
Normal file
79
examples/fractal-tree.p8
Normal file
@ -0,0 +1,79 @@
|
||||
; 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()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user