Module: QuadSphere::Tangential

Defined in:
lib/quad_sphere/tangential.rb

Overview

Implements the tangential spherical cube projection.

In this projection, points on the sphere are projected from the centre of the sphere onto the six faces of an inscribed cube. Thus, the projection consists of six planar faces, each of which is a gnomonic projection of a portion of the sphere.

This module exists solely because the CSC projection is a distortion of the mapping produced by a tangential projection. Thus, the forward and inverse computations here are required, but they have been segregated on the oft chance that they could be useful on their own.

See Also:

Author:

  • Cesar Rincon

Class Method Summary collapse

Class Method Details

.forward(phi, theta) ⇒ Array

Computes the projection of a point on the surface of the sphere, given in spherical coordinates (φ,θ), to a point of cartesian coordinates (χ,ψ) on one of the six cube faces.

Parameters:

  • phi (Float)

    the φ angle in radians, from -π to π (or 0 to to 2π, if you like). This is the azimuth, or longitude (spherical, not geodetic).

  • theta (Float)

    the θ angle in radians, from -π/2 to π/2. This is the elevation, or latitude (spherical, not geodetic).

Returns:

  • (Array)

    an array of three elements: the identifier of the face (see constants in QuadSphere), the χ coordinate of the projected point, and the ψ coordinate of the projected point. Both coordinates will be in the range -1 to 1.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/quad_sphere/tangential.rb', line 54

def self.forward(phi, theta)
  # compute the direction cosines
  l = Math::cos(theta) * Math::cos(phi)
  m = Math::cos(theta) * Math::sin(phi)
  n = Math::sin(theta)

  # identify the face, and adjust our parameters.
  max, face = nil, -1
  [ n, l, m, -l, -m, -n ].each_with_index do |v, i|
    max, face = v, i if max.nil? || v > max
  end

  xi, eta, zeta = FORWARD_PARAMETERS[face].call(l,m,n)

  # Compute χ and ψ.
  # XXX - This will blow up if ζ is zero... can it happen?
  chi = xi / zeta
  psi = eta / zeta

  # Out of curiosity: why does Calabretta do this?
  # x = phi_c + Math::PI/4 * chi
  # y = theta_c + Math::PI/4 * psi

  [face,chi,psi]
end

.inverse(face, chi, psi) ⇒ Array

Computes the projection of a point at cartesian coordinates (χ,ψ) on one of the six cube faces, to a point at spherical coordinates (φ,θ) on the surface of the sphere.

Note that, while the projection is reversible for points within each of the cube faces, it is not necessarily so for points located exactly on the edges. This is because points on the edges of the cube are shared amongst two or even three faces, and the forward projection may return an alternative mapping to a neighbouring face.

Parameters:

  • face (Integer)

    the identifier of the cube face; see constants in QuadSphere.

  • chi (Float)

    the χ coordinate of the point within the face, from -1.0 to 1.0.

  • psi (Float)

    the ψ coordinate of the point within the face, from -1.0 to 1.0.

Returns:

  • (Array)

    an array of two elements: the φ angle in radians (azimuth or longitude - spherical, not geodetic), from -π to π; and the θ angle in radians, from -π/2 to π/2 (elevation or latitude - spherical, not geodetic).



119
120
121
122
123
124
125
126
127
128
# File 'lib/quad_sphere/tangential.rb', line 119

def self.inverse(face, chi, psi)
  zeta = 1.0 / Math.sqrt(1.0 + chi**2 + psi**2)
  xi = chi*zeta
  eta = psi*zeta

  # get the direction cosines
  l, m, n = INVERSE_PARAMETERS[face].call(xi, eta, zeta)

  [ Math.atan2(m,l), Math.asin(n) ] # φ,θ
end