@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
46 lines (38 loc) • 1.42 kB
JavaScript
import { assert } from "../../../assert.js";
import { clamp01 } from "../../../math/clamp01.js";
/**
*
* @param {number} a
* @param {number} b
* @return {number}
*/
function multiply_add_fraction(a, b) {
const ab = a * b;
return ab - Math.floor(ab);
}
const PHI = Math.sqrt(5) * 0.5 + 0.5;
/**
* Generate a spherical fibonacci point
* The points go from z = +1 down to z = -1 in a spiral. To generate samples on the +z hemisphere, just stop before i > N/2.
*
* @see http://lgdv.cs.fau.de/publications/publication/Pub.2015.tech.IMMD.IMMD9.spheri/
*
* @param {number[]|Float32Array} output 3d point
* @param {number} output_offset
* @param {number} i index of a point, from 0 to n-1
* @param {number} n total number of points
*/
export function sphere_fibonacci_point(output, output_offset, i, n) {
assert.isNonNegativeInteger(i, 'i');
assert.isNonNegativeInteger(n, 'n');
assert.isNonNegativeInteger(output_offset, 'output_offset');
const phi = 2 * Math.PI * multiply_add_fraction(i, PHI - 1);
const cosTheta = 1.0 - (2.0 * i + 1.0) * (1.0 / n);
const sinTheta = Math.sqrt(clamp01(1.0 - cosTheta * cosTheta));
const x = Math.cos(phi) * sinTheta;
const y = Math.sin(phi) * sinTheta;
const z = cosTheta;
output[output_offset] = x;
output[output_offset + 1] = y;
output[output_offset + 2] = z;
}