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