function sphere_basis, north, prime_meridian=prime_meridian ; $Id: sphere_basis.pro 7092 2010-01-12 20:18:45Z jimm $ ;; ;; Returns the rectangular coordinate vectors x,y,z, in the standard ;; basis from a spherical coordinate system with north as +z. The ;; return value is a 3x3 array with x,y,z coordinate vectors in the ;; rows of the array. ;; ;; The standard basis is the one used for the north and prime_meridian ;; vectors. ;; ;; x,y,z form a right-handed coordinate system. ;; ;; The spherical coordinate system equatorial phase 0 reference (+x) ;; is determined by prime_meridian. Think of +x as 0 longitude or 0 ;; azimuth. ;; ;; +x is taken in the plane of north and prime_meridian with ;; dot(+x,prime_meridian) > 0. ;; ;; When prime_meridian is not given or is parallel to north, the ;; default for the equatorial phase is chosen such that +y is in the ;; "northerly" [1,0,0] direction. Specifically: ;; ;; +z = north, +y is in the (north, [1,0,0]) plane with dot(+y,[1,0,0]) > 0. ;; ;; If north is parallel to [1,0,0] and prime_meridian is not given or ;; is parallel to north then the standard coordinate system is used. ;; ;; Alternatively, prime_meridian can be a second row of north, ;; i.e. north can be size 3x2. ;; Standard basis +z z_d = [0., 0., 1.] if (n_elements(north(*, 0)) ne 3) then begin message, "North must be a 3 element vector" return, 0 endif if n_elements(north(0, *)) eq 2 and n_elements(prime_meridian) eq 0 then begin prime_meridian = north(*, 1) endif ;; x1, y1, z1 are the rectangular coordinates in the standard basis of ;; spherical system. ;; ;; Make into a row vector. z1 = reform(north(*, 0), 3) z1 = z1/norm(z1) if n_elements(prime_meridian) ne 0 then begin if n_elements(prime_meridian) ne 3 then begin message, "Prime_meridian should be size 3" return, 0 endif x1 = prime_meridian - dot(prime_meridian, z1)*z1 vx = norm(x1) if vx eq 0 then begin message, "Prime_meridian is along same direction as north." return, 0 endif x1 = x1/vx y1 = crossp(z1, x1) endif else begin ;; y1 is in the northerly direction y1 = z_d - dot(z_d, z1)*z1 vy = norm(y1) if vy eq 0 then begin ;; Canonical coordinates x1 = [1., 0., 0.] y1 = crossp(z1, x1) endif else begin y1 = y1/vy ;; choose x1 to form a right-hand coordinate system for the pinhole x1 = crossp(y1, z1) endelse endelse ;; The coordinate vectors form the _rows_ of the transformation matrix. coord = float([[x1],[y1],[z1]]) return, coord end