ulis, 2004-11-28. From chaos to order.
The mesh evolves until a pseudo-equilibrium is reached.
At each step, an atom moves to state n+1 if it encounters an atom already in state n+1.
In other words, state n+1 eats state n.
For evolution to be continuous, state nmax+1 is state 0.
# procs
proc getIndex {i j} \
{
if {$i < 0} { set i [expr {$::size - 1}] }
if {$i == $::size} { set i 0 }
if {$j < 0} { set j [expr {$::size - 1}] }
if {$j == $::size} { set j 0 }
return [lsearch -exact $::colors [lindex $::data0 $i $j]]
}
proc createColors {} \
{
set s 128
for {set n 1} {$n <= $::count} {incr n} \
{
set h [expr {256 / ($::count + 1) * $n}]
set v [expr {256 - $h}]
# convert to RGB
if {$s == 0} \
{ foreach c {r g b} { set $c [expr {int($v)}] } } \
else \
{
set f [expr {$h / 60.0}]
set i [expr {int($f)}]
set f [expr {$f - $i}]
set p [expr {$v * (1 - $s)}]
set q [expr {$v * (1 - $s * $f)}]
set t [expr {$v * (1 - $s * (1 - $f))}]
set list \
{
{v t p}
{q v p}
{p v t}
{p q v}
{t p v}
{v p q}
}
foreach c {r g b} u [lindex $list $i] \
{
set $c [expr {int([set $u])}]
if {[set $c] < 0} { set $c 0 }
if {[set $c] > 255} { set $c 255 }
}
}
lappend ::colors [format #%02x%02x%02x $r $g $b]
}
}
# parameters
set size 256
set count 15
# init
createColors
package require Tk
wm title . "ordre et chaos"
wm protocol . WM_DELETE_WINDOW exit
image create photo _img_ -width $size -height $size
canvas .c -width $size -height $size
.c create image 1 1 -anchor nw -image _img_
pack .c
raise .
focus -force .
set data1 [_img_ data]
set data0 $data1
for {set i 0} {$i < $size} {incr i} \
{
for {set j 0} {$j < $size} {incr j} \
{
set index [expr {int(rand() * $count)}]
if {$index == $::count} { set index [expr {$::count - 1}] }
lset ::data1 $i $j [lindex $::colors $index]
}
}
# pensive crystal
while {1} \
{
_img_ put $data1
set data0 $data1
update
for {set i 0} {$i < $size} {incr i} \
{
for {set j 0} {$j < $size} {incr j} \
{
set index [getIndex $i $j]
set next [expr {($index + 1) % $::count}]
incr i -1
set list [list [getIndex $i $j]]
incr i
incr j -1
lappend list [getIndex $i $j]
incr j 2
lappend list [getIndex $i $j]
incr i
incr j -1
lappend list [getIndex $i $j]
incr i -1
foreach ndx $list \
{
if {$ndx == $next} \
{
lset ::data1 $i $j [lindex $::colors $ndx]
break
}
}
}
}
}One more thing: patience. We're simulating geological time here.
The following discussion is translated from wfr.tcl.tk/OrdreEtChaos .
GS It's superb. It's worth being patient.
AM I've read the code and in my opinion the speed can be improved: now the state (as stored in variables data1 and data0) consists of colors - so to calculate the next step you have to translate the colors to numbers and vice versa. I'll try to rebuild the above code according to these ideas.
Another improvement: show the time in, for example, the title - it will be easier to accept that there are changes even if they are slow.
AM Perhaps in the same category we can write an implementation of the Ising model :)