Skip to content

Commit 174c684

Browse files
committed
Add tcod.noise.grid function.
Update noise docs to use helper function.
1 parent be69c34 commit 174c684

File tree

2 files changed

+79
-27
lines changed

2 files changed

+79
-27
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Unreleased
1010
------------------
1111
Added
1212
- Added `tcod.noise.Algorithm` and `tcod.noise.Implementation` enums.
13+
- Added `tcod.noise.grid` helper function.
1314

1415
Deprecated
1516
- The non-enum noise implementation names have been deprecated.

tcod/noise.py

Lines changed: 78 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,34 @@
55
66
Example::
77
8-
import numpy as np
9-
import tcod
10-
11-
noise = tcod.noise.Noise(
12-
dimensions=2,
13-
algorithm=tcod.noise.Algorithm.SIMPLEX,
14-
implementation=tcod.noise.Implementation.TURBULENCE,
15-
hurst=0.5,
16-
lacunarity=2.0,
17-
octaves=4,
18-
seed=None,
19-
)
20-
21-
# Create a 5x5 open multi-dimensional mesh-grid.
22-
ogrid = [np.arange(5, dtype=np.float32),
23-
np.arange(5, dtype=np.float32)]
24-
print(ogrid)
25-
26-
# Scale the grid.
27-
ogrid[0] *= 0.25
28-
ogrid[1] *= 0.25
29-
30-
# Return the sampled noise from this grid of points.
31-
samples = noise.sample_ogrid(ogrid)
32-
print(samples)
33-
"""
8+
>>> import numpy as np
9+
>>> import tcod
10+
>>> noise = tcod.noise.Noise(
11+
... dimensions=2,
12+
... algorithm=tcod.noise.Algorithm.SIMPLEX,
13+
... seed=42,
14+
... )
15+
>>> samples = noise[tcod.noise.grid(shape=(5, 5), scale=0.25, origin=(0, 0))]
16+
>>> samples # Samples are a grid of floats between -1.0 and 1.0
17+
array([[ 0. , -0.55046356, -0.76072866, -0.7088647 , -0.68165785],
18+
[-0.27523372, -0.7205134 , -0.74057037, -0.43919194, -0.29195625],
19+
[-0.40398532, -0.57662135, -0.33160293, 0.12860827, 0.2864191 ],
20+
[-0.50773406, -0.2643614 , 0.24446318, 0.6390255 , 0.5922846 ],
21+
[-0.64945626, -0.12529983, 0.5346834 , 0.80402255, 0.52655405]],
22+
dtype=float32)
23+
>>> (samples + 1.0) * 0.5 # You can normalize samples to 0.0 - 1.0
24+
array([[0.5 , 0.22476822, 0.11963567, 0.14556766, 0.15917107],
25+
[0.36238313, 0.1397433 , 0.12971482, 0.28040403, 0.35402188],
26+
[0.29800734, 0.21168932, 0.33419853, 0.5643041 , 0.6432096 ],
27+
[0.24613297, 0.3678193 , 0.6222316 , 0.8195127 , 0.79614234],
28+
[0.17527187, 0.4373501 , 0.76734173, 0.9020113 , 0.76327705]],
29+
dtype=float32)
30+
31+
32+
""" # noqa: E501
3433
import enum
3534
import warnings
36-
from typing import Any, Optional, Sequence, Union
35+
from typing import Any, Optional, Sequence, Tuple, Union
3736

3837
import numpy as np
3938

@@ -432,3 +431,55 @@ def _setstate_old(self, state: Any) -> None:
432431
self._tdl_noise_c = ffi.new(
433432
"TDLNoise*", (self.noise_c, self.noise_c.ndim, state[1], state[2])
434433
)
434+
435+
436+
def grid(
437+
shape: Tuple[int, ...],
438+
scale: Union[Tuple[float, ...], float],
439+
origin: Optional[Tuple[int, ...]] = None,
440+
) -> Tuple[np.ndarray, ...]:
441+
"""A helper function for generating a grid of noise samples.
442+
443+
`shape` is the shape of the returned mesh grid. This can be any number of
444+
dimensions, but :class:`Noise` classes only support up to 4.
445+
446+
`scale` is the step size of indexes away from `origin`.
447+
This can be a single float, or it can be a tuple of floats with one float
448+
for each axis in `shape`. A lower scale gives smoother transitions
449+
between noise values.
450+
451+
`origin` is the first sample of the grid.
452+
If `None` then the `origin` will be zero on each axis.
453+
`origin` is not scaled by the `scale` parameter.
454+
455+
Example::
456+
457+
>>> noise = tcod.noise.Noise(dimensions=2, seed=42)
458+
>>> noise[tcod.noise.grid(shape=(5, 5), scale=0.25)]
459+
array([[ 0. , -0.55046356, -0.76072866, -0.7088647 , -0.68165785],
460+
[-0.27523372, -0.7205134 , -0.74057037, -0.43919194, -0.29195625],
461+
[-0.40398532, -0.57662135, -0.33160293, 0.12860827, 0.2864191 ],
462+
[-0.50773406, -0.2643614 , 0.24446318, 0.6390255 , 0.5922846 ],
463+
[-0.64945626, -0.12529983, 0.5346834 , 0.80402255, 0.52655405]],
464+
dtype=float32)
465+
>>> noise[tcod.noise.grid(shape=(5, 5), scale=(0.5, 0.25), origin=(1, 1))]
466+
array([[ 0.52655405, -0.5037453 , -0.81221616, -0.7057655 , 0.24630858],
467+
[ 0.25038874, -0.75348294, -0.6379566 , -0.5817767 , -0.02789652],
468+
[-0.03488023, -0.73630923, -0.12449139, -0.22774395, -0.22243626],
469+
[-0.18455243, -0.35063767, 0.4495706 , 0.02399864, -0.42226675],
470+
[-0.16333057, 0.18149695, 0.7547447 , -0.07006818, -0.6546707 ]],
471+
dtype=float32)
472+
""" # noqa: E501
473+
if isinstance(scale, float):
474+
scale = (scale,) * len(shape)
475+
if origin is None:
476+
origin = (0,) * len(shape)
477+
if len(shape) != len(scale):
478+
raise TypeError("shape must have the same length as scale")
479+
if len(shape) != len(origin):
480+
raise TypeError("shape must have the same length as origin")
481+
indexes = (
482+
np.arange(i_shape) * i_scale + i_origin
483+
for i_shape, i_scale, i_origin in zip(shape, scale, origin)
484+
)
485+
return tuple(np.meshgrid(*indexes, copy=False, sparse=True, indexing="xy"))

0 commit comments

Comments
 (0)