UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

51 lines (41 loc) 1.53 kB
import { assert } from "../assert.js"; /** * Computes associated Legendre Polynomial P(l,m,x) at x * Useful in Spherical Harmonics coefficient computation * @param {number} l band * @param {number} m * @param {number} x must be between 0 and 1 * @returns {number} */ export function compute_legendre_polynomial(l, m, x) { assert.lessThanOrEqual(x,1,'only valid for X <= 1'); // TODO we might be able to do better, see https://github.com/halueda/wavy-orbitals/blob/fe738b0f8de8783cb7886d2c6ee616c2befb363b/legendre.js#L16 // based on code from https://github.com/jan-van-bergen/SphericalHarmonicLighting/blob/2b214b3451859ded07ea4e41fb2aa8d2a44ab579/SphericalHarmonicsLighting/SphericalHarmonics.cpp#L61 // Apply rule 2; P m m let pmm = 1.0; if (m > 0) { const somx2 = Math.sqrt((1.0 - x) * (1.0 + x)); let fact = 1.0; for (let i = 1; i <= m; i++) { pmm *= (-fact) * somx2; fact += 2.0; } } // If l is equal to m then P m m is already the right answer if (l === m) { return pmm; } // Use rule 3 once let pmmp1 = x * (2.0 * m + 1.0) * pmm; if (l === m + 1) { return pmmp1; } // Iterate rule 1 until the right answer is found let pll = 0.0; for (let ll = m + 2; ll <= l; ll++) { pll = ((2.0 * ll - 1.0) * x * pmmp1 - (ll + m - 1.0) * pmm) / (ll - m); pmm = pmmp1; pmmp1 = pll; } return pll; }