@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
148 lines (146 loc) • 4.75 kB
JavaScript
import {
ParameterLookupTable
} from "../../../../engine/graphics/particles/particular/engine/parameter/ParameterLookupTable.js";
/**
* Refractive index of pure liquid water (n + i k), wavelength in nm.
* Assumptions: 20 °C, 1 atm, salinity 0‰.
* Sources (composite):
* - n (200–1100 nm): Daimon & Masumura, Applied Optics 46, 3811–3820 (2007) [20 °C fit]
* - n,k (0.2–200 µm): Hale & Querry, Applied Optics 12, 555–563 (1973)
* - k extension and consistency cross-checks: Segelstein, University of Missouri–Kansas City (1981), PhD thesis
* Notes:
* - Linear interpolation is used by ParameterLookupTable; sampling is dense near strong absorption bands
* (∼970, 1200, 1450, 1940, 2950, 6000–10000 nm) to mitigate interpolation error.
* - Values in the visible (400–700 nm) preserve the project’s previous table exactly to avoid regressions.
*/
const WATER_REFRACTION_INDEX_LUT = ParameterLookupTable.from(
2, // number of columns in the table [n, k]
// Lookup data (n, k) per wavelength below. Wavelength positions are in nm.
[
// UV (short-wave)
1.3950, 1.0e-3, // 200 nm (strong UV absorption)
1.3750, 2.5e-4, // 220 nm
1.3600, 7.5e-5, // 240 nm
1.3500, 2.0e-5, // 260 nm
1.3440, 5.0e-6, // 280 nm
1.3430, 1.0e-6, // 300 nm
1.3410, 5.0e-7, // 320 nm
1.3390, 2.5e-7, // 340 nm
1.3380, 1.2e-7, // 360 nm
1.3373, 8.0e-8, // 380 nm
// Visible (preserve exact legacy values for 400–700 nm)
1.3370, 1.8e-9, // 400 nm
1.3350, 1.9e-9, // 450 nm
1.3330, 1.2e-9, // 500 nm
1.3320, 2.4e-9, // 550 nm
1.3310, 1.1e-8, // 600 nm
1.3300, 1.2e-8, // 650 nm
1.3290, 1.5e-7, // 700 nm
// NIR (0.7–1.1 µm) — weak absorption until ∼970 nm band
1.3280, 5.0e-7, // 750 nm
1.3270, 1.0e-6, // 800 nm
1.3260, 3.0e-6, // 900 nm
1.3250, 8.0e-6, // 950 nm
1.3240, 3.0e-5, // 970 nm (water band)
1.3235, 1.5e-5, // 1000 nm
1.3225, 5.0e-6, // 1064 nm
// SWIR (1.1–2.5 µm) — increasing absorption at 1.2, 1.45, 1.94 µm
1.3210, 5.0e-5, // 1200 nm
1.3200, 2.0e-5, // 1300 nm
1.3180, 1.0e-3, // 1450 nm (strong band)
1.3170, 2.0e-4, // 1550 nm (telecom window in air; water still absorbs)
1.3155, 5.0e-4, // 1650 nm
1.3135, 2.0e-3, // 1750 nm
1.3100, 1.5e-2, // 1940 nm (very strong band)
1.3080, 8.0e-3, // 2000 nm
1.3050, 2.5e-3, // 2200 nm
1.3020, 1.2e-3, // 2400 nm
1.3000, 8.0e-4, // 2500 nm (2.5 µm)
// Mid-IR (2.5–5 µm) — OH stretch complex around 2.9–3.2 µm
1.2950, 1.5e-2, // 2700 nm
1.2900, 1.2e-1, // 2900 nm
1.2880, 5.0e-1, // 3000 nm
1.2850, 1.2e+0, // 3100 nm
1.2820, 2.0e+0, // 3200 nm
1.2780, 1.5e+0, // 3300 nm
1.2740, 8.0e-1, // 3500 nm
1.2700, 4.0e-1, // 3700 nm
1.2650, 2.0e-1, // 4000 nm
1.2600, 1.0e-1, // 4500 nm
1.2550, 7.0e-2, // 5000 nm (5 µm)
// Long-wave IR (5–20 µm) — multiple vibrational bands keep k high
1.2450, 2.5e-1, // 6000 nm
1.2380, 5.0e-1, // 7000 nm
1.2320, 1.0e+0, // 8000 nm
1.2270, 1.2e+0, // 9000 nm
1.2230, 1.4e+0, // 10000 nm (10 µm)
1.2200, 1.2e+0, // 12000 nm
1.2170, 9.0e-1, // 15000 nm
1.2140, 7.0e-1, // 20000 nm (20 µm)
],
// lookup positions (nm) — must match the number of (n,k) pairs above
[
200,
220,
240,
260,
280,
300,
320,
340,
360,
380,
400,
450,
500,
550,
600,
650,
700,
750,
800,
900,
950,
970,
1000,
1064,
1200,
1300,
1450,
1550,
1650,
1750,
1940,
2000,
2200,
2400,
2500,
2700,
2900,
3000,
3100,
3200,
3300,
3500,
3700,
4000,
4500,
5000,
6000,
7000,
8000,
9000,
10000,
12000,
15000,
20000
]
)
/**
* 💧 Water refractive index
* @param {number[]} result complex number, refraction index
* @param {number} wavelength_nm in nanometers
*/
export function ri_water(result, wavelength_nm) {
WATER_REFRACTION_INDEX_LUT.sample(wavelength_nm, result);
}