proc main {} { set ::sense -1 pack [canvas .c -width 100 -height 100] for {set i 1} {$i<13} {incr i} { set a [expr {$i/6.*$::sense*acos(-1)}] set x [expr {50 + 43 * sin($a)}] set y [expr {50 - 43 * cos($a)}] .c create text $x $y -text $i -tag t } wm geom . 128x100 # every 100 {drawhands .c 50 50} every 500 {set time [clock format [clock sec] -format %H:%M:%S] drawhands .c 50 50; wm title . $time } bind .c <1> {set sense [expr -$sense]; .c scale t 50 50 -1 1} } proc drawhands {w xm ym} { $w delete hands set secSinceMidnight [expr {[clock seconds] - [clock scan 00:00:00]}] foreach divisor {30 1800 21600} length {40 35 30} width {1 2 3} { set angle [expr {$secSinceMidnight*$::sense*acos(-1) / $divisor}] set x [expr {$xm + $length * sin($angle)}] set y [expr {$ym - $length * cos($angle)}] $w create line $xm $ym $x $y -width $width -tags hands } } proc every {ms body} {eval $body; after $ms [info level 0]} main
AM (20 may 2005) I could not resist commenting on the introductory remarks :)Quite apart from clockwise and counterclockwise directions, there is also the matter of using the positive x-axis as the reference, instead of the positive y-axis. This is all about conventions, of course, but you would be surprised by the confusion they may cause - see Angles and directions for an earlier "lamentation" on the subject.In short: a mathematician (and, by proxy, a physicist) would devise a clock running from 0 to 11, where the 0 mark is at the right and the hands move in a leftward direction - counterclockwise you might say, but if such a clock were standard, it would not be a counter direction ...CLN Ah, handism rears its ugly head again! Speaking as a lefty, I have to ask, Why is a right-handed coordiate system better than a left-handed one? ;-)AM (In a conspiratory voice, as a fellow-lefty) In a right-handed system you actually rotate things leftwise! There have been rumours that the universe is right-handed - but I take that to be a vile plot ...Larry Smith It's a neurological fact that each side of a human body is controlled by the opposite side of the brain. It therefore follows that only lefties are in their right minds... =)RS confesses that he was born left-handed but retaught - only with tools like hammers or badminton or table-tennis rackets, my left hand does better :)
AM Whimsical design for a "true" mathematicians' clock:
- The clock is divided into 17 sectors
- The numbers start with zero and run up to 16
- Zero is placed on the positive x-axis
- The hands move in the counter-clockwise direction
proc main {} { set ::sense -1 set ::mode 24 pack [canvas .c -width 100 -height 100] for {set i 1} {$i<=$::mode} {incr i} { set a [expr {2*$i/double(${::mode})*$::sense*acos(-1)}] set x [expr {50 + 43 * sin($a)}] set y [expr {50 - 43 * cos($a)}] set c [expr {$i%2 ? "white" : "black"}] ;# alternate colors .c create text $x $y -text $i -tag t -fill $c } every 100 {drawhands .c 50 50} bind .c <1> {set sense [expr -$sense]; .c scale t 50 50 -1 1} } proc drawhands {w xm ym} { $w delete hands set secSinceMidnight [expr {[clock seconds] - [clock scan 00:00:00]}] foreach divisor [list 60 3600 [expr {86400*$::mode/24.0}]] length {40 35 30} width {1 2 3} { set angle [expr {$secSinceMidnight*$::sense*2*acos(-1) / $divisor}] set x [expr {$xm + $length * sin($angle)}] set y [expr {$ym - $length * cos($angle)}] $w create line $xm $ym $x $y -width $width -tags hands } } proc every {ms body} {eval $body; after $ms [info level 0]} mainAlmost the same code, with an extra parameter mode, giving the number of hours to display (24 hours here, as I've seen on some (marine?, italian?) wall clock). Setting mode to 12 give the standard 12 hours watch. You can of course set it to more exotic values, as 10 or 17 for instance. (PBO)
Same code again, but this version handles resizing of the main window:
proc main {} { set ::sense -1 set ::mode 24 set ::every_timer {} pack [canvas .c -width 100 -height 100] -fill both -expand yes bind .c <1> {set sense [expr -$sense]; .c scale t 50 50 -1 1} bind .c <Configure> [list redraw_digits %W %w %h] } proc drawhands {w xm ym} { $w delete hands set secSinceMidnight [expr {[clock seconds] - [clock scan 00:00:00]}] foreach divisor [list 60 3600 [expr {86400*$::mode/24.0}]] length {0.8 0.7 0.6} width {1 2 3} { set angle [expr {$secSinceMidnight*$::sense*2*acos(-1) / $divisor}] set x [expr {$xm + $length * $xm * sin($angle)}] set y [expr {$ym - $length * $ym * cos($angle)}] $w create line $xm $ym $x $y -width $width -tags hands } } proc every {ms body} { after cancel $::every_timer eval $body set ::every_timer [after $ms [info level 0]] } proc redraw_digits {w width height} { $w delete all set w2 [expr {$width/2.0}] set h2 [expr {$height/2.0}] set radius 0.86 for {set i 1} {$i<=$::mode} {incr i} { set a [expr {2*$i/double(${::mode})*$::sense*acos(-1)}] set x [expr {$w2 * (1 + $radius*sin($a))}] set y [expr {$h2 * (1 - $radius*cos($a))}] set c [expr {$i%2 ? "white" : "black"}] ;# alternate colors $w create text $x $y -text $i -tag t -fill $c } set cmd {set sense [expr -$sense];} append cmd [list $w scale t $w2 $h2 -1 1] bind $w <1> $cmd every 100 [list drawhands $w $w2 $h2] } mainRalf Fassel