Skip to content

Commit ae49f32

Browse files
committed
Add offset parameter to tcod.noise.grid
`origin` parameter is unintuitive for sampling noise by chunks or by integer offsets.
1 parent d641bc1 commit ae49f32

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ This project adheres to [Semantic Versioning](https://semver.org/) since version
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- `tcod.noise.grid` now has the `offset` parameter for easier sampling of noise chunks.
12+
913
## [19.1.0] - 2025-07-12
1014

1115
### Added

tcod/noise.py

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
... algorithm=tcod.noise.Algorithm.SIMPLEX,
1313
... seed=42,
1414
... )
15-
>>> samples = noise[tcod.noise.grid(shape=(5, 4), scale=0.25, origin=(0, 0))]
15+
>>> samples = noise[tcod.noise.grid(shape=(5, 4), scale=0.25, offset=(0, 0))]
1616
>>> samples # Samples are a grid of floats between -1.0 and 1.0
1717
array([[ 0. , -0.55046356, -0.76072866, -0.7088647 , -0.68165785],
1818
[-0.27523372, -0.7205134 , -0.74057037, -0.43919194, -0.29195625],
@@ -412,8 +412,10 @@ def _setstate_old(self, state: tuple[Any, ...]) -> None:
412412
def grid(
413413
shape: tuple[int, ...],
414414
scale: tuple[float, ...] | float,
415-
origin: tuple[int, ...] | None = None,
415+
origin: tuple[float, ...] | None = None,
416416
indexing: Literal["ij", "xy"] = "xy",
417+
*,
418+
offset: tuple[float, ...] | None = None,
417419
) -> tuple[NDArray[np.number], ...]:
418420
"""Generate a mesh-grid of sample points to use with noise sampling.
419421
@@ -427,6 +429,11 @@ def grid(
427429
If `None` then the `origin` will be zero on each axis.
428430
`origin` is not scaled by the `scale` parameter.
429431
indexing: Passed to :any:`numpy.meshgrid`.
432+
offset: The offset into the shape to generate.
433+
Similar to `origin` but is scaled by the `scale` parameter.
434+
Can be multiples of `shape` to index noise samples by chunk.
435+
436+
.. versionadded:: Unreleased
430437
431438
Returns:
432439
A sparse mesh-grid to be passed into a :class:`Noise` instance.
@@ -435,21 +442,38 @@ def grid(
435442
436443
>>> noise = tcod.noise.Noise(dimensions=2, seed=42)
437444
438-
# Common case for ij-indexed arrays.
445+
# Common case for ij-indexed arrays
439446
>>> noise[tcod.noise.grid(shape=(3, 5), scale=0.25, indexing="ij")]
440447
array([[ 0. , -0.27523372, -0.40398532, -0.50773406, -0.64945626],
441448
[-0.55046356, -0.7205134 , -0.57662135, -0.2643614 , -0.12529983],
442449
[-0.76072866, -0.74057037, -0.33160293, 0.24446318, 0.5346834 ]],
443450
dtype=float32)
444451
445-
# Transpose an xy-indexed array to get a standard order="F" result.
452+
# Transpose an xy-indexed array to get a standard order="F" result
446453
>>> noise[tcod.noise.grid(shape=(4, 5), scale=(0.5, 0.25), origin=(1.0, 1.0))].T
447454
array([[ 0.52655405, 0.25038874, -0.03488023, -0.18455243, -0.16333057],
448455
[-0.5037453 , -0.75348294, -0.73630923, -0.35063767, 0.18149695],
449456
[-0.81221616, -0.6379566 , -0.12449139, 0.4495706 , 0.7547447 ],
450457
[-0.7057655 , -0.5817767 , -0.22774395, 0.02399864, -0.07006818]],
451458
dtype=float32)
452459
460+
# Can sample noise by chunk using the offset keyword
461+
>>> noise[tcod.noise.grid(shape=(3, 5), scale=0.25, indexing="ij", offset=(0, 0))]
462+
array([[ 0. , -0.27523372, -0.40398532, -0.50773406, -0.64945626],
463+
[-0.55046356, -0.7205134 , -0.57662135, -0.2643614 , -0.12529983],
464+
[-0.76072866, -0.74057037, -0.33160293, 0.24446318, 0.5346834 ]],
465+
dtype=float32)
466+
>>> noise[tcod.noise.grid(shape=(3, 5), scale=0.25, indexing="ij", offset=(3, 0))]
467+
array([[-0.7088647 , -0.43919194, 0.12860827, 0.6390255 , 0.80402255],
468+
[-0.68165785, -0.29195625, 0.2864191 , 0.5922846 , 0.52655405],
469+
[-0.7841389 , -0.46131462, 0.0159424 , 0.17141782, -0.04198273]],
470+
dtype=float32)
471+
>>> noise[tcod.noise.grid(shape=(3, 5), scale=0.25, indexing="ij", offset=(6, 0))]
472+
array([[-0.779634 , -0.60696834, -0.27446985, -0.23233278, -0.5037453 ],
473+
[-0.5474089 , -0.54476213, -0.42235228, -0.49519652, -0.7101793 ],
474+
[-0.28291094, -0.4326369 , -0.5227732 , -0.69655263, -0.81221616]],
475+
dtype=float32)
476+
453477
.. versionadded:: 12.2
454478
"""
455479
if isinstance(scale, (int, float)):
@@ -462,6 +486,13 @@ def grid(
462486
if len(shape) != len(origin):
463487
msg = "shape must have the same length as origin"
464488
raise TypeError(msg)
489+
if offset is not None:
490+
if len(shape) != len(offset):
491+
msg = "shape must have the same length as offset"
492+
raise TypeError(msg)
493+
origin = tuple(
494+
i_origin + i_scale * i_offset for i_scale, i_offset, i_origin in zip(scale, offset, origin, strict=True)
495+
)
465496
indexes = (
466497
np.arange(i_shape) * i_scale + i_origin for i_shape, i_scale, i_origin in zip(shape, scale, origin, strict=True)
467498
)

0 commit comments

Comments
 (0)