Version 9 of hypot

Updated 2008-04-23 04:16:11 by andy

Purpose: Discuss the math function hypot.


The call,

    [expr { hypot( $x, $y ) }]

returns the length of the hypotenuse of a right triangle when the length of the legs are $x and $y. It is equivalent to

    [expr { sqrt( $x * $x + $y * $y ) }]

except that it can handle cases where $x or $y are extremely large or extremely small without getting overflow or underflow.

In cases where there are no problems with being very close to the limits of the underlying double representation and you don't actually need the distance itself (e.g. in circle intersection testing and checking to see if one point is close enough to another) it is often quicker to work with the square of the length of the hypotenuse and avoid the expensive square root operation. I do not know how this ranks up with the additional overheads of math in Tcl though. DKF


The most common use of hypot is in Converting between rectangular and polar co-ordinates.


hypot is also available in Tclx.


GPS The hypotenuse is very useful for drawing lines pixel by pixel. For example:

 #Copyright 2003 George Peter Staplin
 #You may use this under the same terms as Tcl.
 proc draw.line.on.image {img x1 y1 x2 y2 color} {
        set xDiff [expr {$x2 - $x1}]
        set yDiff [expr {$y2 - $y1}]

        set numPixels [expr {hypot($xDiff,$yDiff)}]
        set xRatio    [expr {$xDiff / $numPixels}]
        set yRatio    [expr {$yDiff / $numPixels}]

        for {set p 0} {$p < $numPixels} {incr p} {
                set x [expr {round($xRatio * $p) + $x1}]
                set y [expr {round($yRatio * $p) + $y1}]
                $img put $color -to $x $y [expr {$x + 1}] [expr {$y + 1}]
        }        
 }

 proc main {} {
        set img [image create photo -width 300 -height 300]
        draw.line.on.image $img 10 10 100 100 green
        draw.line.on.image $img 50 20  50 200 blue
        draw.line.on.image $img 40 50 300  50 maroon

        pack [label .l -image $img]
 }
 main 

Basically the display is like a right triangle. The left edge of the window is the side opposite the hypotenuse, while the bottom edge is the base side. Therefore using the Pythagorean Theorem which says that the length of the hypotenuse is the square root of: (x * x) + (y * y) we can find the number of pixels between the two points. If you have another use for the hypot function (perhaps for 3D) then I (GPS) would like to see it.


AMG: Feature request! Why not extend hypot() to take any number of arguments? In general, hypot() is the square root of the sum of the squares of the arguments. Right now it only supports two arguments, making it painful to use in 3D and above. Single-argument hypot() should work the same as abs(), and zero-argument hypot() should return 0.

Lars H: Reasonable idea, although I'm not sure I'd count

  expr {hypot(hypot($x,$y),$z)}

as particularly painful.

AMG: True, I had that in mind, but I still find it painful to think that this code is harder to write, harder to read, and takes longer to execute, in comparison to the way it "should" be. It's gross to contemplate the fact that internally numbers are being square root'ed and then immediately squared again. Also it turns out that this is more efficient:

 expr {sqrt($x * $x + $y * $y + $z * $z)}

According to [time], the sqrt method takes 2.63027 microseconds on my machine, and the double hypot takes 3.64441 microseconds, which is 38.6% longer.