Filling the Gaps Between Eight Buried Detectors
You deploy eight radon detectors in a 200-metre grid and wait a week. Now you have eight numbers representing becquerels per cubic metre at eight specific points. What you want is a continuous surface—a map showing radon concentration everywhere, not just where you buried a detector.
The classic solution is inverse distance weighting. The idea: any unknown point’s value is the weighted average of all known points, where the weight is inversely proportional to distance. Closer measurements matter more. A point 10 metres from a detector gets 100× more influence than a point 100 metres away (1/10² vs 1/100², using the common power of 2).
function idw(points, [x, y], power = 2) {
let weightedSum = 0, totalWeight = 0;
for (const p of points) {
const dist = Math.sqrt((x - p.x) ** 2 + (y - p.y) ** 2);
if (dist === 0) return p.value;
const weight = 1 / (dist ** power);
weightedSum += p.value * weight;
totalWeight += weight;
}
return weightedSum / totalWeight;
}
const samples = [{x:0,y:0,value:120}, {x:100,y:0,value:85}, {x:50,y:50,value:200}];
console.log(idw(samples, [25, 25])); // 153.2
idw(Points, {X, Y}, Power) ->
{WeightedSum, TotalWeight} = lists:foldl(fun({Px, Py, Value}, {WS, TW}) ->
Dist = math:sqrt(math:pow(X - Px, 2) + math:pow(Y - Py, 2)),
Weight = 1 / math:pow(Dist, Power),
{WS + Value * Weight, TW + Weight}
end, {0, 0}, Points),
WeightedSum / TotalWeight.
The power parameter controls how quickly influence drops with distance. Set it to 1 and distant points still matter; set it to 3 and you get sharp boundaries around each sample. Most GIS tools default to 2 as a compromise between smooth gradients and local detail. The algorithm has no concept of barriers—it doesn’t know that a granite outcrop stops radon diffusion—so you get phantom halos around high readings. But for a first-pass map from eight detectors, it works.