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 equationsExample: 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
