← Natura·Docs/Modules/Source

refraction-test.js

45 lines · in natura-src-1.0.0.zip as natura/refraction-test.js · a test

// refraction-test.js -- assertions for ATMOSPHERIC REFRACTION / MIRAGE. Run: node refraction-test.js
const N = require('./natura.js');
const { makeRefraction } = require('./refraction.js');
const { World, UNITS } = N;
const DAY = UNITS.DAY;
let pass = 0, fail = 0;
const ok = (c, m) => { if (c) pass++; else { fail++; console.log('  FAIL: ' + m); } };
const settle = (cfg) => { const w = World({ seed: 1, systems: [makeRefraction(cfg)] }); w.step(DAY); return w.fields().refraction; };

console.log('refraction assertions:');

// 1. NO GRADIENT -> NO MIRAGE (still air, ground and air the same temperature: light runs straight)
{
  const f = settle({ groundTemp: 20, airTemp: 20 });
  ok(f.mirageType === 'none' && Math.abs(f.bend) < 1e-9, 'an even air column bends nothing (mirageType ' + f.mirageType + ')');
}

// 2. HOT GROUND -> INFERIOR MIRAGE -- rays curve up, a distant object SINKS and an inverted image pools below (the road-water)
{
  const f = settle({ groundTemp: 55, airTemp: 25, distance: 1.2 });
  ok(f.mirageType === 'inferior' && f.inverted && f.apparent(0.05) < 0.05, 'a superheated ground makes the INFERIOR mirage (the desert water); a thing at 0.05 appears at ' + f.apparent(0.05).toFixed(4));
}

// 3. INVERSION (warm air over cold surface) -> SUPERIOR mirage / LOOMING -- distant things rise and stack
{
  const f = settle({ groundTemp: 4, airTemp: 22, distance: 1.2 });
  ok((f.mirageType === 'looming' || f.mirageType === 'fata-morgana') && f.apparent(0.02) > 0.02, 'a temperature INVERSION makes things LOOM (superior mirage): 0.02 appears raised to ' + f.apparent(0.02).toFixed(4));
}

// 4. STRENGTH -- a bigger anomaly (or a longer sight-line) bends the light more, tipping looming into a Fata Morgana
{
  const mild = settle({ groundTemp: 12, airTemp: 20, distance: 1 });
  const strong = settle({ groundTemp: 2, airTemp: 34, distance: 2 });
  ok(Math.abs(strong.bend) > Math.abs(mild.bend) && strong.mirageType === 'fata-morgana', 'a stronger inversion + longer view bends more, into a Fata Morgana (bend ' + mild.bend + ' -> ' + strong.bend + ')');
}

// 5. DETERMINISM / symmetry -- the inferior and superior cases are mirror images in the bend
{
  const hot = settle({ groundTemp: 40, airTemp: 20, distance: 1 });
  const cold = settle({ groundTemp: 0, airTemp: 20, distance: 1 });
  ok(Math.abs(hot.bend + cold.bend) < 1e-9 && hot.bend < 0 && cold.bend > 0, 'hot-ground and cold-ground bend oppositely and equally (' + hot.bend + ' vs ' + cold.bend + ')');
}

console.log(`\n${pass} passed, ${fail} failed`);
process.exit(fail ? 1 : 0);