1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
use crate::noise_fns::NoiseFn;
/// Noise function that scales the coordinates of the input value before
/// returning the output value from the source function.
///
/// The get() method multiplies the coordinates of the input value with a
/// scaling factor before returning the output value from the source function.
pub struct ScalePoint<Source> {
/// Source function that outputs a value
pub source: Source,
/// Scaling factor applied to the _x_ coordinate of the input value. The
/// default scaling factor is set to 1.0.
pub x_scale: f64,
/// Scaling factor applied to the _y_ coordinate of the input value. The
/// default scaling factor is set to 1.0.
pub y_scale: f64,
/// Scaling factor applied to the _z_ coordinate of the input value. The
/// default scaling factor is set to 1.0.
pub z_scale: f64,
/// Scaling factor applied to the _u_ coordinate of the input value. The
/// default scaling factor is set to 1.0.
pub u_scale: f64,
}
impl<Source> ScalePoint<Source> {
pub fn new(source: Source) -> Self {
Self {
source,
x_scale: 1.0,
y_scale: 1.0,
z_scale: 1.0,
u_scale: 1.0,
}
}
/// Sets the scaling factor to apply to the _x_ coordinate of the input
/// value.
pub fn set_x_scale(self, x_scale: f64) -> Self {
Self { x_scale, ..self }
}
/// Sets the scaling factor to apply to the _x_ coordinate of the input
/// value.
pub fn set_y_scale(self, y_scale: f64) -> Self {
Self { y_scale, ..self }
}
/// Sets the scaling factor to apply to the _x_ coordinate of the input
/// value.
pub fn set_z_scale(self, z_scale: f64) -> Self {
Self { z_scale, ..self }
}
/// Sets the scaling factor to apply to the _x_ coordinate of the input
/// value.
pub fn set_u_scale(self, u_scale: f64) -> Self {
Self { u_scale, ..self }
}
/// Sets the scaling factor to apply to all coordinates of the input value.
pub fn set_scale(self, scale: f64) -> Self {
Self {
x_scale: scale,
y_scale: scale,
z_scale: scale,
u_scale: scale,
..self
}
}
/// Sets the individual scaling factors to apply to each coordinate of the
/// input value.
pub fn set_all_scales(self, x_scale: f64, y_scale: f64, z_scale: f64, u_scale: f64) -> Self {
Self {
x_scale,
y_scale,
z_scale,
u_scale,
..self
}
}
}
impl<Source> NoiseFn<[f64; 2]> for ScalePoint<Source>
where
Source: NoiseFn<[f64; 2]>,
{
fn get(&self, point: [f64; 2]) -> f64 {
self.source
.get([point[0] * self.x_scale, point[1] * self.y_scale])
}
}
impl<Source> NoiseFn<[f64; 3]> for ScalePoint<Source>
where
Source: NoiseFn<[f64; 3]>,
{
fn get(&self, point: [f64; 3]) -> f64 {
self.source.get([
point[0] * self.x_scale,
point[1] * self.y_scale,
point[2] * self.z_scale,
])
}
}
impl<Source> NoiseFn<[f64; 4]> for ScalePoint<Source>
where
Source: NoiseFn<[f64; 4]>,
{
fn get(&self, point: [f64; 4]) -> f64 {
self.source.get([
point[0] * self.x_scale,
point[1] * self.y_scale,
point[2] * self.z_scale,
point[3] * self.u_scale,
])
}
}
#[cfg(test)]
mod tests {
use super::super::super::Perlin;
use super::*;
#[test]
fn test_pass_by_ref() {
let source = Perlin::new();
let transformed_by_ref = ScalePoint::new(&source)
.set_x_scale(0.8)
.set_y_scale(0.1)
.set_z_scale(0.4)
.set_u_scale(0.2);
let mut zero_count = 0;
for x in 0..10 {
for y in 0..10 {
for z in 0..10 {
for u in 0..10 {
let point: [f64; 4] = [
(x as f64) / 10.0,
(y as f64) / 10.0,
(z as f64) / 10.0,
(u as f64) / 10.0,
];
let source_value = source.get(point);
let transform_value = transformed_by_ref.get(point);
if source_value != 0.0 {
assert_ne!(source_value, transform_value);
} else {
zero_count += 1;
}
}
}
}
}
assert!(zero_count < 10 * 10 * 10 * 10);
}
}