use glam::Vec3;
#[inline]
#[must_use]
pub fn hand_drawn_jitter(position: Vec3, noise_direction: Vec3, amplitude: f32) -> Vec3 {
position + noise_direction * amplitude
}
#[inline]
#[must_use]
pub fn sketch_wobble(position: Vec3, amplitude: f32, frequency: f32) -> Vec3 {
let f = frequency.max(0.0);
let offset = Vec3::new(
(position.y * f).sin(),
(position.z * f).sin(),
(position.x * f).sin(),
);
position + offset * amplitude
}
#[inline]
#[must_use]
pub fn line_boil(position: Vec3, time: f32, amplitude: f32, frequency: f32) -> Vec3 {
let f = frequency.max(0.0);
let offset = Vec3::new(
(position.y * f + time * 3.0).sin(),
(position.z * f + time * 3.7).sin(),
(position.x * f + time * 4.1).sin(),
);
position + offset * amplitude
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn hand_drawn_jitter_zero_amplitude_no_change() {
let p = Vec3::new(1.0, 2.0, 3.0);
let out = hand_drawn_jitter(p, Vec3::new(0.5, -0.3, 0.7), 0.0);
assert!((out - p).length() < 1e-6);
}
#[test]
fn hand_drawn_jitter_zero_noise_no_change() {
let p = Vec3::new(1.0, 2.0, 3.0);
let out = hand_drawn_jitter(p, Vec3::ZERO, 0.5);
assert!((out - p).length() < 1e-6);
}
#[test]
fn hand_drawn_jitter_scales_linearly() {
let p = Vec3::ZERO;
let n = Vec3::new(1.0, 0.0, 0.0);
let out = hand_drawn_jitter(p, n, 0.5);
assert!((out - Vec3::new(0.5, 0.0, 0.0)).length() < 1e-6);
}
#[test]
fn sketch_wobble_zero_amplitude_no_change() {
let p = Vec3::new(1.0, 2.0, 3.0);
let out = sketch_wobble(p, 0.0, 5.0);
assert!((out - p).length() < 1e-6);
}
#[test]
fn sketch_wobble_zero_frequency_returns_unchanged() {
let p = Vec3::new(1.0, 2.0, 3.0);
let out = sketch_wobble(p, 0.5, 0.0);
assert!((out - p).length() < 1e-6);
}
#[test]
fn sketch_wobble_deterministic() {
let p = Vec3::new(1.0, 2.0, 3.0);
let a = sketch_wobble(p, 0.3, 2.0);
let b = sketch_wobble(p, 0.3, 2.0);
assert!((a - b).length() < 1e-6);
}
#[test]
fn line_boil_time_changes_output() {
let p = Vec3::new(1.0, 2.0, 3.0);
let a = line_boil(p, 0.0, 0.5, 2.0);
let b = line_boil(p, 1.0, 0.5, 2.0);
assert!((a - b).length() > 1e-3, "time should change output");
}
#[test]
fn line_boil_zero_amplitude_no_change() {
let p = Vec3::new(1.0, 2.0, 3.0);
let out = line_boil(p, 5.0, 0.0, 2.0);
assert!((out - p).length() < 1e-6);
}
}