libnoise/core/generator.rs
1use crate::core::adapters;
2use std::marker::Sized;
3
4/// A trait for building a coherent noise generation pipeline.
5///
6/// This is the main generator trait. Every noise source and every adapter must implement this trait.
7/// A noise source is a generator which, for a given point in input-space, produces a value based
8/// on the noise function implemented in the source. An adapter is a generator which modifies another
9/// generator by transforming input and/or output data. Some adapters require further parameterization
10/// or multiple generators. This allows for powerful chaining of sources and adapters to flexibly
11/// generate a wide variety of coherent noise.
12///
13/// The constant generic `D` represents the dimensionality of the input space, and can typically be
14/// inferred without explicitly specifiying it when working with generators.
15///
16/// # Creating generators
17///
18/// A source implements [`Generator<D>`] and requires no further generators as argument to be created,
19/// though they may be parameterized by e.g. a seed. For more on sources, see [`Source`]. Here a simple
20/// generator for simplex noise is created. Note how the constant generic parameter `D` represents the
21/// dimensionality of the input is inferred:
22///
23/// [`Source`]: crate::Source
24///
25/// ```
26/// # use libnoise::{Source, Generator};
27/// let generator = Source::simplex(42); // create a generator
28/// let value = generator.sample([0.2, 0.5]); // sample the generator at [0.2, 0.5]
29/// ```
30///
31/// Given a generator, it is possible to use adapters to transform the input and/or output in various
32/// ways:
33///
34/// ```
35/// # use libnoise::{Source, Generator, Generator4D};
36/// // create a complex generator by chaining adapters
37/// let generator = Source::simplex(42) // create a simplex noise generator
38/// .fbm(3, 0.013, 2.0, 0.5) // apply fractal brownian motion
39/// .abs() // generate the absolute value of outputs
40/// .mul(2.0) // multiply the outputs by 2.0
41/// .lambda(|x| 1.0 - x.exp() / 2.8) // apply a closure to the outputs
42/// .displace_x( // displace the input x-coordinate with...
43/// Source::worley(43) // ...a worley noise generator
44/// .scale([0.005; 4]) // ...with its inputs scaled by 0.005
45/// .fbm(3, 1.0, 2.0, 0.5) // ...and fractal brownian motion applied
46/// .mul(5.0)) // ...multiplied by 5.0
47/// .blend( // blend the output with...
48/// Source::worley(45) // ...a worley noise generator
49/// .scale([0.033; 4]), // ...scaled by 0.033
50/// Source::perlin(45) // ...and blending controlled by perlin noise
51/// .scale([0.033; 4]) // ...scaled by 0.033
52/// .add(0.3)); // ...and 0.3 added
53///
54/// // sample the generator at [0.2, 0.5, 0.3, 0.7]
55/// let value = generator.sample([0.2, 0.5, 0.3, 0.7]);
56/// ```
57pub trait Generator<const D: usize>: Sized {
58 /// Samples the generator at a given `point` and returns the resulting value.
59 ///
60 /// The input dimension is determined by the specific generator, and the required size of `point`
61 /// changes accordingly.
62 ///
63 /// # Examples
64 ///
65 /// Basic usage:
66 ///
67 /// ```
68 /// # use libnoise::{Source, Generator};
69 /// // Create a generator, here simplex noise.
70 /// let generator = Source::simplex(42);
71 ///
72 /// // Sample the generator at a given point in 2D space.
73 /// let value = generator.sample([0.2, 0.5]);
74 ///
75 /// // Simplex noise lies between -1.0 and 1.0.
76 /// assert!(-1.0 <= value && value <= 1.0);
77 /// ```
78 fn sample(&self, point: [f64; D]) -> f64;
79
80 /// Create a generator which scales input points before passing them to the underlying generator.
81 ///
82 /// Takes a scale factor for each dimension of the input space and crates a generator which scales
83 /// each input point accordingly before passing it to the underlying generator.
84 ///
85 /// # Examples
86 ///
87 /// Basic usage:
88 ///
89 /// ```
90 /// # use libnoise::{Source, Generator};
91 /// let point = [0.2, 0.5];
92 ///
93 /// let generator = Source::simplex(42) // build a generator
94 /// .scale([2.0, 0.2]); // apply the adapter
95 ///
96 /// let value = generator.sample(point); // sample the generator
97 ///
98 /// // [0.4, 0.1] is equivalent to [0.2 * 2.0, 0.5 * 0.2]
99 /// assert_eq!(value, Source::simplex(42).sample([0.4, 0.1]))
100 /// ```
101 #[inline]
102 fn scale(self, scale: [f64; D]) -> adapters::Scale<D, Self> {
103 adapters::Scale::new(self, scale)
104 }
105
106 /// Create a generator which translates input points before passing them to the underlying generator.
107 ///
108 /// Takes a translation offset for each dimension of the input space and crates a generator which
109 /// translates each input point accordingly before passing it to the underlying generator.
110 ///
111 /// # Examples
112 ///
113 /// Basic usage:
114 ///
115 /// ```
116 /// # use libnoise::{Source, Generator};
117 /// let point = [0.2, 0.5];
118 ///
119 /// let generator = Source::simplex(42) // build a generator
120 /// .translate([0.3, 1.0]); // apply the adapter
121 ///
122 /// let value = generator.sample(point); // sample the generator
123 ///
124 /// // [0.5, 1.5] is equivalent to [0.2 + 0.3, 0.5 + 1.0]
125 /// assert_eq!(value, Source::simplex(42).sample([0.5, 1.5]))
126 /// ```
127 #[inline]
128 fn translate(self, translation: [f64; D]) -> adapters::Translate<D, Self> {
129 adapters::Translate::new(self, translation)
130 }
131
132 /// Create a generator which negates the results of the underlying generator.
133 ///
134 /// Creates a generator which is exactly the same as the underlying generator, except it changes
135 /// the sign of the result.
136 ///
137 /// # Examples
138 ///
139 /// Basic usage:
140 ///
141 /// ```
142 /// # use libnoise::{Source, Generator};
143 /// let point = [0.2, 0.5];
144 ///
145 /// let generator = Source::simplex(42) // build a generator
146 /// .neg(); // apply the adapter
147 ///
148 /// let value = generator.sample(point); // sample the generator
149 ///
150 /// assert_eq!(value, -Source::simplex(42).sample(point))
151 /// ```
152 #[inline]
153 fn neg(self) -> adapters::Neg<D, Self> {
154 adapters::Neg::new(self)
155 }
156
157 /// Create a generator returning the absolute value of the results of the underlying generator.
158 ///
159 /// Creates a generator which is exactly the same as the underlying generator, except the absolute
160 /// value of underlying result is generated.
161 ///
162 /// # Examples
163 ///
164 /// Basic usage:
165 ///
166 /// ```
167 /// # use libnoise::{Source, Generator};
168 /// let point = [0.2, 0.5];
169 ///
170 /// let generator = Source::simplex(42) // build a generator
171 /// .abs(); // apply the adapter
172 ///
173 /// let value = generator.sample(point); // sample the generator
174 ///
175 /// assert_eq!(value, Source::simplex(42).sample(point).abs())
176 /// ```
177 #[inline]
178 fn abs(self) -> adapters::Abs<D, Self> {
179 adapters::Abs::new(self)
180 }
181
182 /// Create a generator applying the exponential function on results of the underlying generator.
183 ///
184 /// Creates a generator which is exactly the same as the underlying generator, except the exponential
185 /// function `e^x` is applied to the result. Here, `e` represents Euler's number, and `x` is the
186 /// result of the underlying generator.
187 ///
188 /// # Examples
189 ///
190 /// Basic usage:
191 ///
192 /// ```
193 /// # use libnoise::{Source, Generator};
194 /// let point = [0.2, 0.5];
195 ///
196 /// let generator = Source::simplex(42) // build a generator
197 /// .exp(); // apply the adapter
198 ///
199 /// let value = generator.sample(point); // sample the generator
200 ///
201 /// assert_eq!(value, Source::simplex(42).sample(point).exp())
202 /// ```
203 #[inline]
204 fn exp(self) -> adapters::Exp<D, Self> {
205 adapters::Exp::new(self)
206 }
207
208 /// Create a generator adding `offset` to results of the underlying generator.
209 ///
210 /// Creates a generator which is exactly the same as the underlying generator, except the `offset`
211 /// is added to the result.
212 ///
213 /// # Examples
214 ///
215 /// Basic usage:
216 ///
217 /// ```
218 /// # use libnoise::{Source, Generator};
219 /// let point = [0.2, 0.5];
220 ///
221 /// let generator = Source::simplex(42) // build a generator
222 /// .add(1.5); // apply the adapter
223 ///
224 /// let value = generator.sample(point); // sample the generator
225 ///
226 /// assert_eq!(value, Source::simplex(42).sample(point) + 1.5)
227 /// ```
228 #[inline]
229 fn add(self, offset: f64) -> adapters::Add<D, Self> {
230 adapters::Add::new(self, offset)
231 }
232
233 /// Create a generator multiplying `scale` to results of the underlying generator.
234 ///
235 /// Creates a generator which is exactly the same as the underlying generator, except the result
236 /// is multiplied by `scale`.
237 ///
238 /// # Examples
239 ///
240 /// Basic usage:
241 ///
242 /// ```
243 /// # use libnoise::{Source, Generator};
244 /// let point = [0.2, 0.5];
245 ///
246 /// let generator = Source::simplex(42) // build a generator
247 /// .mul(1.5); // apply the adapter
248 ///
249 /// let value = generator.sample(point); // sample the generator
250 ///
251 /// assert_eq!(value, Source::simplex(42).sample(point) * 1.5)
252 /// ```
253 #[inline]
254 fn mul(self, scale: f64) -> adapters::Mul<D, Self> {
255 adapters::Mul::new(self, scale)
256 }
257
258 /// Create a generator raising results of the underlying generator to the power of `exponent`.
259 ///
260 /// Creates a generator which is exactly the same as the underlying generator, except the result
261 /// is raised to the power of `exponent`. For `powi`, the `exponent` must be an integer,
262 /// specifically `i32`. Using this function is generally faster than using `powf` and should be
263 /// used, if the desired exponent is an integer.
264 ///
265 /// # Examples
266 ///
267 /// Basic usage:
268 ///
269 /// ```
270 /// # use libnoise::{Source, Generator};
271 /// let point = [0.2, 0.5];
272 ///
273 /// let generator = Source::simplex(42) // build a generator
274 /// .powi(2); // apply the adapter
275 ///
276 /// let value = generator.sample(point); // sample the generator
277 ///
278 /// assert_eq!(value, Source::simplex(42).sample(point).powi(2))
279 /// ```
280 #[inline]
281 fn powi(self, exponent: i32) -> adapters::Pow<D, Self, i32> {
282 adapters::Pow::new(self, exponent)
283 }
284
285 /// Create a generator raising results of the underlying generator to the power of `exponent`.
286 ///
287 /// Creates a generator which is exactly the same as the underlying generator, except the result
288 /// is raised to the power of `exponent`. For `powf`, the `exponent` must be a floating point
289 /// number, specifically `f64`. Using this function is generally slower than using `powi` and
290 /// should only be used, if the desired exponent is not an integer.
291 ///
292 /// # Examples
293 ///
294 /// Basic usage:
295 ///
296 /// ```
297 /// # use libnoise::{Source, Generator};
298 /// let point = [0.2, 0.5];
299 ///
300 /// let generator = Source::simplex(42) // build a generator
301 /// .powf(1.5); // apply the adapter
302 ///
303 /// let value = generator.sample(point); // sample the generator
304 ///
305 /// assert_eq!(value, Source::simplex(42).sample(point).powf(1.5))
306 /// ```
307 #[inline]
308 fn powf(self, exponent: f64) -> adapters::Pow<D, Self, f64> {
309 adapters::Pow::new(self, exponent)
310 }
311
312 /// Create a generator clamping results of the underlying generator to a given interval.
313 ///
314 /// Creates a generator which is exactly the same as the underlying generator, except the result
315 /// is clamped to the interval [`min`, `max`]. Specifically, `max` is generated if the result is
316 /// greater than `max` and `min` is generated if the result is less than `min`. If the result was
317 /// NaN, it will remain NaN after clamping.
318 ///
319 /// # Examples
320 ///
321 /// Basic usage:
322 ///
323 /// ```
324 /// # use libnoise::{Source, Generator};
325 /// let point = [0.2, 0.5];
326 ///
327 /// let generator = Source::simplex(42) // build a generator
328 /// .clamp(-0.5, 0.5); // apply the adapter
329 ///
330 /// let value = generator.sample(point); // sample the generator
331 ///
332 /// assert_eq!(value, Source::simplex(42).sample(point).clamp(-0.5, 0.5))
333 /// ```
334 #[inline]
335 fn clamp(self, min: f64, max: f64) -> adapters::Clamp<D, Self> {
336 adapters::Clamp::new(self, min, max)
337 }
338
339 /// Create a generator applying the supplied closure to results of the underlying generator.
340 ///
341 /// Creates a generator which is exactly the same as the underlying generator, except the result
342 /// of the generator modified by the closure provided.
343 ///
344 /// # Examples
345 ///
346 /// Basic usage:
347 ///
348 /// ```
349 /// # use libnoise::{Source, Generator};
350 /// let point = [0.2, 0.5];
351 /// let closure = |x| x * x;
352 ///
353 /// let generator = Source::simplex(42) // build a generator
354 /// .lambda(closure); // apply the adapter
355 ///
356 /// let value = generator.sample(point); // sample the generator
357 ///
358 /// assert_eq!(value, closure(Source::simplex(42).sample(point)))
359 /// ```
360 #[inline]
361 fn lambda<L>(self, lambda: L) -> adapters::Lambda<D, Self, L>
362 where
363 L: Fn(f64) -> f64,
364 {
365 adapters::Lambda::new(self, lambda)
366 }
367
368 /// Create a generator adding results of the underlying generator to results of a given other
369 /// generator.
370 ///
371 /// Creates a generator which is exactly the same as the underlying generator, except the result
372 /// of the generator is added to the result of the given generator for the same input point.
373 ///
374 /// # Examples
375 ///
376 /// Basic usage:
377 ///
378 /// ```
379 /// # use libnoise::{Source, Generator};
380 /// let point = [0.2, 0.5];
381 ///
382 /// let generator = Source::simplex(42) // build a generator
383 /// .sum(Source::simplex(43)); // apply the adapter
384 ///
385 /// let value = generator.sample(point); // sample the generator
386 ///
387 /// assert_eq!(value, Source::simplex(42).sample(point) + Source::simplex(43).sample(point))
388 /// ```
389 #[inline]
390 fn sum<G>(self, other: G) -> adapters::Sum<D, Self, G>
391 where
392 G: Generator<D>,
393 {
394 adapters::Sum::new(self, other)
395 }
396
397 /// Create a generator multiplying results of the underlying generator to results of a given other
398 /// generator.
399 ///
400 /// Creates a generator which is exactly the same as the underlying generator, except the result
401 /// of the generator is multiplied with the result of the given generator for the same input point.
402 ///
403 /// # Examples
404 ///
405 /// Basic usage:
406 ///
407 /// ```
408 /// # use libnoise::{Source, Generator};
409 /// let point = [0.2, 0.5];
410 ///
411 /// let generator = Source::simplex(42) // build a generator
412 /// .product(Source::simplex(43)); // apply the adapter
413 ///
414 /// let value = generator.sample(point); // sample the generator
415 ///
416 /// assert_eq!(value, Source::simplex(42).sample(point) * Source::simplex(43).sample(point))
417 /// ```
418 #[inline]
419 fn product<G>(self, other: G) -> adapters::Product<D, Self, G>
420 where
421 G: Generator<D>,
422 {
423 adapters::Product::new(self, other)
424 }
425
426 /// Create a generator producing the minimum of results of the underlying generator and results of
427 /// a given other generator.
428 ///
429 /// Creates a generator which is producing either the result of the underlying generator, or the
430 /// result of given the generator, whichever is less.
431 ///
432 /// # Examples
433 ///
434 /// Basic usage:
435 ///
436 /// ```
437 /// # use libnoise::{Source, Generator};
438 /// let point = [0.2, 0.5];
439 ///
440 /// let generator = Source::simplex(42) // build a generator
441 /// .min(Source::simplex(43)); // apply the adapter
442 ///
443 /// let value = generator.sample(point); // sample the generator
444 ///
445 /// assert_eq!(value, Source::simplex(42).sample(point).min(Source::simplex(43).sample(point)))
446 /// ```
447 #[inline]
448 fn min<G>(self, other: G) -> adapters::Min<D, Self, G>
449 where
450 G: Generator<D>,
451 {
452 adapters::Min::new(self, other)
453 }
454
455 /// Create a generator producing the maximum of results of the underlying generator and results of
456 /// a given other generator.
457 ///
458 /// Creates a generator which is producing either the result of the underlying generator, or the
459 /// result of given the generator, whichever is greater.
460 ///
461 /// # Examples
462 ///
463 /// Basic usage:
464 ///
465 /// ```
466 /// # use libnoise::{Source, Generator};
467 /// let point = [0.2, 0.5];
468 ///
469 /// let generator = Source::simplex(42) // build a generator
470 /// .max(Source::simplex(43)); // apply the adapter
471 ///
472 /// let value = generator.sample(point); // sample the generator
473 ///
474 /// assert_eq!(value, Source::simplex(42).sample(point).max(Source::simplex(43).sample(point)))
475 /// ```
476 #[inline]
477 fn max<G>(self, other: G) -> adapters::Max<D, Self, G>
478 where
479 G: Generator<D>,
480 {
481 adapters::Max::new(self, other)
482 }
483
484 /// Create a generator raising results of the underlying generator to the power of results of a
485 /// given other generator.
486 ///
487 /// Creates a generator which is exactly the same as the underlying generator, except the result
488 /// of the generator is raised to the power of the result of the given generator for the same
489 /// input point.
490 ///
491 /// # Examples
492 ///
493 /// Basic usage:
494 ///
495 /// ```
496 /// # use libnoise::{Source, Generator};
497 /// let point = [0.2, 0.5];
498 ///
499 /// let generator = Source::simplex(42) // build a generator
500 /// .power(Source::simplex(43)); // apply the adapter
501 ///
502 /// let value = generator.sample(point); // sample the generator
503 ///
504 /// assert_eq!(value, Source::simplex(42).sample(point).powf(Source::simplex(43).sample(point)))
505 /// ```
506 #[inline]
507 fn power<G>(self, other: G) -> adapters::Power<D, Self, G>
508 where
509 G: Generator<D>,
510 {
511 adapters::Power::new(self, other)
512 }
513
514 /// Create a generator applying fractal brownian motion on the underlying generator.
515 ///
516 /// Within the context of coherent noise, fractal brownian motion is a common technique for making
517 /// noise appear more natural. This is done by layering versions of noise with differently scaled
518 /// inputs and outputs on top of each other.
519 ///
520 /// The process can be described as follows: The initial amplitude is 1, while the initial frequency
521 /// is the passed `frequency` parameter. For each octave, the number of which is specified by the
522 /// `octaves` parameter, the following is done: The input point is scaled by the frequency argument,
523 /// and the underlying generator is sampled at that point. The sample is then multiplied by the
524 /// amplitude. Each iteration, the frequency and amplitude are updated by multiplying them with
525 /// `lacunarity` and `persistence` respectively. If not 1, this causes exponential growth or decay
526 /// of the frequency and amplitude, as octaves are increase. The result is the normalized sum of
527 /// samples from each octave.
528 ///
529 /// <p style="background:rgba(122,186,255,0.16);padding:0.75em;">
530 /// <strong>Note:</strong>
531 /// The initial amplitude is not a parameter because the result of the generator is normalized.
532 /// </p>
533 ///
534 /// <p style="background:rgba(122,186,255,0.16);padding:0.75em;">
535 /// <strong>Note:</strong>
536 /// Typically, a desireable value for `lacunarity` is 2 while a desireable value for `persistence`
537 /// lies somewhere between 0 and 1.
538 /// </p>
539 ///
540 /// # Examples
541 ///
542 /// Basic usage:
543 ///
544 /// ```
545 /// # use libnoise::{Source, Generator};
546 /// let point = [0.2, 0.5];
547 ///
548 /// let octaves = 6;
549 /// let frequency = 1.0;
550 /// let lacunarity = 2.0;
551 /// let persistence = 0.5;
552 ///
553 /// // build a generator using the adapter
554 /// let generator = Source::simplex(42)
555 /// .fbm(octaves, frequency, lacunarity, persistence);
556 ///
557 /// // sample the generator
558 /// let value = generator.sample(point);
559 ///
560 /// // compute manually for the given point to illustrate
561 /// let underlying = Source::simplex(42);
562 /// let mut expected = 0.0;
563 /// let mut amp = 1.0;
564 /// let mut freq = frequency;
565 /// for _ in 0..octaves {
566 /// expected += amp * underlying.sample(point.map(|x| x * freq));
567 /// freq *= lacunarity;
568 /// amp *= persistence;
569 /// }
570 /// expected /= (0..octaves).fold(0.0, |acc, octave| acc + persistence.powi(octave as i32));
571 ///
572 /// assert!(value - expected < f64::EPSILON);
573 /// ```
574 #[inline]
575 fn fbm(
576 self,
577 octaves: u32,
578 frequency: f64,
579 lacunarity: f64,
580 persistence: f64,
581 ) -> adapters::Fbm<D, Self> {
582 adapters::Fbm::new(self, octaves, frequency, lacunarity, persistence)
583 }
584
585 /// Create a generator applying an [`fbm()`]-like effect on the underlying generator.
586 ///
587 /// This adapter is very similar to the [`fbm()`] adapter, except instead of using the output of the
588 /// underlying generator directly, the absolute value, rescaled to the [-1, 1] range, is used instead.
589 /// For details, see the [`fbm()`] adapter.
590 ///
591 /// <p style="background:rgba(255,181,77,0.16);padding:0.75em;">
592 /// <strong>Warning:</strong>
593 /// This adapter assumes that the underlying generator produces values in the [-1, 1] range. This is
594 /// because the adapter has no knowledge of the theoretical bounds of the underlying generator and
595 /// must therefore assume a range for the rescaling of absolute values for each octave. The generator
596 /// created by this adapter will not produce correct results, if this contract is violated.
597 /// </p>
598 ///
599 /// <p style="background:rgba(122,186,255,0.16);padding:0.75em;">
600 /// <strong>Note:</strong>
601 /// The initial amplitude is not a parameter because the result of the generator is normalized.
602 /// </p>
603 ///
604 /// <p style="background:rgba(122,186,255,0.16);padding:0.75em;">
605 /// <strong>Note:</strong>
606 /// Typically, a desireable value for `lacunarity` is 2 while a desireable value for `persistence` lies
607 /// somewhere between 0 and 1.
608 /// </p>
609 ///
610 /// [`fbm()`]: Generator::fbm
611 ///
612 /// # Examples
613 ///
614 /// Basic usage:
615 ///
616 /// ```
617 /// # use libnoise::{Source, Generator};
618 /// let point = [0.2, 0.5];
619 ///
620 /// let octaves = 6;
621 /// let frequency = 1.0;
622 /// let lacunarity = 2.0;
623 /// let persistence = 0.5;
624 ///
625 /// // build a generator using the adapter
626 /// let generator = Source::simplex(42)
627 /// .billow(octaves, frequency, lacunarity, persistence);
628 ///
629 /// // sample the generator
630 /// let value = generator.sample(point);
631 ///
632 /// // compute manually for the given point to illustrate
633 /// let underlying = Source::simplex(42);
634 /// let mut expected = 0.0;
635 /// let mut amp = 1.0;
636 /// let mut freq = frequency;
637 /// for _ in 0..octaves {
638 /// expected += amp * (underlying.sample(point.map(|x| x * freq)).abs() * 2.0 - 1.0);
639 /// freq *= lacunarity;
640 /// amp *= persistence;
641 /// }
642 /// expected /= (0..octaves).fold(0.0, |acc, octave| acc + persistence.powi(octave as i32));
643 ///
644 /// assert!(value - expected < f64::EPSILON);
645 /// ```
646 #[inline]
647 fn billow(
648 self,
649 octaves: u32,
650 frequency: f64,
651 lacunarity: f64,
652 persistence: f64,
653 ) -> adapters::Billow<D, Self> {
654 adapters::Billow::new(self, octaves, frequency, lacunarity, persistence)
655 }
656
657 /// Create a generator applying an [`fbm()`]-like effect on the underlying generator.
658 ///
659 /// This adapter is very similar to the [`fbm()`] adapter. A core difference is the lack of a
660 /// persistence parameter, as the amplitude of an octave is determined by the actual value from
661 /// the previous octave. The result for a given octave is computed as the square of 1 subtracted
662 /// by the absolute value of the underlying generator, multiplied by the amplitude. The amplitude
663 /// for the next octave is the previous result, dampened by the `attenuation` parameter and
664 /// clamped to the [0, 1] range. The total result is the sum of results for each octave,
665 /// normalized to the [-1, 1] range. For details, see the [`fbm()`] adapter.
666 ///
667 /// <p style="background:rgba(255,181,77,0.16);padding:0.75em;">
668 /// <strong>Warning:</strong>
669 /// This adapter assumes that the underlying generator produces values in the [-1, 1] range. This is
670 /// because the adapter has no knowledge of the theoretical bounds of the underlying generator and
671 /// must therefore assume a range for the rescaling of noise for which absolute values were computed.
672 /// The generator created by this adapter will not produce correct results, if this contract is
673 /// violated.
674 /// </p>
675 ///
676 /// <p style="background:rgba(122,186,255,0.16);padding:0.75em;">
677 /// <strong>Note:</strong>
678 /// The initial amplitude is not a parameter because the result of the generator is normalized.
679 /// </p>
680 ///
681 /// <p style="background:rgba(122,186,255,0.16);padding:0.75em;">
682 /// <strong>Note:</strong>
683 /// Typically, desireable values for `lacunarity` and `attenuation` are 2.
684 /// </p>
685 ///
686 /// [`fbm()`]: Generator::fbm
687 ///
688 /// # Examples
689 ///
690 /// Basic usage:
691 ///
692 /// ```
693 /// # use libnoise::{Source, Generator};
694 /// let point = [0.2, 0.5];
695 ///
696 /// let octaves = 6;
697 /// let frequency = 1.0;
698 /// let lacunarity = 2.0;
699 /// let attenuation = 2.0;
700 ///
701 /// // build a generator using the adapter
702 /// let generator = Source::simplex(42)
703 /// .ridgedmulti(octaves, frequency, lacunarity, attenuation);
704 ///
705 /// // sample the generator
706 /// let value = generator.sample(point);
707 ///
708 /// // compute manually for the given point to illustrate
709 /// let underlying = Source::simplex(42);
710 /// let mut expected = 0.0;
711 /// let mut amp = 1.0;
712 /// let mut freq = frequency;
713 /// for _ in 0..octaves {
714 /// let mut tmp = amp * (1.0 - underlying.sample(point.map(|x| x * freq)).abs()).powi(2);
715 /// expected += amp;
716 /// freq *= lacunarity;
717 /// amp = (tmp / attenuation).clamp(0.0, 1.0);
718 /// }
719 /// expected = (expected / (0..octaves).fold(0.0, |acc, octave| {
720 /// acc + (1.0 / attenuation).powi(octave as i32)
721 /// })) * 2.0 - 1.0;
722 ///
723 /// assert!(value - expected < f64::EPSILON);
724 /// ```
725 #[inline]
726 fn ridgedmulti(
727 self,
728 octaves: u32,
729 frequency: f64,
730 lacunarity: f64,
731 attenuation: f64,
732 ) -> adapters::RidgedMulti<D, Self> {
733 adapters::RidgedMulti::new(self, octaves, frequency, lacunarity, attenuation)
734 }
735
736 /// Create a generator blending the underlying generator with a given other generator based on the
737 /// value supplied by a control-generator.
738 ///
739 /// This adapter takes two generators, `other` and `control`, as parameters. The generator `control`
740 /// is expected to produce values in the [-1, 1] range. Based on that value, the results of the
741 /// underlying generator and `other` are blended. If the value is -1, the result is equal to that of
742 /// the underlying generator. If the value is 1, the result is equal to that of `other`. For other
743 /// `control` values, the result is the linear interpolation between the results of the underlying
744 /// generator and `other`.
745 ///
746 /// <p style="background:rgba(255,181,77,0.16);padding:0.75em;">
747 /// <strong>Warning:</strong>
748 /// This adapter assumes that the control generator produces values in the [-1, 1] range. The
749 /// generator created by this adapter will not produce correct results, if this contract is violated.
750 /// </p>
751 ///
752 /// # Examples
753 ///
754 /// Basic usage:
755 ///
756 /// ```
757 /// # use libnoise::{Source, Generator};
758 /// let point = [0.2, 0.5];
759 ///
760 /// // build a generator using the adapter
761 /// let generator = Source::simplex(42)
762 /// .blend(Source::simplex(43), Source::simplex(44));
763 ///
764 /// // sample the generator
765 /// let value = generator.sample(point);
766 ///
767 /// // compute manually for the given point to illustrate
768 /// let a = Source::simplex(42).sample(point);
769 /// let b = Source::simplex(43).sample(point);
770 /// let t = Source::simplex(44).sample(point) * 0.5 + 0.5;
771 /// let expected = a + t * (b - a);
772 ///
773 /// assert!(value - expected < f64::EPSILON);
774 /// ```
775 #[inline]
776 fn blend<G, GC>(self, other: G, control: GC) -> adapters::Blend<D, Self, G, GC>
777 where
778 G: Generator<D>,
779 GC: Generator<D>,
780 {
781 adapters::Blend::new(self, other, control)
782 }
783
784 /// Create a generator selecting the result of either the underlying generator or that of a given
785 /// other generator based on whether the value supplied by a control-generator lies within the
786 /// provided interval.
787 ///
788 /// This adapter takes two generators, `other` and `control`, as well as an interval defined by
789 /// `selection_min` and `selection_max`, as parameters. If the value produced by generator `control`
790 /// lies within the provided interval, produce the result of the underlying generator. Otherwise,
791 /// produce the result of `other`.
792 ///
793 /// # Examples
794 ///
795 /// Basic usage:
796 ///
797 /// ```
798 /// # use libnoise::{Source, Generator};
799 /// let point = [0.2, 0.5];
800 ///
801 /// // build a generator using the adapter
802 /// let generator = Source::simplex(42)
803 /// .select(Source::simplex(43), Source::simplex(44), -0.3, 0.1);
804 ///
805 /// // sample the generator
806 /// let value = generator.sample(point);
807 ///
808 /// // compute manually for the given point to illustrate
809 /// let expected = match Source::simplex(44).sample(point) {
810 /// x if -0.3 <= x && x <= 0.1 => Source::simplex(42).sample(point),
811 /// _ => Source::simplex(43).sample(point),
812 /// };
813 ///
814 /// assert!(value - expected < f64::EPSILON);
815 /// ```
816 #[inline]
817 fn select<G, GC>(
818 self,
819 other: G,
820 control: GC,
821 selection_min: f64,
822 selection_max: f64,
823 ) -> adapters::Select<D, Self, G, GC>
824 where
825 G: Generator<D>,
826 GC: Generator<D>,
827 {
828 adapters::Select::new(self, other, control, selection_min, selection_max)
829 }
830
831 /// Create a generator returning the function value of a provided spline given the result of the
832 /// underlying generator as input.
833 ///
834 /// Creates a generator which maps outputs of the underlying generator to function values of
835 /// the defined spline. This is equivalent to using [`lambda()`] and supplying a function which
836 /// evaluates a spline at a given position and returns [`f64::NAN`] if the value was out of bounds
837 /// for the domain of the spline. `knot_vector` is an array of `f64` values representing the
838 /// ordered list of interval boundaries over which the spline is defined. `knots` represents the
839 /// value attached to the respective interval boundary. Therefore `knot_vector[i]` is associated
840 /// to `knots[i]` for each `i`.
841 ///
842 /// <p style="background:rgba(255,181,77,0.16);padding:0.75em;">
843 /// <strong>Note:</strong>
844 /// This adapter performs sanity checks on whether there are enough knots, whether knot_vector and
845 /// knots are all finite values and of the same length, and whether knot_vector is sorted. Ensure
846 /// inputs are well formed.
847 /// </p>
848 ///
849 /// <p style="background:rgba(122,186,255,0.16);padding:0.75em;">
850 /// <strong>Note:</strong>
851 /// Values out of bounds for the spline domain cause the generator to yield NaN.
852 /// </p>
853 ///
854 /// # Examples
855 ///
856 /// Basic usage:
857 ///
858 /// ```
859 /// # use libnoise::{Source, Generator, NaturalCubicSpline};
860 /// let point = [0.2, 0.5];
861 ///
862 /// let generator = Source::simplex(42) // build a generator
863 /// .spline::<NaturalCubicSpline>( // apply the adapter
864 /// &[-1.0, 1.5, 3.0, 7.5, 9.2],
865 /// &[5.0, 0.0, -6.5, 2.0, -11.0],
866 /// );
867 ///
868 /// let value = generator.sample(point); // sample the generator
869 /// ```
870 /// [`lambda()`]: Generator::lambda
871 #[inline]
872 fn spline<S>(self, knot_vector: &[f64], knots: &[f64]) -> adapters::Spline<D, Self, S>
873 where
874 S: adapters::SplineImpl,
875 {
876 adapters::Spline::new(self, knot_vector, knots)
877 }
878}
879
880/// A trait representing the specialization of [`Generator<D>`] for 1-dimensional input spaces.
881///
882/// Anything implementing this trait must also implement [`Generator<1>`]. This trait exists
883/// for two reasons: The first is to provide functions that either only make sense for specific
884/// dimensionalities, or are either too difficult or inefficient to implement in a
885/// dimension-agnostic manner. The second is to bypass certain limitations of constant generics.
886pub trait Generator1D: Generator<1> {
887 /// Create a generator providing the results of the underlying generator after displacing the
888 /// x-coordinate by the result of the provided generator.
889 ///
890 /// Creates a generator which is exactly the same as the underlying generator, except the
891 /// x-coordinate of the input point is first displaced by the result of `displacement_generator`
892 /// for that point.
893 ///
894 /// # Examples
895 ///
896 /// Basic usage:
897 ///
898 /// ```
899 /// # use libnoise::{Source, Generator, Generator1D};
900 /// let mut point = [0.2];
901 ///
902 /// let generator = Source::simplex(42) // build a generator
903 /// .displace_x(Source::simplex(43)); // apply the adapter
904 ///
905 /// let value = generator.sample(point); // sample the generator
906 ///
907 /// point[0] += Source::simplex(43).sample(point);
908 /// assert_eq!(value, Source::simplex(42).sample(point))
909 /// ```
910 #[inline]
911 fn displace_x<GA>(self, displacement_generator: GA) -> adapters::Displace<1, 0, Self, GA>
912 where
913 GA: Generator<1>,
914 {
915 adapters::Displace::new(self, displacement_generator)
916 }
917}
918
919/// A trait representing the specialization of [`Generator<D>`] for 2-dimensional input spaces.
920///
921/// Anything implementing this trait must also implement [`Generator<2>`]. This trait exists
922/// for two reasons: The first is to provide functions that either only make sense for specific
923/// dimensionalities, or are either too difficult or inefficient to implement in a
924/// dimension-agnostic manner. The second is to bypass certain limitations of constant generics.
925pub trait Generator2D: Generator<2> {
926 /// Create a generator which rotates input points before passing them to the underlying generator.
927 ///
928 /// Takes an angle in radians for each unique pair of axes in the input space and crates a
929 /// generator which rotates each input point for the provided angle on the plane spanned by each
930 /// axis pair, before passing it to the underlying generator. The specific plane of rotation
931 /// for each angle is as follows:
932 ///
933 /// | plane of rotation | corresponding angle |
934 /// |-------------------|---------------------|
935 /// | `xy`-plane | `rotation[0]` |
936 ///
937 /// # Examples
938 ///
939 /// Basic usage:
940 ///
941 /// ```
942 /// # use libnoise::{Source, Generator, Generator2D};
943 /// let point = [0.2, 0.5];
944 ///
945 /// let generator = Source::simplex(42) // build a generator
946 /// .rotate([0.4]); // apply the adapter
947 ///
948 /// let value = generator.sample(point); // sample the generator
949 /// ```
950 #[inline]
951 fn rotate(self, rotation: [f64; 1]) -> adapters::Rotate<2, 1, Self> {
952 adapters::Rotate::new(self, rotation)
953 }
954
955 /// Create a generator providing the results of the underlying generator after displacing the
956 /// x-coordinate by the result of the provided generator.
957 ///
958 /// Creates a generator which is exactly the same as the underlying generator, except the
959 /// x-coordinate of the input point is first displaced by the result of `displacement_generator`
960 /// for that point.
961 ///
962 /// # Examples
963 ///
964 /// Basic usage:
965 ///
966 /// ```
967 /// # use libnoise::{Source, Generator, Generator2D};
968 /// let mut point = [0.2, 0.5];
969 ///
970 /// let generator = Source::simplex(42) // build a generator
971 /// .displace_x(Source::simplex(43)); // apply the adapter
972 ///
973 /// let value = generator.sample(point); // sample the generator
974 ///
975 /// point[0] += Source::simplex(43).sample(point);
976 /// assert_eq!(value, Source::simplex(42).sample(point))
977 /// ```
978 #[inline]
979 fn displace_x<GA>(self, displacement_generator: GA) -> adapters::Displace<2, 0, Self, GA>
980 where
981 GA: Generator<2>,
982 {
983 adapters::Displace::new(self, displacement_generator)
984 }
985
986 /// Create a generator providing the results of the underlying generator after displacing the
987 /// y-coordinate by the result of the provided generator.
988 ///
989 /// Creates a generator which is exactly the same as the underlying generator, except the
990 /// y-coordinate of the input point is first displaced by the result of `displacement_generator`
991 /// for that point.
992 ///
993 /// # Examples
994 ///
995 /// Basic usage:
996 ///
997 /// ```
998 /// # use libnoise::{Source, Generator, Generator2D};
999 /// let mut point = [0.2, 0.5];
1000 ///
1001 /// let generator = Source::simplex(42) // build a generator
1002 /// .displace_y(Source::simplex(43)); // apply the adapter
1003 ///
1004 /// let value = generator.sample(point); // sample the generator
1005 ///
1006 /// point[1] += Source::simplex(43).sample(point);
1007 /// assert_eq!(value, Source::simplex(42).sample(point))
1008 /// ```
1009 #[inline]
1010 fn displace_y<GA>(self, displacement_generator: GA) -> adapters::Displace<2, 1, Self, GA>
1011 where
1012 GA: Generator<2>,
1013 {
1014 adapters::Displace::new(self, displacement_generator)
1015 }
1016}
1017
1018/// A trait representing the specialization of [`Generator<D>`] for 3-dimensional input spaces.
1019///
1020/// Anything implementing this trait must also implement [`Generator<3>`]. This trait exists
1021/// for two reasons: The first is to provide functions that either only make sense for specific
1022/// dimensionalities, or are either too difficult or inefficient to implement in a
1023/// dimension-agnostic manner. The second is to bypass certain limitations of constant generics.
1024pub trait Generator3D: Generator<3> {
1025 /// Create a generator which rotates input points before passing them to the underlying generator.
1026 ///
1027 /// Takes an angle in radians for each unique pair of axes in the input space and crates a
1028 /// generator which rotates each input point for the provided angle on the plane spanned by each
1029 /// axis pair, before passing it to the underlying generator. The specific plane of rotation
1030 /// for each angle is as follows:
1031 ///
1032 /// | plane of rotation | corresponding angle |
1033 /// |-------------------|---------------------|
1034 /// | `xy`-plane | `rotation[0]` |
1035 /// | `yz`-plane | `rotation[1]` |
1036 /// | `zx`-plane | `rotation[2]` |
1037 ///
1038 /// # Examples
1039 ///
1040 /// Basic usage:
1041 ///
1042 /// ```
1043 /// # use libnoise::{Source, Generator, Generator3D};
1044 /// let point = [0.2, 0.5, 0.3];
1045 ///
1046 /// let generator = Source::simplex(42) // build a generator
1047 /// .rotate([0.4, 1.5, 2.3]); // apply the adapter
1048 ///
1049 /// let value = generator.sample(point); // sample the generator
1050 /// ```
1051 #[inline]
1052 fn rotate(self, rotation: [f64; 3]) -> adapters::Rotate<3, 3, Self> {
1053 adapters::Rotate::new(self, rotation)
1054 }
1055
1056 /// Create a generator providing the results of the underlying generator after displacing the
1057 /// x-coordinate by the result of the provided generator.
1058 ///
1059 /// Creates a generator which is exactly the same as the underlying generator, except the
1060 /// x-coordinate of the input point is first displaced by the result of `displacement_generator`
1061 /// for that point.
1062 ///
1063 /// # Examples
1064 ///
1065 /// Basic usage:
1066 ///
1067 /// ```
1068 /// # use libnoise::{Source, Generator, Generator3D};
1069 /// let mut point = [0.2, 0.5, 0.3];
1070 ///
1071 /// let generator = Source::simplex(42) // build a generator
1072 /// .displace_x(Source::simplex(43)); // apply the adapter
1073 ///
1074 /// let value = generator.sample(point); // sample the generator
1075 ///
1076 /// point[0] += Source::simplex(43).sample(point);
1077 /// assert_eq!(value, Source::simplex(42).sample(point))
1078 /// ```
1079 #[inline]
1080 fn displace_x<GA>(self, displacement_generator: GA) -> adapters::Displace<3, 0, Self, GA>
1081 where
1082 GA: Generator<3>,
1083 {
1084 adapters::Displace::new(self, displacement_generator)
1085 }
1086
1087 /// Create a generator providing the results of the underlying generator after displacing the
1088 /// y-coordinate by the result of the provided generator.
1089 ///
1090 /// Creates a generator which is exactly the same as the underlying generator, except the
1091 /// y-coordinate of the input point is first displaced by the result of `displacement_generator`
1092 /// for that point.
1093 ///
1094 /// # Examples
1095 ///
1096 /// Basic usage:
1097 ///
1098 /// ```
1099 /// # use libnoise::{Source, Generator, Generator3D};
1100 /// let mut point = [0.2, 0.5, 0.3];
1101 ///
1102 /// let generator = Source::simplex(42) // build a generator
1103 /// .displace_y(Source::simplex(43)); // apply the adapter
1104 ///
1105 /// let value = generator.sample(point); // sample the generator
1106 ///
1107 /// point[1] += Source::simplex(43).sample(point);
1108 /// assert_eq!(value, Source::simplex(42).sample(point))
1109 /// ```
1110 #[inline]
1111 fn displace_y<GA>(self, displacement_generator: GA) -> adapters::Displace<3, 1, Self, GA>
1112 where
1113 GA: Generator<3>,
1114 {
1115 adapters::Displace::new(self, displacement_generator)
1116 }
1117
1118 /// Create a generator providing the results of the underlying generator after displacing the
1119 /// z-coordinate by the result of the provided generator.
1120 ///
1121 /// Creates a generator which is exactly the same as the underlying generator, except the
1122 /// z-coordinate of the input point is first displaced by the result of `displacement_generator`
1123 /// for that point.
1124 ///
1125 /// # Examples
1126 ///
1127 /// Basic usage:
1128 ///
1129 /// ```
1130 /// # use libnoise::{Source, Generator, Generator3D};
1131 /// let mut point = [0.2, 0.5, 0.3];
1132 ///
1133 /// let generator = Source::simplex(42) // build a generator
1134 /// .displace_z(Source::simplex(43)); // apply the adapter
1135 ///
1136 /// let value = generator.sample(point); // sample the generator
1137 ///
1138 /// point[2] += Source::simplex(43).sample(point);
1139 /// assert_eq!(value, Source::simplex(42).sample(point))
1140 /// ```
1141 #[inline]
1142 fn displace_z<GA>(self, displacement_generator: GA) -> adapters::Displace<3, 2, Self, GA>
1143 where
1144 GA: Generator<3>,
1145 {
1146 adapters::Displace::new(self, displacement_generator)
1147 }
1148}
1149
1150/// A trait representing the specialization of [`Generator<D>`] for 4-dimensional input spaces.
1151///
1152/// Anything implementing this trait must also implement [`Generator<4>`]. This trait exists
1153/// for two reasons: The first is to provide functions that either only make sense for specific
1154/// dimensionalities, or are either too difficult or inefficient to implement in a
1155/// dimension-agnostic manner. The second is to bypass certain limitations of constant generics.
1156pub trait Generator4D: Generator<4> {
1157 /// Create a generator which rotates input points before passing them to the underlying generator.
1158 ///
1159 /// <p style="background:rgba(255,181,77,0.16);padding:0.75em;">
1160 /// <strong>Warning:</strong>
1161 /// The correctness of this adapter is untested. It may not work as expected.
1162 /// </p>
1163 ///
1164 /// Takes an angle in radians for each unique pair of axes in the input space and crates a
1165 /// generator which rotates each input point for the provided angle on the plane spanned by each
1166 /// axis pair, before passing it to the underlying generator. The specific plane of rotation
1167 /// for each angle is as follows:
1168 ///
1169 /// | plane of rotation | corresponding angle |
1170 /// |-------------------|---------------------|
1171 /// | `zw`-plane | `rotation[0]` |
1172 /// | `yw`-plane | `rotation[1]` |
1173 /// | `yz`-plane | `rotation[2]` |
1174 /// | `xw`-plane | `rotation[3]` |
1175 /// | `yz`-plane | `rotation[4]` |
1176 /// | `xy`-plane | `rotation[5]` |
1177 ///
1178 /// # Examples
1179 ///
1180 /// Basic usage:
1181 ///
1182 /// ```
1183 /// # use libnoise::{Source, Generator, Generator4D};
1184 /// let point = [0.2, 0.5, 0.3, 0.7];
1185 ///
1186 /// let generator = Source::simplex(42) // build a generator
1187 /// .rotate([0.4, 1.5, 2.3, 0.9, 1.7, 3.1]); // apply the adapter
1188 ///
1189 /// let value = generator.sample(point); // sample the generator
1190 /// ```
1191 #[inline]
1192 fn rotate(self, rotation: [f64; 6]) -> adapters::Rotate<4, 6, Self> {
1193 adapters::Rotate::new(self, rotation)
1194 }
1195
1196 /// Create a generator providing the results of the underlying generator after displacing the
1197 /// x-coordinate by the result of the provided generator.
1198 ///
1199 /// Creates a generator which is exactly the same as the underlying generator, except the
1200 /// x-coordinate of the input point is first displaced by the result of `displacement_generator`
1201 /// for that point.
1202 ///
1203 /// # Examples
1204 ///
1205 /// Basic usage:
1206 ///
1207 /// ```
1208 /// # use libnoise::{Source, Generator, Generator4D};
1209 /// let mut point = [0.2, 0.5, 0.3, 0.7];
1210 ///
1211 /// let generator = Source::simplex(42) // build a generator
1212 /// .displace_x(Source::simplex(43)); // apply the adapter
1213 ///
1214 /// let value = generator.sample(point); // sample the generator
1215 ///
1216 /// point[0] += Source::simplex(43).sample(point);
1217 /// assert_eq!(value, Source::simplex(42).sample(point))
1218 /// ```
1219 #[inline]
1220 fn displace_x<GA>(self, displacement_generator: GA) -> adapters::Displace<4, 0, Self, GA>
1221 where
1222 GA: Generator<4>,
1223 {
1224 adapters::Displace::new(self, displacement_generator)
1225 }
1226
1227 /// Create a generator providing the results of the underlying generator after displacing the
1228 /// y-coordinate by the result of the provided generator.
1229 ///
1230 /// Creates a generator which is exactly the same as the underlying generator, except the
1231 /// y-coordinate of the input point is first displaced by the result of `displacement_generator`
1232 /// for that point.
1233 ///
1234 /// # Examples
1235 ///
1236 /// Basic usage:
1237 ///
1238 /// ```
1239 /// # use libnoise::{Source, Generator, Generator4D};
1240 /// let mut point = [0.2, 0.5, 0.3, 0.7];
1241 ///
1242 /// let generator = Source::simplex(42) // build a generator
1243 /// .displace_y(Source::simplex(43)); // apply the adapter
1244 ///
1245 /// let value = generator.sample(point); // sample the generator
1246 ///
1247 /// point[1] += Source::simplex(43).sample(point);
1248 /// assert_eq!(value, Source::simplex(42).sample(point))
1249 /// ```
1250 #[inline]
1251 fn displace_y<GA>(self, displacement_generator: GA) -> adapters::Displace<4, 1, Self, GA>
1252 where
1253 GA: Generator<4>,
1254 {
1255 adapters::Displace::new(self, displacement_generator)
1256 }
1257
1258 /// Create a generator providing the results of the underlying generator after displacing the
1259 /// z-coordinate by the result of the provided generator.
1260 ///
1261 /// Creates a generator which is exactly the same as the underlying generator, except the
1262 /// z-coordinate of the input point is first displaced by the result of `displacement_generator`
1263 /// for that point.
1264 ///
1265 /// # Examples
1266 ///
1267 /// Basic usage:
1268 ///
1269 /// ```
1270 /// # use libnoise::{Source, Generator, Generator4D};
1271 /// let mut point = [0.2, 0.5, 0.3, 0.7];
1272 ///
1273 /// let generator = Source::simplex(42) // build a generator
1274 /// .displace_z(Source::simplex(43)); // apply the adapter
1275 ///
1276 /// let value = generator.sample(point); // sample the generator
1277 ///
1278 /// point[2] += Source::simplex(43).sample(point);
1279 /// assert_eq!(value, Source::simplex(42).sample(point))
1280 /// ```
1281 #[inline]
1282 fn displace_z<GA>(self, displacement_generator: GA) -> adapters::Displace<4, 2, Self, GA>
1283 where
1284 GA: Generator<4>,
1285 {
1286 adapters::Displace::new(self, displacement_generator)
1287 }
1288
1289 /// Create a generator providing the results of the underlying generator after displacing the
1290 /// w-coordinate by the result of the provided generator.
1291 ///
1292 /// Creates a generator which is exactly the same as the underlying generator, except the
1293 /// w-coordinate of the input point is first displaced by the result of `displacement_generator`
1294 /// for that point.
1295 ///
1296 /// # Examples
1297 ///
1298 /// Basic usage:
1299 ///
1300 /// ```
1301 /// # use libnoise::{Source, Generator, Generator4D};
1302 /// let mut point = [0.2, 0.5, 0.3, 0.7];
1303 ///
1304 /// let generator = Source::simplex(42) // build a generator
1305 /// .displace_w(Source::simplex(43)); // apply the adapter
1306 ///
1307 /// let value = generator.sample(point); // sample the generator
1308 ///
1309 /// point[3] += Source::simplex(43).sample(point);
1310 /// assert_eq!(value, Source::simplex(42).sample(point))
1311 /// ```
1312 #[inline]
1313 fn displace_w<GA>(self, displacement_generator: GA) -> adapters::Displace<4, 3, Self, GA>
1314 where
1315 GA: Generator<4>,
1316 {
1317 adapters::Displace::new(self, displacement_generator)
1318 }
1319}