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}