Implement post-transform coefficients
This commit is contained in:
@@ -17,21 +17,21 @@ const IMAGE_DIMENSION: UVec2 = uvec2(600, 600);
|
|||||||
|
|
||||||
pub fn main() -> Result<()> {
|
pub fn main() -> Result<()> {
|
||||||
let transforms = [
|
let transforms = [
|
||||||
|
{
|
||||||
// F_0: (x / 2, y / 2)
|
// F_0: (x / 2, y / 2)
|
||||||
Transform::new(
|
let coefficients = Affine2::from_coefficients(0.5, 0.0, 0.0, 0.0, 0.5, 0.0);
|
||||||
Affine2::from_coefficients(0.5, 0.0, 0.0, 0.0, 0.5, 0.0),
|
Transform::new(coefficients, Affine2::IDENTITY, uvec2(0, 1))
|
||||||
uvec2(0, 1),
|
},
|
||||||
),
|
{
|
||||||
// F_1: ((x + 1) / 2, y / 2)
|
// F_1: ((x + 1) / 2, y / 2)
|
||||||
Transform::new(
|
let coefficients = Affine2::from_coefficients(0.5, 0.0, 0.5, 0.0, 0.5, 0.0);
|
||||||
Affine2::from_coefficients(0.5, 0.0, 0.5, 0.0, 0.5, 0.0),
|
Transform::new(coefficients, Affine2::IDENTITY, uvec2(0, 1))
|
||||||
uvec2(0, 1),
|
},
|
||||||
),
|
{
|
||||||
// F_2: (x / 2, (y + 1) / 2)
|
// F_2: (x / 2, (y + 1) / 2)
|
||||||
Transform::new(
|
let coefficients = Affine2::from_coefficients(0.5, 0.0, 0.0, 0.0, 0.5, 0.5);
|
||||||
Affine2::from_coefficients(0.5, 0.0, 0.0, 0.0, 0.5, 0.5),
|
Transform::new(coefficients, Affine2::IDENTITY, uvec2(0, 1))
|
||||||
uvec2(0, 1),
|
},
|
||||||
),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
let weights = [1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0];
|
let weights = [1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0];
|
||||||
|
|||||||
@@ -13,14 +13,16 @@ use rand::Rng;
|
|||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Transform {
|
pub struct Transform {
|
||||||
coefficients: Affine2,
|
coefficients: Affine2,
|
||||||
|
coefficients_post: Affine2,
|
||||||
variation_range: UVec2,
|
variation_range: UVec2,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Transform {
|
impl Transform {
|
||||||
/// Create a new transform from an affine transformation matrix
|
/// Create a new transform from an affine transformation matrix
|
||||||
pub fn new(coefficients: Affine2, variation_range: UVec2) -> Self {
|
pub fn new(coefficients: Affine2, coefficients_post: Affine2, variation_range: UVec2) -> Self {
|
||||||
Transform {
|
Transform {
|
||||||
coefficients,
|
coefficients,
|
||||||
|
coefficients_post,
|
||||||
variation_range,
|
variation_range,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,6 +45,53 @@ impl Transform {
|
|||||||
point_output += variation.transform_point(point, rng, &self.coefficients)
|
point_output += variation.transform_point(point, rng, &self.coefficients)
|
||||||
}
|
}
|
||||||
|
|
||||||
point_output
|
self.coefficients_post.transform_point2(point)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use crate::rng::xoshiro256starstar_from_seed;
|
||||||
|
use crate::transform::Transform;
|
||||||
|
use crate::variation::{Variation, VariationKind};
|
||||||
|
use glam::{Affine2, uvec2, vec2};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn transform_scaling() {
|
||||||
|
let scale_coefficients = vec2(2.0, 0.5);
|
||||||
|
let transform = Transform::new(
|
||||||
|
Affine2::from_scale(scale_coefficients),
|
||||||
|
Affine2::IDENTITY,
|
||||||
|
uvec2(0, 1),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut rng = xoshiro256starstar_from_seed([0; 32]);
|
||||||
|
let variations = [Variation::IDENTITY];
|
||||||
|
let point = vec2(1.0, 1.0);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
transform.transform_point(&mut rng, &variations, point),
|
||||||
|
scale_coefficients
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn transform_scaling_post() {
|
||||||
|
let scale_coefficients = vec2(2.0, 0.5);
|
||||||
|
let transform_pdj = Transform::new(Affine2::IDENTITY, Affine2::IDENTITY, uvec2(0, 1));
|
||||||
|
let transform_pdj_post = Transform::new(
|
||||||
|
Affine2::IDENTITY,
|
||||||
|
Affine2::from_scale(scale_coefficients),
|
||||||
|
uvec2(0, 1),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut rng = xoshiro256starstar_from_seed([0; 32]);
|
||||||
|
let variations = [Variation::new(VariationKind::Pdj, 1.0, [0.0f32; 4].into())];
|
||||||
|
let point = vec2(1.0, 1.0);
|
||||||
|
|
||||||
|
let point_pdj = transform_pdj.transform_point(&mut rng, &variations, point);
|
||||||
|
let point_pdj_post = transform_pdj_post.transform_point(&mut rng, &variations, point);
|
||||||
|
|
||||||
|
assert_eq!(point_pdj * scale_coefficients, point_pdj_post);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,12 @@ use rand::{Rng, RngExt};
|
|||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct VariationParams([f32; 4]);
|
pub struct VariationParams([f32; 4]);
|
||||||
|
|
||||||
|
impl From<[f32; 4]> for VariationParams {
|
||||||
|
fn from(v: [f32; 4]) -> Self {
|
||||||
|
VariationParams(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Enum for all supported variation types
|
/// Enum for all supported variation types
|
||||||
///
|
///
|
||||||
/// ID numbers are chosen to match the variation identifier also used by `flam3`
|
/// ID numbers are chosen to match the variation identifier also used by `flam3`
|
||||||
|
|||||||
Reference in New Issue
Block a user