GS 2010-01-08: This little demo, draw a tree with interactive parameters controls such as tree height, trunk bending, branch level or angle.
Jeff Smith 2019-06-17 : Below is an online demo using CloudTk
#! /bin/env tclsh # growingtree.tcl # Author: Gerard Sookahet # Date: 08 Jan 2010 # Description: Draw an interactive tree with controls. # Changelog: 2018-04-26: Code reformatted by pooryorick. # 2018-04-29: Updated by dbohdan to use Ttk widgets and # namespace variables instead of globals, and handle resizing. package require Tk 8.5 namespace eval growingtree { variable lcolor { #00ff00 #00e500 #00cc00 #00b200 #009900 #007f00 #006600 #004c00 #003300 #001900 } variable bendangle0 9 variable bendangle $bendangle0 variable branchangle0 60 variable branchangle $branchangle0 variable branchratio .4 variable height 2.6 variable rdepth 5 variable trunkratio .2 } proc growingtree::About {} { set w .about catch {destroy $w} toplevel $w wm title $w {About growingtree} message $w.msg \ -justify center \ -aspect 250 \ -relief sunken \ -bg blue \ -fg white \ -text "growingtree\n\nGerard Sookahet\n\nJanuary 2010" ttk::button $w.bquit -text { OK } -command {destroy .about} pack $w.msg pack $w.bquit -pady 5 } proc growingtree::UpdateScaleVar {w varName resolution value} { upvar 1 $varName var set var [expr {int($value) * $resolution}] RedrawTree $w } proc growingtree::TreeScale {w path varName text from to resolution} { upvar 1 $varName var set qualVarName [namespace current]::$varName ttk::label ${path}_info -text $text ttk::label ${path}_value -textvariable $qualVarName ttk::scale $path \ -from [expr {$from / $resolution}] \ -to [expr {$to / $resolution}] \ -value [expr {$var / $resolution}] \ -length 360 \ -orient horiz \ -command [list \ [namespace current]::UpdateScaleVar \ $w \ $qualVarName \ $resolution \ ] } proc growingtree::Main N { variable bendangle0 variable branchangle0 variable branchratio variable H variable height variable lcolor variable rdepth variable trunkratio set w .itree catch {destroy $w} toplevel $w wm withdraw . wm title $w "Growing tree" wm geometry $w +10+10 set f0 [frame $w.f0] pack [canvas $w.c -width $N -height $N -bg white] \ -side left \ -fill both \ -expand 1 pack $f0 -side right -fill both set H $N RedrawTree $w set f1 [ttk::frame $f0.f1] pack $f1 -fill x TreeScale $w $f1.sc1 rdepth {branch level} 1 10 1 TreeScale $w $f1.sc2 bendangle0 {bend angle} -60 60 1 TreeScale $w $f1.sc3 branchangle0 {branch angle} 0 180 1 TreeScale $w $f1.sc4 trunkratio {trunk ratio} 0 0.7 0.01 TreeScale $w $f1.sc5 branchratio {branch ratio} 0.1 2.0 0.1 TreeScale $w $f1.sc6 height {tree height} 0.1 4.0 0.1 pack {*}[winfo children $f1] -padx 10 set f3 [ttk::frame $f0.f3] pack $f3 -fill x ttk::button $f3.ba -text About -width 6 -command [namespace code About] ttk::button $f3.bq -text Quit -width 5 -command exit pack {*}[winfo children $f3] -side left -padx 5 -pady 5 } proc growingtree::DrawTree {w xo yo a r level} { variable bendangle variable branchangle variable branchratio variable height variable lcolor variable trunkratio set rad 0.0174532925 set arad [expr {$a*$rad}] set rtr [expr {$r*$trunkratio}] set x [expr {$xo + cos($arad)*$rtr}] set y [expr {$yo - sin($arad)*$rtr}] $w.c create line $xo $yo $x $y -fill [lindex $lcolor $level] -width $level if {$level > 0} then { incr level -1 set a [expr {$a + $bendangle}] set rbr [expr {$r*$branchratio}] DrawTree $w $x $y [expr {$a - $branchangle}] $rbr $level DrawTree $w $x $y [expr {$a + $branchangle}] $rbr $level DrawTree $w $x $y $a [expr {(1 - $trunkratio)*$r}] $level } } proc growingtree::RedrawTree w { variable bendangle variable bendangle0 variable branchangle variable branchangle0 variable H variable height variable lcolor variable rdepth $w.c delete all set rad 0.0174532925 set bendangle $bendangle0 set branchangle $branchangle0 DrawTree $w 200 400 90 [expr {($H - 200)*$height}] $rdepth } # If this is the main script... if {[info exists argv0] && ([file tail [info script]] eq [file tail $argv0])} { bind all <Escape> {exit} growingtree::Main 400 }