Generate and draw a fractal tree.

 Draw the trunk
 At the end of the trunk, split by some angle and draw two branches
 Repeat at the end of each branch until a sufficient level of branching is reached


Related tasks
 Pythagoras Tree


--
-- demo\rosetta\FractalTree.exw
-- ============================
--
with javascript_semantics
include pGUI.e

Ihandle dlg, canvas
cdCanvas cddbuffer, cdcanvas

procedure drawTree(integer level, atom angle, len, integer x, y)
    integer xn = x + floor(len*cos(angle)),
            yn = y + floor(len*sin(angle)),
            red = 255-level*8,
            green = level*12+100
    cdCanvasSetForeground(cddbuffer, red*#10000 + green*#100)
    cdCanvasSetLineWidth(cddbuffer,floor(5-level/3))
    cdCanvasLine(cddbuffer, x, 480-y, xn, 480-yn)
    if level<12 then
        drawTree(level+1, angle-0.4, len*0.8, xn, yn)   --left
        drawTree(level+1, angle+0.1, len*0.8, xn, yn)   --right
    end if
end procedure
 
function redraw_cb(Ihandle /*ih*/, integer /*posx*/, /*posy*/)
    cdCanvasActivate(cddbuffer)
    cdCanvasClear(cddbuffer)
    drawTree(0, -PI/2.0, 80.0, 360, 460)
    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_PARCHMENT)
    return IUP_DEFAULT
end function

procedure main()
    IupOpen()

    canvas = IupCanvas("RASTERSIZE=640x480")
    IupSetCallbacks(canvas, {"MAP_CB", Icallback("map_cb"),
                             "ACTION", Icallback("redraw_cb")})

    dlg = IupDialog(canvas,"RESIZE=NO")
    IupSetAttribute(dlg, "TITLE", "Fractal Tree")

    IupShow(dlg)
    if platform()!=JS then
        IupMainLoop()
        IupClose()
    end if
end procedure

main()
