proc ui {} { set width 620 pack [canvas .c -width $width -height 170 -bg white] pack [label .l -textvariable info -fg blue] -fill x .c create rect 0 50 $width 120 -fill grey90 .c create rect 0 50 $width 120 -fill beige -outline beige \ -tag {slide slidebase} .c create line 0 0 0 120 -tag mark -fill blue drawScale .c K x3 10 5 5 log10 1 1000 186.6666667 drawScale .c A x2 10 50 -5 log10 1 100 280 drawScale .c B x2 10 50 5 log10 1 100 280 slide drawScale .c CI 1/x 10 90 -5 -log10 1 10 560 slide drawScale .c C x 10 120 -5 log10 1 10 560 slide drawScale .c D x 10 120 5 log10 1 10 560 drawScale .c L "lg x" 10 160 -5 by100 0 10 5600 bind .c <Motion> {.c coords mark %x 0 %x 170; set info [values .c]} bind .c <1> {set x %x} bind .c <B1-Motion> {%W move slide [expr {%x-$x}] 0; set x %x} bind . <Shift-Left> {.c move slide -1 0; set info [values .c]} bind . <Shift-Right> {.c move slide 1 0; set info [values .c]} bind . <Left> {.c move mark -1 0; set info [values .c]} bind . <Right> {.c move mark 1 0; set info [values .c]} } proc drawScale {w name label x y dy f from to fac {tag {}}} { set color [expr {[string match -* $f]? "red": "black"}] $w create text $x [expr $y+2*$dy] -text $name -tag $tag -fill $color $w create text 600 [expr $y+2*$dy] -text $label -tag $tag -fill $color set x [expr {[string match -* $f]? 580: $x+10}] set mod 5 set lastlabel "" set lastx 0 for {set i [expr {$from*10}]} {$i<=$to*10} {incr i} { if {$i>100} { if {$i%10} continue ;# coarser increments set mod 50 } if {$i>1000} { if {$i%100} continue ;# coarser increments set mod 500 } set x0 [expr $x+[$f [expr {$i/10.}]]*$fac] set y1 [expr {$i%(2*$mod)==0? $y+2.*$dy: $i%$mod==0? $y+1.7*$dy: $y+$dy}] set firstdigit [string index $i 0] if {$y1==$y+$dy && abs($x0-$lastx)<2} continue set lastx $x0 if {$i%($mod*2)==0 && $firstdigit != $lastlabel} { $w create text $x0 [expr $y+3*$dy] -text $firstdigit \ -tag $tag -font {Helvetica 7} -fill $color set lastlabel $firstdigit } $w create line $x0 $y $x0 $y1 -tag $tag -fill $color } } proc values w { set x0 [lindex [$w coords slidebase] 0] set x1 [lindex [$w coords mark] 0] set lgx [expr {($x1-20)/560.}] set x [expr {pow(10,$lgx)}] set lgxs [expr {($x1-$x0-20)/560.}] set xs [expr {pow(10,$lgxs)}] set res K:[format %.2f [expr {pow($x,3)}]] append res " A:[format %.2f [expr {pow($x,2)}]]" append res " B:[format %.2f [expr {pow($xs,2)}]]" append res " CI:[format %.2f [expr {pow(10,-$lgxs)*10}]]" append res " C:[format %.2f $xs]" append res " D:[format %.2f $x]" append res " L:[format %.2f $lgx]" } proc pow10 x {expr {pow(10,$x)}} proc log10 x {expr {log10($x)}} proc -log10 x {expr {-log10($x)}} proc by100 x {expr {$x/100.}} #-------------------------------- ui bind . <Escape> {exec wish $argv0 &; exit}
Judging from some web sites, it appears as if the parts of a slide-rule are called "stator" (big white), "slide" (thin beige), and "cursor" (transparent little thing, blue line in the above example). Also, there's a roughly comparable emulation in Java at http://www.cs.utsa.edu/~wagner/slide/Slide5.html
Absolutely Amazing for such little code! Nicely DONE!
AM I can add a personal touch to the end of the slide-rule era:When I took my final exams in secondary school (in 1978-79), there was a debate whether electronic calculators should be allowed. The decision was no, because they were still pretty expensive at the time and allowing them might force students who did not yet have one to buy such a thing.It was, however, a prequisite when I went to university in that same year. After school I have used it sporadically, but I envy my father for his possessing a very smooth wooden slide-rule in a nice wooden casing.This page inspired me to look into another obsolete instrument, the klepsydra.
Anyone ever build a Tcl toy circular slide rule [1] ?
GWM I also used slide rules for A level exams in 1970 - this version doesn't have the sliding part sticking out of the end which was useful for taking people's eyes out. I met my first 'pocket' calculator (an HP with RPN notation costing some £200, or $500 at the time) working for ESTEC in 1972; it had some 20 math functions and the head of department took it to the Munich Olympics to calculate the speed of the runners. I discovered that selecting the arc-tan function repeatedly eventually produced a constant value (89.35883916.. you can repeat this with a modern calculator) - just a short way from discovering Mandelbrot sets (this solves the equation f=atan(f)). One colleague had an Otis King cylindrical slide rule giving an effective 200 cm long slide rule (all of 5 sig figs accuracy!). See http://www.hpmuseum.org/srcyl.htm for pictures of slide rules. The figures in this note are probably distorted by my memory, do not rely on them for correctness.
RFox - I used a Keufel-Esser Log-Log Duplex Decitrig model slide rule throughout graduate school, especially, while being a TA at UIUC's PHYS 101 class. I did this mostly to attempt to discourage students from reacting to a problem by ducking their heads into their calculator, rather than taking the time to analytically solve their problems first... Richard.. Having the cursor location shown numerically at the bottom of the stator is cheating ;-) The whole point of being a slide-rule whiz was to learn to estimate/interpolate by eye where the cursor was on the stator or slide.
GS (040915) Don't forget the Curta [2], one of the first pocket calculator (mechanical).
US Changing the proc ui to the following makes it, at least for me, better usable. Left button clicked and moved on the 'stator' moves the 'cursor', whereas clicking and moving on the 'slide' moves the 'slide'.
proc ui {} { set width 620 pack [canvas .c -width $width -height 170 -bg white] pack [label .l -textvariable info -fg blue] -fill x .c create rect 0 0 $width 170 -fill white -outline white \ -tag stator .c create rect 0 50 $width 120 -fill grey90 .c create rect 0 50 $width 120 -fill beige -outline beige \ -tag {slide slidebase} .c create line 0 0 0 120 -tag mark -fill blue drawScale .c K x3 10 5 5 log10 1 1000 186.6666667 stator drawScale .c A x2 10 50 -5 log10 1 100 280 stator drawScale .c B x2 10 50 5 log10 1 100 280 slide drawScale .c CI 1/x 10 90 -5 -log10 1 10 560 slide drawScale .c C x 10 120 -5 log10 1 10 560 slide drawScale .c D x 10 120 5 log10 1 10 560 stator drawScale .c L "lg x" 10 160 -5 by100 0 10 5600 stator .c bind stator <B1-Motion> {.c coords mark %x 0 %x 170; set info [values .c]} .c bind stator <1> {.c coords mark %x 0 %x 170; set info [values .c]} .c bind slide <1> {set x %x} .c bind slide <B1-Motion> {%W move slide [expr {%x-$x}] 0; set x %x} bind . <Shift-Left> {.c move slide -1 0; set info [values .c]} bind . <Shift-Right> {.c move slide 1 0; set info [values .c]} bind . <Left> {.c move mark -1 0; set info [values .c]} bind . <Right> {.c move mark 1 0; set info [values .c]} }
TP Here's a nice link on how to actually use a slide rule: http://www.sliderulemuseum.com/SR_Course.htm The page includes an HTML version that you can open in a browser.