RosettaCodeData/Task/Brownian-tree/FutureBasic/brownian-tree.basic

154 lines
3.2 KiB
Plaintext

// Brownian tree
//https://rosettacode.org/wiki/Brownian_tree
/*
A Brownian tree is built with these steps:
first, a "seed" is placed somewhere on the screen.
Then, a particle is placed in a random position of the screen,
and moved randomly until it bumps against the seed.
The particle is left there, and another particle is placed in a random position
and moved until it bumps against the seed or any previous particle, and so on.
*/
begin globals
_w = 400 // window size
short w = _w
bool pixelUsed(_w ,_w )
short x, y , Oldx, Oldy
cgRect TheRect
short Edge
long SpeckleCount
short MainColor,SpeckleColor
bool GreenGreen,WhiteWhite,WhiteIndigo,WhiteMagenta,GreenIndigo,CyanBlue
bool SeedPlanted
long count
// Color Options
GreenGreen = 0
GreenIndigo = 0
WhiteIndigo = 1
WhiteWhite = 0
WhiteMagenta = 0
CyanBlue = 0
if GreenGreen then MainColor = _ZGreen : SpeckleColor = _ZGreen
if WhiteWhite then MainColor = _ZWhite : SpeckleColor = _ZWhite
if WhiteIndigo then MainColor = _ZWhite : SpeckleColor = _zSystemIndigo
if WhiteMagenta then MainColor = _ZWhite : SpeckleColor = _zMagenta
if GreenIndigo then MainColor = _ZGreen : SpeckleColor = _zSystemIndigo
if CyanBlue then MainColor = _zCyan : SpeckleColor = _zBlue
end globals
_Window = 1
window _Window, @"", ( 0, 0, _w, _w ), NSWindowStyleMaskTitled + NSWindowStyleMaskMiniaturizable
windowcenter(_Window)
WindowSetBackgroundColor(_Window,fn ColorBlack)
local fn ClearPixelArray
cls
short row,col
for row = 1 to 400
for col = 1 to 400
pixelUsed(row,col) = NO
next
next
SpeckleCount = 0
Edge = _w
/// place seed in the middle
pen -1
oval fill (w/2,w/2,5,5), MainColor
x = w/2
y = w/2
pixelUsed(x,y) = YES
Oldx = x
Oldy = y
count = 0
SeedPlanted = _true
end fn
local fn DrawPixels
// Set New Random particle location
if SeedPlanted = _false
do
x = rnd(Edge)
y = rnd(Edge)
until pixelUsed(x,y) = NO
end if
SeedPlanted = _false
short xBack, yBack
xBack = x
yBack = x
// Find a location for the new particle
do
Oldx = x
Oldy = y
// set x and y within plus or minus 15 pixels of x or y
x += RND(3) - 2
y += RND(3) - 2
// prevent results that are not within 15 pixels of Oldx and Oldy
if x <= 0 then x = xBack : y = yBack
if y <= 0 then y = xBack : y = yBack
if x > Edge then x = xBack : y = yBack
if y > Edge then y = xBack : y = yBack
until pixelUsed(x,y) = YES
// Draw the new particle but protect the margin on the edge
if Oldx > 15 && Oldx < Edge - 15 && Oldy > 15 && Oldy < Edge - 15
SpeckleCount ++
pen -1
if SpeckleCount < 200
oval fill (Oldx,Oldy,1,1), MainColor
else
oval fill (Oldx,Oldy,2,2), SpeckleColor
SpeckleCount = 0
end if
pixelUsed(Oldx,Oldy) = YES
xBack = x
yBack = y
count ++
end if
if count > 10000
CFStringRef ReturnedKey
ReturnedKey = Inkey %(90,1),@"Any key for another one. Q to quit"
if fn StringContainsString(ReturnedKey, @"q") then end
if fn StringContainsString(ReturnedKey, @"Q") then end
fn ClearPixelArray
end if
end fn
fn ClearPixelArray
fn AppSetTimer( .000001, @Fn DrawPixels, _true )
handleevents