Updated 2012-06-03 18:34:26 by aspect

Arjen Markus (19 december 2003) I intend this page for collecting a few examples to show with my mathematical notebook.

Example: Constructing a cycloid
 # Explain the construction of a cycloid
 #
 # Note:
 # We use a simple animation technique here
 #
 # Initialisation: define the procedure that takes care of drawing
 #
 @init {

    # Notes:
    # - Time must start at zero!
    # - The first time we do not want the animation
    #
    set stop 1

    proc drawCycloid {time deltt} {
       variable CNV
       variable width
       variable height
       variable radius
       variable stop

       $CNV delete all

       #
       # Draw the circle at the right position
       #
       set xcentre [expr {$time+$radius}]
       set ycentre [expr {$height-1-$radius}]
       set xleft   [expr {$xcentre-$radius}]
       set xright  [expr {$xcentre+$radius}]
       set ytop    [expr {$ycentre-$radius}] ;# Signs are correct!
       set ybottom [expr {$ycentre+$radius}]

       $CNV create oval $xleft $ytop $xright $ybottom -outline gray -width 2

       #
       # Draw the spoke
       #
       set angle [expr {$time/$radius}]
       set xend  [expr {$xcentre-$radius*sin($angle)}]
       set yend  [expr {$ycentre+$radius*cos($angle)}]

       $CNV create line $xcentre $ycentre $xend $yend -fill black

       #
       # Draw the cycloid
       #
       set t     0.0
       set xend  $radius
       set yend  [expr {$height-1}]
       while { $t <= $time } {
          set angle  [expr {$t/$radius}]
          set xbegin $xend
          set ybegin $yend
          set xend   [expr {$t+$radius-$radius*sin($angle)}]
          set yend   [expr {$ycentre+$radius*cos($angle)}]

          $CNV create line $xbegin $ybegin $xend $yend -fill black

          set t      [expr {$t+$deltt}]
       }

       #
       # Careful: we need to call this procedure from the global namespace
       #
       set time [expr {$time+$deltt}]
       if { $time < $width && $stop == 0 } {
          after 100 [list [namespace current]::drawCycloid $time $deltt]
       } else {
          set stop 0
       }
    }
 }
 <h1>Constructing a cycloid</h1>
 <p>
 (Press the Refresh button to see the construction at work)
 <p>
 @canvas 500 100 {
    set width  [$CNV cget -width]
    set height [$CNV cget -height]
    set radius [expr {$height*0.4}]
    set deltt  [expr {$width/50}]
    set time   0

    drawCycloid $time $deltt
 }
 <p>
 If you take a circle and roll it along a straight line, just as with a
 bicycle, then a fixed point on the circle (or wheel, if you like),
 follows a curve called the cycloid (see the picture)
 <p>
 The points on the cycloid can be described via these formulae:
 <pre>
    x  =  r * (t - sin(t))
    y  =  r * (1 - cos(t))

    r = radius of the circle
    t = time parameter
 </pre>
 <h1>Exercise</h1>
 Proof these equations

Example: Pythagorean triples
 # Pythagorean triples
 #
 <h1>Pythagorean triples</h1>
 <p>
 From elementary geometry we know the following equation by Pythagoras:
 <pre>

    a^2 + b^2 = c^2

 </pre>

 where a, b and c are the lengths of the sides of a right triangle
 <p>
 @canvas 200 200 {
    scale {-1 -1 6 6}
    polyline {0 0 4 0 4 3 0 0} black
    text     2.0 -0.5 a
    text     1.5  2.0 c
    text     4.5  1.5 b
 }
 <p>
 In general, one of a, b, or c will be an irrational number.

 But if we limit our attention to triangles where a, b and c are all
 integer, we get the so-called Pythagorean triples. Famous ones are:
 <pre>
    3, 4, 5
    5, 12, 13
 </pre>
 There is a simple formula that will gives us all the solutions:
 <pre>
    a = u^2 - v^2
    b = 2 uv
    c = u^2 + v^2
 </pre>
 And if we plot these solutions in a plane (regarding a and b as the
 coordinates of a point), we get this picture:
 @canvas 360 360 {
    $CNV create line 0  180 360 180 -fill gray
    $CNV create line 180  0 180 360 -fill gray
    for { set v 0 } { $v <= 40 } { incr v } {
       for { set u 0 } { $u <= $v } { incr u } {
          set x [expr {$u*$u-$v*$v}]
          set y [expr {2*$u*$v}]

          $CNV create rectangle [expr {179-$x}] [expr {179-$y}] \
                                [expr {181-$x}] [expr {181-$y}] \
                                -outline black -fill black

          $CNV create rectangle [expr {179+$x}] [expr {179+$y}] \
                                [expr {181+$x}] [expr {181+$y}] \
                                -outline black -fill black

          $CNV create rectangle [expr {179-$x}] [expr {179+$y}] \
                                [expr {181-$x}] [expr {181+$y}] \
                                -outline black -fill black

          $CNV create rectangle [expr {179+$x}] [expr {179-$y}] \
                                [expr {181+$x}] [expr {181-$y}] \
                                -outline black -fill black
       }
    }
 }

Example: A geographical quiz - not very mathematical :)
 # Simple geographical quiz
 #
 @init {
    #
    # The variable "names" has the following contents:
    # - The name of a country followed by the names of three cities,
    #   the first is the capital
    # - This is repeated
    #
    set names {
       Italy       {Rome Ravenna Rimini}
       France      {Paris Prague Palermo}
       Holland     {Amsterdam Arnhem Amstelveen}
       Britain     {London Liverpool Leeds}
       Switzerland {Bern Basel Bonn}
       Germany     {Berlin Bern Bonn}
       Austria     {Vienna Venice Vilnius}
    }

    #
    # Initialisation
    #
    set question 0
    set score    0
    set total    [expr {[llength $names] / 2}]

    proc nextQuestion {} {
       variable names
       variable question
       variable score
       variable total
       variable capital
       variable first
       variable second
       variable third
       variable answer
       variable correct_answer
       variable correct

       set correct ""
       if { $question < $total } {
          set capital [lindex $names [expr {2*$question}]]
          set answers [lindex $names [expr {2*$question+1}]]

          puts "Next: $answers"
          foreach {correct_answer first second third} \
             [randomList $answers] {break}
       } else {
          tk_messageBox -type ok -title "Geography quiz" \
             -message "Quiz complete: your score is $score out of $total"
       }
       puts "Next: $correct_answer"
    }

    proc randomList { answers } {
       set result  {}
       set first   [lindex $answers 0]
       set correct ""
       while { [llength $answers] != 0 } {
          set rnd [expr {int(rand()*[llength $answers])}]
          lappend result [lindex $answers $rnd]
          set answers    [lreplace $answers $rnd $rnd]
       }
       set correct  [lsearch $result $first]
       incr correct
       return [concat $correct $result]
    }

    proc checkAnswer {} {
       variable question
       variable correct
       variable correct_answer
       variable answer
       variable score
       variable total

       puts "Check: $answer - $correct_answer"
       if { $answer == $correct_answer } {
          incr score
          set correct "Correct"
       } else {
          set correct "Wrong, should have been: $correct_answer"
       }
       set answer ""
       incr question
    }

    #
    # Show the first question
    #
    nextQuestion
    console show
 }

 @refresh {
    checkAnswer
    after 2000 [list [namespace current]::nextQuestion]
 }

 <h1>Geography quiz</h1>
 <p>
 Answer the following questions (press Enter for the next):
 <p>
 What is the capital of
 @label capital 20
 ?
 <br>
 Possible answers:
 <br>
 1.
 @label first 20
 <br>
 2.
 @label second 20
 <br>
 3.
 @label third 20
 <p>
 Your answer (1, 2 or 3):
 @entry answer 5
 @label correct 30
 <p>
 Score:
 @label score 5
 correct out of
 @label total 5