[][src]Function cdshealpix::unproj

pub fn unproj(x: f64, y: f64) -> (f64, f64)

Unproject the given HEALPix projected points.
This unprojection is multi-purpose in the sense that:

  • if input x in [-8, 0[, then output lon in [-2pi, 0]
  • if input x in [ 0, 8], then output lon in [0, 2pi]
  • output lat always in [-pi/2, pi/2]

Inputs

  • x the projected coordinate along the x-axis, supports positive and negative reasonably large values with a naive approach (no Cody-Waite nor Payne Hanek range reduction).
  • y the projected coordinate along te x-axis, must be in [-2, 2]

Output

  • (lon, lat) in radians, the position on the unit sphere whose projected coordinates are the input coordinates (x, y).
  • if x <= 0, then lon in [-2pi, 0];
  • else if x >= 0, the lon in [0, 2pi]
  • lat always in [-pi/2, pi/2].

Panics

If y not in [-2, 2], this method panics.

Examples

To obtain the WCS un-projection (see Calabretta2007), you can write:

use cdshealpix::{HALF_PI, FOUR_OVER_PI, unproj};
use std::f64::consts::{PI};

let x = 2.1f64;
let y = 0.36f64;

let (mut lon, mut lat) = unproj(x * FOUR_OVER_PI, y * FOUR_OVER_PI);
if lon < 0f64 {
    lon += 2f64 * PI;
}

assert!(0f64 <= lon && lon <= 2f64 * PI);
assert!(-HALF_PI <= lat && lat <= HALF_PI);

Other test example:

use cdshealpix::{TRANSITION_LATITUDE, HALF_PI, PI_OVER_FOUR, proj, unproj};

fn dist(p1: (f64, f64), p2: (f64, f64)) -> f64 {
    let sindlon = f64::sin(0.5 * (p2.0 - p1.0));
    let sindlat = f64::sin(0.5 * (p2.1 - p1.1));
    2f64 * f64::asin(f64::sqrt(sindlat * sindlat + p1.1.cos() * p2.1.cos() * sindlon * sindlon))
}
 
let points: [(f64, f64); 40] = [
    (0.0 * HALF_PI, 0.0),
    (1.0 * HALF_PI, TRANSITION_LATITUDE),
    (2.0 * HALF_PI, TRANSITION_LATITUDE),
    (3.0 * HALF_PI, TRANSITION_LATITUDE),
    (4.0 * HALF_PI, TRANSITION_LATITUDE),
    (0.0 * HALF_PI + PI_OVER_FOUR, HALF_PI),
    (1.0 * HALF_PI + PI_OVER_FOUR, HALF_PI),
    (2.0 * HALF_PI + PI_OVER_FOUR, HALF_PI),
    (3.0 * HALF_PI + PI_OVER_FOUR, HALF_PI),
    (4.0 * HALF_PI + PI_OVER_FOUR, HALF_PI),
    (0.0 * HALF_PI, 0.0),
    (1.0 * HALF_PI, -TRANSITION_LATITUDE),
    (2.0 * HALF_PI, -TRANSITION_LATITUDE),
    (3.0 * HALF_PI, -TRANSITION_LATITUDE),
    (4.0 * HALF_PI, -TRANSITION_LATITUDE),
    (0.0 * HALF_PI + PI_OVER_FOUR, -HALF_PI),
    (1.0 * HALF_PI + PI_OVER_FOUR, -HALF_PI),
    (2.0 * HALF_PI + PI_OVER_FOUR, -HALF_PI),
    (3.0 * HALF_PI + PI_OVER_FOUR, -HALF_PI),
    (4.0 * HALF_PI + PI_OVER_FOUR, -HALF_PI),
    (-0.0 * HALF_PI, 0.0),
    (-1.0 * HALF_PI, TRANSITION_LATITUDE),
    (-2.0 * HALF_PI, TRANSITION_LATITUDE),
    (-3.0 * HALF_PI, TRANSITION_LATITUDE),
    (-4.0 * HALF_PI, TRANSITION_LATITUDE),
    (-0.0 * HALF_PI + PI_OVER_FOUR, HALF_PI),
    (-1.0 * HALF_PI + PI_OVER_FOUR, HALF_PI),
    (-2.0 * HALF_PI + PI_OVER_FOUR, HALF_PI),
    (-3.0 * HALF_PI + PI_OVER_FOUR, HALF_PI),
    (-4.0 * HALF_PI + PI_OVER_FOUR, HALF_PI),
    (-0.0 * HALF_PI, 0.0),
    (-1.0 * HALF_PI, -TRANSITION_LATITUDE),
    (-2.0 * HALF_PI, -TRANSITION_LATITUDE),
    (-3.0 * HALF_PI, -TRANSITION_LATITUDE),
    (-4.0 * HALF_PI, -TRANSITION_LATITUDE),
    (-0.0 * HALF_PI + PI_OVER_FOUR, -HALF_PI),
    (-1.0 * HALF_PI + PI_OVER_FOUR, -HALF_PI),
    (-2.0 * HALF_PI + PI_OVER_FOUR, -HALF_PI),
    (-3.0 * HALF_PI + PI_OVER_FOUR, -HALF_PI),
    (-4.0 * HALF_PI + PI_OVER_FOUR, -HALF_PI)
];
 
for (lon, lat) in points.iter() {
    let (x, y): (f64, f64) = proj(*lon, *lat);
    assert!(dist((*lon, *lat), unproj(x, y)) < 1e-15);
}