DaisyWorld

 

ulis, 14-12-2004. Qui n'a jamais rêver au joli monde des paquerettes ? Les jaunes qui aiment le soleil, les rouges qui préfèrent l'ombre.

"Daisyworld est un modèle de simulation imaginé par James Lovelock pour illustrer les théories Gaia et répondre aux critiques virulentes de téléologisme, dont faisait l'objet l'hypothèse Gaia".


Pourquoi ?

Qui n'a jamais rêver d'un monde à lui ?


Comment ça marche ?

Trop de pâquerettes rouges et il fait trop chaud pour elles mais c'est un délice pour les jaunes.

Trop de pâquerettes jaunes et il fait trop froid pour elles mais c'est un bonheur pour les rouges.

La température au sol est réglée par l'albedo des pâquerettes sombres et claires qui y poussent.


Le code

  # -----------
  # parameters
  # -----------
  set ::size 128
  set ::gtemp 20
  set ::gmax 60
  set ::step 0.25
  set ::tmin 10
  set ::tmax 20
  # -----------
  # packages
  # -----------
  package require Tk
  # -----------
  # procs
  # -----------
  proc initGaia {} \
  {
    set ::size1 $::size; incr ::size1 -1
    image create photo _img1_ -width $::size -height $::size
    _img1_ put gray -to 0 0 $::size $::size
    set ::ccount 0
    set ::coffset [expr {$::gtemp / 2}]
    set ::ccoef1 [expr {double($::size) / ($::gmax - $::coffset)}]
    set ::ccoef2 [expr {1.0 / $::size}]
    set cwidth [expr {int(($::gmax - $::gtemp) / $::step)}]
    image create photo _img2_ -width $cwidth -height $::size
    _img2_ put black -to 0 0 [expr {$cwidth - 1}] $::size
    set height [expr {$::size + 50}]
    canvas .c -width [expr {$::size + $cwidth + 10}] -height $height \
    -bd 0 -highlightt 0
    .c create image 0 0 -anchor nw -image _img1_
    .c create image [expr {$::size + 10}] 0 -anchor nw -image _img2_
    set y $::size; incr y 10
    .c create text 25 $y -anchor nw -tags t1
    incr y 20
    .c create text 25 $y -anchor nw -tags t2
    pack .c -padx 10 -pady 10
    button .b -width 10 -text "fix temp" -command fixTemp
    set ::fix 0
    pack .b
    . config -pady 10
    wm protocol . WM_DELETE_WINDOW exit
    wm title . "DaisyWorld"
    raise .
    focus -force .
  }
  proc fixTemp {} \
  {
    if {$::fix} \
    {
      .b config -text "fix temp"
      set ::fix 0
    } \
    else \
    {
      .b config -text "free temp"
      set ::fix 1
    }
  }
  proc displayStat {t1 t2 c1 c2} \
  {
    .c itemconfig t1 -text "[format %05.2f $t1]/[format %05.2f $t2] °C sun=purple/ground=green"
    .c itemconfig t2 -text "$c1/$c2   yellow/red daisies"
    _img2_ put purple -to $::ccount [expr {round($::size - ($t1 - $::coffset) * $::ccoef1)}]
    _img2_ put green -to $::ccount [expr {round($::size - ($t2 - $::coffset) * $::ccoef1)}]
    _img2_ put yellow -to $::ccount [expr {round($::size - ($c1 * $::ccoef2))}]
    _img2_ put red -to $::ccount [expr {round($::size - ($c2 * $::ccoef2))}]
  }
  proc initDaisies {d} \
  {
    set $d [list]
    for {set i 0} {$i < $::size} {incr i} \
    { lappend $d [split "[string repeat "g " $::size1]g"] }
  }
  proc getTemp {i j} \
  {
    set t 0
    foreach di {-1 0 1} \
    {
      foreach dj {-1 0 1} \
      {
        set ci [expr {$i + $di}]
        if {$ci < 0} { set ci $::size1 }
        if {$ci > $::size1} { set ci 0 }
        set cj [expr {$j + $dj}]
        if {$cj < 0} { set cj $::size1 }
        if {$cj > $::size1} { set cj 0 }
        set v [lindex $::d $ci $cj]
        set coef [expr {$v == "g" ? 0.5 : $v == "y" ? 0.25 : 0.75}]
        set t [expr {$t + $::gtemp * $coef}]
      }
    }
    return [expr {$t / 9.0}]
  }

  # -----------
  # where life spreads
  # -----------
  initGaia
  initDaisies ::d
  set ::d2 $::d
  while {$::gtemp < $::gmax} \
  {
    set gt 0
    set rc 0
    set yc 0
    for {set i 0} {$i < $::size} {incr i} \
    {
      update
      for {set j 0} {$j < $::size} {incr j} \
      {
        set t [getTemp $i $j]
        set gt [expr {$gt + $t}]
        set v [lindex $::d $i $j]
        if {$v == "g"} \
        {
          if {$t >= $::tmin && $t <= $::tmax} \
          { set v [expr {rand() > 0.5 ? "y" : "r"}] }
        } \
        elseif {$t < $::tmin || $t > $::tmax} { set v "g" }
        lset ::d2 $i $j $v
        set c gray
        if {$v == "y"} \
        {
          set c yellow
          incr yc
        } \
        elseif {$v == "r"} \
        {
          set c red
          incr rc
        }
        set c [expr {$v == "y" ? "yellow" : $v == "g" ? "gray" : "red"}]
        _img1_ put $c -to $i $j
      }
    }
    set gt [expr {$gt / $::size / $::size}]
    displayStat $::gtemp $gt $yc $rc
    set ::d $::d2
    initDaisies ::d2
    if {!$::fix} \
    {
      set ::gtemp [expr {$::gtemp + $::step}]
      incr ::ccount
    }
  }

Voir aussi


Discussion


Catégorie Exemple