affine-rs 0.1.0

Two-dimensional affine transformations for Rust
Documentation
#![allow(clippy::float_cmp)]

use affine_rs::{Affine, AffineError};

#[test]
fn determinant_describes_orientation_and_degeneracy() {
    assert_eq!(Affine::scale(2.0, 3.0).determinant(), 6.0);
    assert!(Affine::scale(2.0, 3.0).is_proper());
    assert!(Affine::scale(0.0, 3.0).is_degenerate());
    assert!(!Affine::scale(-2.0, 3.0).is_proper());
}

#[test]
fn reports_geometric_properties() {
    assert!(Affine::IDENTITY.is_identity());
    assert!(Affine::scale(2.5, 6.1).is_rectilinear());
    assert!(Affine::rotation(90.0).is_rectilinear());
    assert!(!Affine::shear(4.0, -1.0).is_rectilinear());

    assert!(Affine::rotation(-26.0).is_conformal());
    assert!(!Affine::shear(4.0, -1.0).is_conformal());
    assert!(Affine::rotation(-26.0).is_orthonormal());
    assert!(!Affine::scale(2.5, 6.1).is_orthonormal());

    assert_eq!(
        Affine::new(2.0, 3.0, 4.0, 5.0, 6.0, 7.0).column_vectors(),
        [[2.0, 5.0], [3.0, 6.0], [4.0, 7.0]]
    );
}

#[test]
fn computes_scaling_eccentricity_and_rotation() {
    let expected_eccentricity = 5.0_f64.sqrt() / 3.0;
    assert!((Affine::scale(2.0, 3.0).eccentricity() - expected_eccentricity).abs() < 1e-12);
    assert!((Affine::rotation(30.0).rotation_angle().unwrap() - 30.0).abs() < 1e-12);
    assert_eq!(
        Affine::scale(-1.0, 1.0).rotation_angle(),
        Err(AffineError::UndefinedRotation)
    );
}