Version 9 of Why manhole covers are round

Updated 2002-09-23 20:11:08

KPV - Why are manhole covers round? One answer is that they are the simplest shape which won't fall in on themselves.

(Bryan Oakley prefers the answer "because manholes are round". )

Larry Smith For extra credit: why are manhole covers in Nashua NH triangular? (correct answer: they were designed by the same guy who designed the triangular ones in New York City. What? You haven't noticed any triangular manhole covers in NYC? No surprise, they've all been replaced. And they are slowly being replaced in Nashua, too - but there are still a handful left, for those folks willing to cruise the streets of Nashua to see such historical plumbing trivia. The answer is: the tips are supported at three points and so the covers will not rock when cars drive over them.)

Boy, I really like that all the trivia is at the top of this page, instead of at the bottom where it might get overlooked. Anyway, manhole covers are (usually) round because:

 a) they are damn heavy, and round ones don't need to be finessed
    as much to make them drop into their seat.  this makes the
    manhole cover designer of Nashua seem particularly diabolical.
    also consider that with a triangular cover you run the oh-so-real
    risk of having a shifted manhole cover fall into the hole
    far enough to take your head off if you are in the position
    of having to shift one from the nether side.

 b) a round manhole and cover can sustain more damage and still
    serve effectively.

 c) they are damn heavy and round ones can be rolled if you are
    crazy enough to roll one.

 d) if you set your feet down, and hump a round manhole cover
    away from you, it will never land on your toes.

I will keep my round manhole cover, thank you!


But what about other "non-simplest" shapes that meet this criteria? This program draws one family of those non-simplest shapes.

To visualize what the family of shapes looks like, take an odd-side polygon, place on point of a compass on a vertex, the other on an opposite vertex, and draw the arc to the other opposite vertex. Repeat for all vertices.


 ##+##########################################################################
 #
 # Manhole.tcl
 # 
 # Draws N-sided manhole covers
 # by Keith Vetter
 #
 # Revisions:
 # KPV Mar 22, 1996 - initial revision
 # KPV Sep 22, 2002 - cleaned up for 8+
 #
 proc Init {} {
     global sz

     set sz(n) 3                                 ;# Number of sides
     set sz(s) 400                               ;# Size of canvas
     set sz(cx) [expr {$sz(s) / 2}]              ;# Canvas center point
     set sz(cy) $sz(cx)
     set sz(r) [expr {$sz(cx) * 3 / 4}]          ;# Radius
     set sz(rot) 0                               ;# How much to rotate by
     set sz(anim) 0                              ;# No animation yet
     set sz(after) ""                            ;# No after yet
     set sz(a) 0                                 ;# Interior angle to fill in
     set sz(colored) 1                           ;# Colored or solid

     set colors "cyan green magenta blue deepskyblue hotpink aquamarine "
     append colors $colors
     for {set i 0} {$i < 13} {incr i} {
         set sz($i) [lindex $colors $i]
     }

     canvas .c -width $sz(s) -height $sz(s) -bd 2 -relief raised
     .c config -bg black
     .c create oval [expr {$sz(cx)-$sz(r)}] [expr {$sz(cy)-$sz(r)}] \
         [expr {$sz(cx)+$sz(r)}] [expr {$sz(cy)+$sz(r)}] -tag circle \
         -fill [lindex [.c config -bg] 3]

     button .anim -text Animate -command {Animate 1}
     label .l -text "Sides: $sz(n)"
     scale .s -orient h -showvalue 0 -from 0 -to 5 -command MyScale

     pack .c -side top
     pack .anim -side right -expand 1
     pack .s .l -side bottom -expand 1
     wm resizable . 0 0
 }
 ##+##########################################################################
 # 
 # ngon
 # 
 # Compute the vertices for a n-gon
 # 
 proc ngon {n angle} {
     global v sz

     catch {unset v}
     set delta [expr {2*3.14159 / $n}]           ;# Angle of vertices on circle
     set sz(delta) [expr {360.0 / $n}]
     set sz(a) [expr {180.0 / $n}]               ;# Interior angle to fill in

     set angle [expr {$angle * 3.14159 / 180}]
     for {set i 0} {$i < $n} {incr i} {
         set a [expr {$angle + ($i*$delta)}]     ;# Angle in radians
         set v($i,x) [expr {$sz(cx) + $sz(r) * cos($a)}]
         set v($i,y) [expr {$sz(cy) + $sz(r) * sin($a)}]
         set i2 [expr {$i + $n}]
         set v($i2,x) $v($i,x)
         set v($i2,y) $v($i,y)

         lappend vertices $v($i,x) $v($i,y)
     }

     set n2 [expr {$n/2}]                        ;# Opposite angle
     set x [expr {$v(0,x) - $v($n2,x)}]
     set y [expr {$v(0,y) - $v($n2,y)}]
     set sz(d) [expr {sqrt($x*$x + $y*$y)}]      ;# Length of opposite side


     for {set i 0} {$i < $n} {incr i} {
         set v($i,bb) [list [expr {$v($i,x)-$sz(d)}] [expr {$v($i,y)+$sz(d)}] \
                           [expr {$v($i,x)+$sz(d)}] [expr {$v($i,y)-$sz(d)}]]

         set i2 [expr {$i + 1}]
         set n2 [expr {($i + ($sz(n) / 2) + 1) % $sz(n)}]
         set xy [list $sz(cx) $sz(cy) $v($i,x) $v($i,y) $v($i2,x) $v($i2,y)]
         .c create poly $xy -fill $sz($n2) -outline $sz($n2) \
             -tag {poly poly_$i}
     }

     return $vertices
 }
 ##+##########################################################################
 # 
 # DrawPie
 # 
 # Draws a single pie slice for vertex which.
 # 
 proc DrawPie {which} {
     global v sz

     if {$which == 0} {
         set n2 [expr {$which + ($sz(n) / 2) + 1}] ;# Opposite angle
         set x [expr {$v($n2,x) - $v($which,x)}]
         set y [expr {-($v($n2,y) - $v($which,y))}]
         set a [expr {atan2( $y, $x) * 180 / 3.14159}]
         set sz(atan) $a
     } else {
         set a [set sz(atan) [expr {$sz(atan) - $sz(delta)}]]
     }

     eval .c create arc $v($which,bb) -start $a -extent $sz(a) -style chord \
         -fill $sz($which) -outline $sz($which) -tag {{pie pie_$which}}
 }
 ##+##########################################################################
 # 
 # DrawIt
 # 
 # Draws the n-side manhole cover w/ sz(n) sides at angle sz(rot).
 # 
 proc DrawIt {} {
     global sz

     .c delete pie poly
     ngon $sz(n) $sz(rot)                        ;# Get vertices for this angle
     for {set i 0} {$i < $sz(n)} {incr i} {      ;# Draw the pie slices
         DrawPie $i
     }
     update
 }
 ##+##########################################################################
 # 
 # Animate
 # 
 # Draw the figure rotated by a small amount, then if animation is on,
 # it schedules itself to be run again in the near future.
 # 
 proc Animate {toggle} {
     global sz

     if {$toggle} {                              ;# On/off toggle
         set sz(anim) [expr {1 - $sz(anim)}]     ;# Toggle to flag
         if {$sz(anim)} {set relief sunken} {set relief raised}
         .anim config -relief $relief
     }

     if $sz(anim) {                              ;# Are we animating???
         incr sz(rot) 3                          ;# Rotate a bit
         DrawIt                                  ;# Redraw it

         after 1 {Animate 0}                    ;# Rerun in the future
     }
 }
 ##+##########################################################################
 # 
 # MyScale
 # 
 # Command called when scale gets a new value
 # 
 proc MyScale {v} {
     set ::sz(n) [expr {$v*2+3}]
     .l config -text "Sides: $::sz(n)"
     DrawIt
 }
 ################################################################
 ################################################################
 ################################################################
 Init
 DrawIt

Category Graphics