Isotope.NoiseMap (Isotope v0.5.0)

Copy Markdown View Source

A compact representation of a 2D noise map backed by a flat binary of little-endian f32 values in row-major order.

Memory Layout

The data field is a binary where each value is a 32-bit float in little-endian byte order. Values are stored row by row (row-major). A 100x100 map uses exactly 40,000 bytes (~40 KB), compared to ~3.2 MB for the equivalent nested Elixir list.

Accessing Values

{:ok, noise} = Isotope.Noise.new()
nm = Isotope.Noise.noise_map(noise, {100, 100})

# Single value at column 10, row 5
Isotope.NoiseMap.get(nm, 10, 5)

# Entire row as a list of floats
Isotope.NoiseMap.row(nm, 0)

# Convert to nested list (for compatibility or serialization)
Isotope.NoiseMap.to_list(nm)

# Dimensions
{width, height} = Isotope.NoiseMap.size(nm)

Enumerable

The Enumerable protocol is implemented, iterating over rows (each row is a [float()]). This means standard Enum functions work directly:

# Average value per row
Enum.map(nm, fn row -> Enum.sum(row) / length(row) end)

# Find the row with the highest peak
Enum.max_by(nm, fn row -> Enum.max(row) end)

# First 5 rows
Enum.take(nm, 5)

Migration from [[float()]]

If you have code that expects nested lists, use Isotope.NoiseMap.to_list/1:

nm = Isotope.Noise.noise_map(noise, {100, 100})
nested_list = Isotope.NoiseMap.to_list(nm)

Summary

Functions

Returns the noise value at column x, row y.

Returns row y as a list of floats.

Returns {width, height} of the noise map.

Converts the noise map to a nested list [[float()]] (list of rows).

Types

t()

@type t() :: %Isotope.NoiseMap{
  data: binary(),
  height: non_neg_integer(),
  width: non_neg_integer()
}

Functions

get(noise_map, x, y)

@spec get(t(), non_neg_integer(), non_neg_integer()) :: float()

Returns the noise value at column x, row y.

Raises ArgumentError if the coordinates are out of bounds.

iex> nm = %Isotope.NoiseMap{data: <<1.0::float-little-32, 2.0::float-little-32, 3.0::float-little-32, 4.0::float-little-32>>, width: 2, height: 2}
iex> Isotope.NoiseMap.get(nm, 1, 0)
2.0

row(noise_map, y)

@spec row(t(), non_neg_integer()) :: [float()]

Returns row y as a list of floats.

Raises ArgumentError if the row index is out of bounds.

iex> nm = %Isotope.NoiseMap{data: <<1.0::float-little-32, 2.0::float-little-32, 3.0::float-little-32, 4.0::float-little-32>>, width: 2, height: 2}
iex> Isotope.NoiseMap.row(nm, 0)
[1.0, 2.0]

size(noise_map)

@spec size(t()) :: {non_neg_integer(), non_neg_integer()}

Returns {width, height} of the noise map.

iex> nm = %Isotope.NoiseMap{data: <<0::128>>, width: 2, height: 2}
iex> Isotope.NoiseMap.size(nm)
{2, 2}

to_list(nm)

@spec to_list(t()) :: [[float()]]

Converts the noise map to a nested list [[float()]] (list of rows).

iex> nm = %Isotope.NoiseMap{data: <<1.0::float-little-32, 2.0::float-little-32, 3.0::float-little-32, 4.0::float-little-32>>, width: 2, height: 2}
iex> Isotope.NoiseMap.to_list(nm)
[[1.0, 2.0], [3.0, 4.0]]