Brownian tree

You are encouraged to solve this task according to the task description, using any language you may know.



Task

Generate and draw a   Brownian Tree.



A Brownian Tree is generated as a result of an initial seed, followed by the interaction of two processes.

 The initial "seed" is placed somewhere within the field. Where is not particularly important; it could be randomized, or it could be a fixed point.
 Particles are injected into the field, and are individually given a (typically random) motion pattern.
 When a particle collides with the seed or tree, its position is fixed, and it's considered to be part of the tree.

Because of the lax rules governing the random nature of the particle's placement and motion, no two resulting trees are really expected to be the same, or even necessarily have the same general shape. 



-- demo\rosetta\BrownianTree.exw
include pGUI.e
 
Ihandle dlg, canvas
cdCanvas cddbuffer, cdcanvas
 
function redraw_cb(Ihandle /*ih*/, integer /*posx*/, integer /*posy*/)
integer x,y,ox,oy
integer {width, height} = IupGetIntInt(canvas, "DRAWSIZE")
sequence grid = repeat(repeat(0,width),height)
integer xy = floor(width*height*0.8)
--atom t = time()+1
    grid[floor(width/2)][floor(height/2)] = 1
    cdCanvasActivate(cddbuffer)
    cdCanvasClear(cddbuffer)
    for i=1 to xy do
        x = rand(width) y = rand(height)
        ox = x          oy = y
        while x>=1 and x<=width 
          and y>=1 and y<=height do
            if grid[y][x] then
                grid[oy][ox] = 1
                cdCanvasPixel(cddbuffer, ox, oy, #00FF00) 
                exit
            end if
            ox = x  x += rand(3)-2
            oy = y  y += rand(3)-2
        end while
--      -- if making the canvas bigger/resizeable, 
--      --  put this in so that you can kill it.
--      if time()>=t then
--          ?{i,xy}
--          t = time()+1
--      end if
    end for
    cdCanvasFlush(cddbuffer)
    return IUP_DEFAULT
end function
 
function map_cb(Ihandle ih)
    cdcanvas = cdCreateCanvas(CD_IUP, ih)
    cddbuffer = cdCreateCanvas(CD_DBUFFER, cdcanvas)
    cdCanvasSetBackground(cddbuffer, CD_WHITE)
    cdCanvasSetForeground(cddbuffer, CD_RED)
    return IUP_DEFAULT
end function
 
IupOpen()
 
canvas = IupCanvas(NULL)
IupSetAttribute(canvas, "RASTERSIZE", "200x200") -- fixed size
IupSetCallback(canvas, "MAP_CB", Icallback("map_cb"))
 
dlg = IupDialog(canvas, "RESIZE=NO")
IupSetAttribute(dlg, "TITLE", "Brownian Tree")
IupSetCallback(canvas, "ACTION", Icallback("redraw_cb"))
 
IupShow(dlg)
if platform()!=JS then
    IupMainLoop()
    IupClose()
end if
