Updated 2012-05-18 01:12:05 by RLE

Purpose: Show how to convert between rectangular and polar co-ordinates in Tcl.

If you have rectangular co-ordinates $x and $y, and you need polar co-ordinates $r and $theta, you can use the following:
 proc rect_to_polar {x y} {
     list [expr {hypot($y, $x)}]\
          [expr {atan2($y, $x)}]

 lassign [rect_to_polar $x $y] r theta 

Note the use of hypot and atan2 in the code above. These functions are much more robust than any corresponding code using atan and sqrt.

If you have polar co-ordinates $r and $theta, and you need rectangular co-ordinates $x and $y, you can use the following:
 proc polar_to_rect {r theta} {
     list [expr {$r * cos($theta)}]\
          [expr {$r * sin($theta)}]

 lassign [polar_to_rect $r $theta] x y

AM Here is the conversion between rectangular and spherical coordinates:
 proc rect_to_spherical {x y z} {
     list [set rad [expr {hypot($x, hypot($y, $z))}]] [expr {atan2($y,$x)}] [expr {acos($z/($rad+1.0e-20))}]

 proc spherical_to_rect {rad phi theta} {
     list [expr {$rad * cos($phi) * sin($theta)}] [expr {$rad * sin($phi) * sin($theta)}] [expr {$rad * cos($theta)}]

(where phi is the angle in the x-y plane, and theta is the angle from the z axis.)

AMG: As documented on hypot, the other day I found that hypot($x,hypot($y,$z)) takes 38.6% longer than sqrt($x*$x+$y*$y+$z*$z) but is much less susceptible to under/overflow for very small or large input values.

KPV - Hey, I'll take up the hard task of converting cylindrical (r, theta, z) to rectangular (x, y, z).
 proc rect_to_cylindrical {x y z} {
    list {*}[rect_to_polar $x $y] $z
 proc cylindrical_to_rect {r theta z} {
    list {*}[polar_to_rect $r $theta] $z

AM Anyone wanting to add the conversions for the other orthogonal coordinate systems?