lib/sphere/positions.js
function interpolate(f1_φ, f1_λ, f2_φ, f2_λ, d, buf) {

  for (var i = 1; i < d; i += 1) {

    let f = i / d,
        Δ = distance(f1_φ, f1_λ, f2_φ, f2_λ);

    let A = sin((1 - f) * Δ) / sin(Δ),
        B = sin(f * Δ) / sin(Δ);

    let x = A * cos(f1_φ) * cos(f1_λ) + B * cos(f2_φ) * cos(f2_λ),
        z = A * cos(f1_φ) * sin(f1_λ) + B * cos(f2_φ) * sin(f2_λ),
        y = A * sin(f1_φ) + B * sin(f2_φ);

    let φ = atan2(y, sqrt(pow(x, 2) + pow(z, 2))),
        λ = atan2(z, x);

    buf[2 * (i - 1) + 0] = φ;
    buf[2 * (i - 1) + 1] = λ;

  }

}
function interpolate(f1_φ, f1_λ, f2_φ, f2_λ, d, buf) {

  for (var i = 1; i < d; i += 1) {

    let f = i / d,
        Δ = distance(f1_φ, f1_λ, f2_φ, f2_λ);

    let A = sin((1 - f) * Δ) / sin(Δ),
        B = sin(f * Δ) / sin(Δ);

    let x = A * cos(f1_φ) * cos(f1_λ) + B * cos(f2_φ) * cos(f2_λ),
        z = A * cos(f1_φ) * sin(f1_λ) + B * cos(f2_φ) * sin(f2_λ),
        y = A * sin(f1_φ) + B * sin(f2_φ);

    let φ = atan2(y, sqrt(pow(x, 2) + pow(z, 2))),
        λ = atan2(z, x);

    buf[2 * (i - 1) + 0] = φ;
    buf[2 * (i - 1) + 1] = λ;

  }

}
Populates buffer `buf` with `d - 1` evenly-spaced positions between two points.

@param {number} f1_φ - first position's φ value
@param {number} f1_λ - first position's λ value

@param {number} f2_φ - second position's φ value
@param {number} f2_λ - second position's λ value

@param {number} d - number of times to divide the segment between the positions
@param {ArrayBuffer} buf - buffer in which to store the result