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
}