Skip to content

Commit db61d92

Browse files
committed
Add Noise indexing.
This might be more intuitive with NumPy, and could replace all other forms of sampling.
1 parent 4de3606 commit db61d92

2 files changed

Lines changed: 56 additions & 0 deletions

File tree

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Added
1212
- Added `tcod.context.new` function.
1313
- Contexts now have CLI support.
1414
- You can now provide the window x,y position when making contexts.
15+
- `tcod.noise.Noise` instances can now be indexed to generate noise maps.
1516

1617
Changed
1718
- Using `libtcod 1.16.0-alpha.13`.

tcod/noise.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,61 @@ def get_point(
157157
"""
158158
return float(lib.NoiseGetSample(self._tdl_noise_c, (x, y, z, w)))
159159

160+
def __getitem__(self, indexes: Any) -> np.ndarray:
161+
"""Sample a noise map through NumPy indexing.
162+
163+
This follows NumPy's advanced indexing rules, but allows for floating
164+
point values.
165+
166+
.. versionadded:: 11.16
167+
"""
168+
if not isinstance(indexes, tuple):
169+
indexes = (indexes,)
170+
if len(indexes) > self.dimensions:
171+
raise IndexError(
172+
"This noise generator has %i dimensions, but was indexed with %i."
173+
% (self.dimensions, len(indexes))
174+
)
175+
indexes = np.broadcast_arrays(*indexes)
176+
c_input = [ffi.NULL, ffi.NULL, ffi.NULL, ffi.NULL]
177+
for i, index in enumerate(indexes):
178+
if index.dtype.type == np.object_:
179+
raise TypeError("Index arrays can not be of dtype np.object_.")
180+
indexes[i] = np.ascontiguousarray(index, dtype=np.float32)
181+
c_input[i] = ffi.from_buffer("float*", indexes[i])
182+
183+
out = np.empty(indexes[0].shape, dtype=np.float32)
184+
if self.implementation == SIMPLE:
185+
lib.TCOD_noise_get_vectorized(
186+
self.noise_c,
187+
self.algorithm,
188+
out.size,
189+
*c_input,
190+
ffi.from_buffer("float*", out),
191+
)
192+
elif self.implementation == SIMPLE:
193+
lib.TCOD_noise_get_fbm_vectorized(
194+
self.noise_c,
195+
self.algorithm,
196+
self.octaves,
197+
out.size,
198+
*c_input,
199+
ffi.from_buffer("float*", out),
200+
)
201+
elif self.implementation == TURBULENCE:
202+
lib.TCOD_noise_get_turbulence_vectorized(
203+
self.noise_c,
204+
self.algorithm,
205+
self.octaves,
206+
out.size,
207+
*c_input,
208+
ffi.from_buffer("float*", out),
209+
)
210+
else:
211+
raise TypeError("Unexpected %r" % self.implementation)
212+
213+
return out
214+
160215
def sample_mgrid(self, mgrid: np.ndarray) -> np.ndarray:
161216
"""Sample a mesh-grid array and return the result.
162217

0 commit comments

Comments
 (0)