Hey there,
Just a pretty simple demo, I was experimenting with recursive tree drawing fractals using turtle graphics with DBP, and was able to come up with some interesting looking fractal trees.
Here is the demo:
// Screen settings
sync on : sync rate 60
// Initialize LOGO variables
LOGO_Initialize()
// TREE VALUES - THESE VALUES SPECIFY THE LOOK OF THE TREES
#constant TOTAL_TREE_TYPES 5
global dim treeShape(TOTAL_TREE_TYPES) as treeShapeType
type treeShapeType
branchFactor as float
branchAngleLeft as float
branchAngleRight as float
endtype
// TREE TYPE 1: STANDARD
treeShape(1).branchFactor = 0.6
treeShape(1).branchAngleLeft = 45
treeShape(1).branchAngleRight = 45
// TREE TYPE 2: BONZAI
treeShape(2).branchFactor = 0.7
treeShape(2).branchAngleLeft = 15
treeShape(2).branchAngleRight = 25
// TREE TYPE 3: WILLOW
treeShape(3).branchFactor = 0.7
treeShape(3).branchAngleLeft = 70
treeShape(3).branchAngleRight = 70
// TREE TYPE 4: PALM
treeShape(4).branchFactor = 0.6
treeShape(4).branchAngleLeft = 15
treeShape(4).branchAngleRight = 70
// TREE TYPE 5: PINE
treeShape(5).branchFactor = 0.7
treeShape(5).branchAngleLeft = 120
treeShape(5).branchAngleRight = 0
// Defaults for animated tree
treeType = 1 // Default tree type
size# = 100.0 // Tree size
branch# = 0.0 // Branch sway oscillation
// Main loop
do
// Clear screen and show info
cls
set cursor 0, 0
print "SCREEN FPS: "+str$(screen fps())
print "ANIMATED FRACTAL TREE"
print "L-Click to grow, R-Click to shrink"
print "SPACE to change tree type"
print "Hold CTRL for more branches (MAY CAUSE FPS DROP)"
// Change type of tree with space
space = spacekey()
if space = 1 and spacePress = 0
// Toggle tree types
inc treeType
if treeType > TOTAL_TREE_TYPES then dec treeType, TOTAL_TREE_TYPES
endif
spacePress = space
// Sway branches
branch# = wrapvalue(branch# + 0.5)
// Grow / Shrink tree
if mouseclick() = 1 then inc size#, 0.5
if mouseclick() = 2 then dec size#, 0.5
// Draw tree
FractalTree(mousex(), mousey(), 0, int(size#), treeShape(treeType).branchFactor+(controlkey()*0.1), treeShape(treeType).branchAngleLeft+sin(branch#), treeShape(treeType).branchAngleRight-sin(branch#))
sync
loop
// Draw a fractal tree to the current bitmap
function FractalTree(x#, y#, ang#, size, branchFactor#, angLeft#, angRight#)
// If branchFactor# is not less than 1.0, then the branches cannot get any
// smaller and the tree will never end, so don't allow that to happen
if branchFactor# >= 1.0 then exitfunction
// Set initial drawing position
LOGO_Position(x#, y#, ang#)
LOGO_PenDown()
// Draw the first branch
FractalTree_Branch(size, size, branchFactor#, angLeft#, angRight#)
endfunction
// Draw a branch of the fractal tree
function FractalTree_Branch(size, mainSize, branchFactor#, angLeft#, angRight#)
// End the branch if the size is too small
if size <= 0 then exitfunction
// Determine color of branch
// (Fade from brown [bottom] to green [top])
greenVal# = (mainSize*1.0 - size*3.0) / (mainSize*1.0)
if greenVal# < 0.0 then greenVal# = 0.0
ink rgb(128-128*greenVal#, 64+64*greenVal#, 0), 0
// Move the turtle forward
LOGO_Forward(size)
// Draw the left branches
LOGO_Left(angLeft#)
FractalTree_Branch(size * branchFactor#, mainSize, branchFactor#, angLeft#, angRight#)
// Draw the right branches
LOGO_Right(angLeft#+angRight#)
FractalTree_Branch(size * branchFactor#, mainSize, branchFactor#, angLeft#, angRight#)
// Return to original position
LOGO_PenUp()
LOGO_Left(angRight#)
LOGO_Back(size)
LOGO_PenDown()
endfunction
// Setup global variables used by LOGO drawing system
function LOGO_Initialize()
// Variable set
global LOGO as LOGOType
// Default variables
LOGO.x = 0
LOGO.y = 0
LOGO.angle = 0
LOGO.penDown = 1
endfunction
// Put the pen down (draw lines as the turtle moves)
function LOGO_PenDown()
// Draw lines
LOGO.penDown = 1
endfunction
// Put the pen up (don't draw lines as the turtle moves)
function LOGO_PenUp()
// Don't draw lines
LOGO.penDown = 0
endfunction
// Absolutely position the turtle
function LOGO_Position(x#, y#, ang#)
// Position the turtle
LOGO.x = x#
LOGO.y = y#
LOGO.angle = ang#
endfunction
// Move the turtle forward
function LOGO_Forward(dist#)
// Determine the angle (assume angle 0 = North)
ang# = wrapvalue(LOGO.angle - 90)
// Determine destination offset
dx# = dist# * cos(ang#)
dy# = dist# * sin(ang#)
// Draw the line
if LOGO.penDown = 1 then line LOGO.x, LOGO.y, LOGO.x+dx#, LOGO.y+dy#
// Move the turtle
inc LOGO.x, dx#
inc LOGO.y, dy#
endfunction
// Move the turtle backwards
function LOGO_Back(dist#)
LOGO_Forward(-dist#)
endfunction
// Spin left
function LOGO_Left(ang#)
LOGO_Right(-ang#)
endfunction
// Spin right
function LOGO_Right(ang#)
LOGO.angle = wrapvalue(LOGO.angle + ang#)
endfunction
// UDT for LOGO system
type LOGOType
x as float
y as float
angle as float
penDown as boolean
endtype
It draws the trees in realtime each frame, allowing them to be animated or changed live. You can move the tree with the mouse, grow/shrink it with clicks, see how the tree "sways in the wind", grow extra branches with CTRL, and view 5 different possible types of trees with SPACE.
And here's the "Lite" version of the code, just generates a basic tree and doesn't have anything fancy like color changing or animation, but it's easier to see just what's going on.
// Screen settings
sync on : sync rate 60
// Initialize LOGO variables
LOGO_Initialize()
// Create a bitmap for tree
create bitmap 1, 512, 512
ink rgb(0, 128, 0), 0
FractalTree(256, 512, 0, 200, 0.6, 45, 45)
get image 1, 0, 0, 512, 512, 1
delete bitmap 1
// Main loop
do
// Clear screen and show info
cls
set cursor 0, 0
print "SCREEN FPS: "+str$(screen fps())
print "STATIC FRACTAL TREE"
// Show tree
paste image 1, 0, 0
sync
loop
// Draw a fractal tree to the current bitmap
function FractalTree(x#, y#, ang#, size, branchFactor#, angLeft#, angRight#)
// If branchFactor# is not less than 1.0, then the branches cannot get any
// smaller and the tree will never end, so don't allow that to happen
if branchFactor# >= 1.0 then exitfunction
// Set initial drawing position
LOGO_Position(x#, y#, ang#)
LOGO_PenDown()
// Draw the first branch
FractalTree_Branch(size, branchFactor#, angLeft#, angRight#)
endfunction
// Draw a branch of the fractal tree
function FractalTree_Branch(size, branchFactor#, angLeft#, angRight#)
// End the branch if the size is too small
if size <= 0 then exitfunction
// Move the turtle forward
LOGO_Forward(size)
// Draw the left branches
LOGO_Left(angLeft#)
FractalTree_Branch(size * branchFactor#, branchFactor#, angLeft#, angRight#)
// Draw the right branches
LOGO_Right(angLeft#+angRight#)
FractalTree_Branch(size * branchFactor#, branchFactor#, angLeft#, angRight#)
// Return to original position
LOGO_PenUp()
LOGO_Left(angRight#)
LOGO_Back(size)
LOGO_PenDown()
endfunction
// Setup global variables used by LOGO drawing system
function LOGO_Initialize()
// Variable set
global LOGO as LOGOType
// Default variables
LOGO.x = 0
LOGO.y = 0
LOGO.angle = 0
LOGO.penDown = 1
endfunction
// Put the pen down (draw lines as the turtle moves)
function LOGO_PenDown()
// Draw lines
LOGO.penDown = 1
endfunction
// Put the pen up (don't draw lines as the turtle moves)
function LOGO_PenUp()
// Don't draw lines
LOGO.penDown = 0
endfunction
// Absolutely position the turtle
function LOGO_Position(x#, y#, ang#)
// Position the turtle
LOGO.x = x#
LOGO.y = y#
LOGO.angle = ang#
endfunction
// Move the turtle forward
function LOGO_Forward(dist#)
// Determine the angle (assume angle 0 = North)
ang# = wrapvalue(LOGO.angle - 90)
// Determine destination offset
dx# = dist# * cos(ang#)
dy# = dist# * sin(ang#)
// Draw the line
if LOGO.penDown = 1 then line LOGO.x, LOGO.y, LOGO.x+dx#, LOGO.y+dy#
// Move the turtle
inc LOGO.x, dx#
inc LOGO.y, dy#
endfunction
// Move the turtle backwards
function LOGO_Back(dist#)
LOGO_Forward(-dist#)
endfunction
// Spin left
function LOGO_Left(ang#)
LOGO_Right(-ang#)
endfunction
// Spin right
function LOGO_Right(ang#)
LOGO.angle = wrapvalue(LOGO.angle + ang#)
endfunction
// UDT for LOGO system
type LOGOType
x as float
y as float
angle as float
penDown as boolean
endtype
Screenshot attached of a possible tree that can be generated (using the first snippet). Using the LOGO functions it's also pretty simple to program any sort of line-based fractals, like snowflakes, for example.
Just thought it was interesting.