Primitive construction is more idiomatique using new.

This commit is contained in:
Sébastien Crozet 2013-06-08 10:09:17 +00:00
parent e9948f55d0
commit 8a1b81f839
8 changed files with 119 additions and 99 deletions

View File

@ -7,9 +7,9 @@ use traits::inv::Inv;
use traits::transpose::Transpose;
use traits::rotation::Rotation;
use traits::delta_transform::DeltaTransform;
use dim1::vec1::{Vec1, vec1};
use dim2::mat2::{Mat2, mat2};
use dim3::mat3::{Mat3, mat3};
use dim1::vec1::Vec1;
use dim2::mat2::Mat2;
use dim3::mat3::Mat3;
use dim3::vec3::{Vec3};
#[deriving(Eq, ToStr)]
@ -30,7 +30,7 @@ pub fn rotmat2<T: Copy + Trigonometric + Neg<T>>(angle: T) -> Rotmat<Mat2<T>>
let sia = angle.sin();
Rotmat
{ submat: mat2(coa, -sia, sia, coa) }
{ submat: Mat2::new(coa, -sia, sia, coa) }
}
pub fn rotmat3<T: Copy + Trigonometric + Neg<T> + One + Sub<T, T> + Add<T, T> +
@ -49,7 +49,7 @@ pub fn rotmat3<T: Copy + Trigonometric + Neg<T> + One + Sub<T, T> + Add<T, T> +
let sin = angle.sin();
Rotmat {
submat: mat3(
submat: Mat3::new(
(sqx + (_1 - sqx) * cos),
(ux * uy * one_m_cos - uz * sin),
(ux * uz * one_m_cos + uy * sin),
@ -68,7 +68,7 @@ impl<T: Div<T, T> + Trigonometric + Neg<T> + Mul<T, T> + Add<T, T> + Copy>
Rotation<Vec1<T>> for Rotmat<Mat2<T>>
{
fn rotation(&self) -> Vec1<T>
{ vec1(-(self.submat.m12 / self.submat.m11).atan()) }
{ Vec1::new(-(self.submat.m12 / self.submat.m11).atan()) }
fn rotated(&self, rot: &Vec1<T>) -> Rotmat<Mat2<T>>
{ rotmat2(rot.x) * *self }

View File

@ -5,16 +5,19 @@ use traits::dim::Dim;
use traits::inv::Inv;
use traits::transpose::Transpose;
use traits::workarounds::rlmul::{RMul, LMul};
use dim1::vec1::{Vec1, vec1};
use dim1::vec1::Vec1;
#[deriving(Eq, ToStr)]
pub struct Mat1<T>
{ m11: T }
pub fn mat1<T:Copy>(m11: T) -> Mat1<T>
impl<T: Copy> Mat1<T>
{
Mat1
{ m11: m11 }
pub fn new(m11: T) -> Mat1<T>
{
Mat1
{ m11: m11 }
}
}
impl<T> Dim for Mat1<T>
@ -26,13 +29,13 @@ impl<T> Dim for Mat1<T>
impl<T:Copy + One> One for Mat1<T>
{
fn one() -> Mat1<T>
{ return mat1(One::one()) }
{ return Mat1::new(One::one()) }
}
impl<T:Copy + Zero> Zero for Mat1<T>
{
fn zero() -> Mat1<T>
{ mat1(Zero::zero()) }
{ Mat1::new(Zero::zero()) }
fn is_zero(&self) -> bool
{ self.m11.is_zero() }
@ -41,19 +44,19 @@ impl<T:Copy + Zero> Zero for Mat1<T>
impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Mat1<T>, Mat1<T>> for Mat1<T>
{
fn mul(&self, other: &Mat1<T>) -> Mat1<T>
{ mat1(self.m11 * other.m11) }
{ Mat1::new(self.m11 * other.m11) }
}
impl<T:Copy + Add<T, T> + Mul<T, T>> RMul<Vec1<T>> for Mat1<T>
{
fn rmul(&self, other: &Vec1<T>) -> Vec1<T>
{ vec1(self.m11 * other.x) }
{ Vec1::new(self.m11 * other.x) }
}
impl<T:Copy + Add<T, T> + Mul<T, T>> LMul<Vec1<T>> for Mat1<T>
{
fn lmul(&self, other: &Vec1<T>) -> Vec1<T>
{ vec1(self.m11 * other.x) }
{ Vec1::new(self.m11 * other.x) }
}
impl<T:Copy + Mul<T, T> + Div<T, T> + Sub<T, T> + Neg<T> + Zero + One>
@ -100,5 +103,5 @@ impl<T:ApproxEq<T>> ApproxEq<T> for Mat1<T>
impl<T:Rand + Copy> Rand for Mat1<T>
{
fn rand<R: Rng>(rng: &mut R) -> Mat1<T>
{ mat1(rng.gen()) }
{ Mat1::new(rng.gen()) }
}

View File

@ -13,8 +13,12 @@ use traits::workarounds::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub}
pub struct Vec1<T>
{ x : T }
pub fn vec1<T:Copy>(x: T) -> Vec1<T>
{ Vec1 {x: x} }
impl<T: Copy> Vec1<T>
{
pub fn new(x: T) -> Vec1<T>
{ Vec1 {x: x} }
}
impl<T> Dim for Vec1<T>
{
@ -25,13 +29,13 @@ impl<T> Dim for Vec1<T>
impl<T:Copy + Add<T,T>> Add<Vec1<T>, Vec1<T>> for Vec1<T>
{
fn add(&self, other: &Vec1<T>) -> Vec1<T>
{ vec1(self.x + other.x) }
{ Vec1::new(self.x + other.x) }
}
impl<T:Copy + Sub<T,T>> Sub<Vec1<T>, Vec1<T>> for Vec1<T>
{
fn sub(&self, other: &Vec1<T>) -> Vec1<T>
{ vec1(self.x - other.x) }
{ Vec1::new(self.x - other.x) }
}
impl<T: Copy + Mul<T, T>>
@ -109,7 +113,7 @@ Norm<T> for Vec1<T>
{ self.sqnorm().sqrt() }
fn normalized(&self) -> Vec1<T>
{ vec1(self.x / self.norm()) }
{ Vec1::new(self.x / self.norm()) }
fn normalize(&mut self) -> T
{
@ -124,7 +128,7 @@ Norm<T> for Vec1<T>
impl<T:Copy + Neg<T>> Neg<Vec1<T>> for Vec1<T>
{
fn neg(&self) -> Vec1<T>
{ vec1(-self.x) }
{ Vec1::new(-self.x) }
}
impl<T:Copy + Zero> Zero for Vec1<T>
@ -132,7 +136,7 @@ impl<T:Copy + Zero> Zero for Vec1<T>
fn zero() -> Vec1<T>
{
let _0 = Zero::zero();
vec1(_0)
Vec1::new(_0)
}
fn is_zero(&self) -> bool
@ -142,7 +146,7 @@ impl<T:Copy + Zero> Zero for Vec1<T>
impl<T: Copy + One> Basis for Vec1<T>
{
fn canonical_basis() -> ~[Vec1<T>]
{ ~[ vec1(One::one()) ] } // FIXME: this should be static
{ ~[ Vec1::new(One::one()) ] } // FIXME: this should be static
fn orthogonal_subspace_basis(&self) -> ~[Vec1<T>]
{ ~[] }
@ -163,5 +167,5 @@ impl<T:ApproxEq<T>> ApproxEq<T> for Vec1<T>
impl<T:Rand + Copy> Rand for Vec1<T>
{
fn rand<R: Rng>(rng: &mut R) -> Vec1<T>
{ vec1(rng.gen()) }
{ Vec1::new(rng.gen()) }
}

View File

@ -6,7 +6,7 @@ use traits::dim::Dim;
use traits::inv::Inv;
use traits::transpose::Transpose;
use traits::workarounds::rlmul::{RMul, LMul};
use dim2::vec2::{Vec2, vec2};
use dim2::vec2::Vec2;
#[deriving(Eq, ToStr)]
pub struct Mat2<T>
@ -15,12 +15,15 @@ pub struct Mat2<T>
m21: T, m22: T
}
pub fn mat2<T:Copy>(m11: T, m12: T, m21: T, m22: T) -> Mat2<T>
impl<T: Copy> Mat2<T>
{
Mat2
pub fn new(m11: T, m12: T, m21: T, m22: T) -> Mat2<T>
{
m11: m11, m12: m12,
m21: m21, m22: m22,
Mat2
{
m11: m11, m12: m12,
m21: m21, m22: m22,
}
}
}
@ -35,8 +38,8 @@ impl<T:Copy + One + Zero> One for Mat2<T>
fn one() -> Mat2<T>
{
let (_0, _1) = (Zero::zero(), One::one());
return mat2(_1, _0,
_0, _1)
return Mat2::new(_1, _0,
_0, _1)
}
}
@ -45,8 +48,8 @@ impl<T:Copy + Zero> Zero for Mat2<T>
fn zero() -> Mat2<T>
{
let _0 = Zero::zero();
return mat2(_0, _0,
_0, _0)
return Mat2::new(_0, _0,
_0, _0)
}
fn is_zero(&self) -> bool
@ -60,11 +63,12 @@ impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Mat2<T>, Mat2<T>> for Mat2<T>
{
fn mul(&self, other: &Mat2<T>) -> Mat2<T>
{
mat2
(self.m11 * other.m11 + self.m12 * other.m21,
self.m11 * other.m12 + self.m12 * other.m22,
self.m21 * other.m11 + self.m22 * other.m21,
self.m21 * other.m12 + self.m22 * other.m22)
Mat2::new(
self.m11 * other.m11 + self.m12 * other.m21,
self.m11 * other.m12 + self.m12 * other.m22,
self.m21 * other.m11 + self.m22 * other.m21,
self.m21 * other.m12 + self.m22 * other.m22
)
}
}
@ -72,7 +76,7 @@ impl<T:Copy + Add<T, T> + Mul<T, T>> RMul<Vec2<T>> for Mat2<T>
{
fn rmul(&self, other: &Vec2<T>) -> Vec2<T>
{
vec2(
Vec2::new(
self.m11 * other.x + self.m12 * other.y,
self.m21 * other.x + self.m22 * other.y
)
@ -83,7 +87,7 @@ impl<T:Copy + Add<T, T> + Mul<T, T>> LMul<Vec2<T>> for Mat2<T>
{
fn lmul(&self, other: &Vec2<T>) -> Vec2<T>
{
vec2(
Vec2::new(
self.m11 * other.x + self.m21 * other.y,
self.m12 * other.x + self.m22 * other.y
)
@ -108,8 +112,8 @@ Inv for Mat2<T>
assert!(!det.is_zero());
*self = mat2(self.m22 / det , -self.m12 / det,
-self.m21 / det, self.m11 / det)
*self = Mat2::new(self.m22 / det , -self.m12 / det,
-self.m21 / det, self.m11 / det)
}
}
@ -117,8 +121,8 @@ impl<T:Copy> Transpose for Mat2<T>
{
fn transposed(&self) -> Mat2<T>
{
mat2(self.m11, self.m21,
self.m12, self.m22)
Mat2::new(self.m11, self.m21,
self.m12, self.m22)
}
fn transpose(&mut self)
@ -152,5 +156,5 @@ impl<T:ApproxEq<T>> ApproxEq<T> for Mat2<T>
impl<T:Rand + Copy> Rand for Mat2<T>
{
fn rand<R: Rng>(rng: &mut R) -> Mat2<T>
{ mat2(rng.gen(), rng.gen(), rng.gen(), rng.gen()) }
{ Mat2::new(rng.gen(), rng.gen(), rng.gen(), rng.gen()) }
}

View File

@ -1,6 +1,6 @@
use std::num::{Zero, One, Algebraic};
use std::rand::{Rand, Rng, RngUtil};
use dim1::vec1::{Vec1, vec1};
use dim1::vec1::Vec1;
use std::cmp::ApproxEq;
use traits::basis::Basis;
use traits::cross::Cross;
@ -18,8 +18,11 @@ pub struct Vec2<T>
y : T
}
pub fn vec2<T:Copy>(x: T, y: T) -> Vec2<T>
{ Vec2 {x: x, y: y} }
impl<T: Copy> Vec2<T>
{
pub fn new(x: T, y: T) -> Vec2<T>
{ Vec2 {x: x, y: y} }
}
impl<T> Dim for Vec2<T>
{
@ -30,13 +33,13 @@ impl<T> Dim for Vec2<T>
impl<T:Copy + Add<T,T>> Add<Vec2<T>, Vec2<T>> for Vec2<T>
{
fn add(&self, other: &Vec2<T>) -> Vec2<T>
{ vec2(self.x + other.x, self.y + other.y) }
{ Vec2::new(self.x + other.x, self.y + other.y) }
}
impl<T:Copy + Sub<T,T>> Sub<Vec2<T>, Vec2<T>> for Vec2<T>
{
fn sub(&self, other: &Vec2<T>) -> Vec2<T>
{ vec2(self.x - other.x, self.y - other.y) }
{ Vec2::new(self.x - other.x, self.y - other.y) }
}
impl<T: Copy + Mul<T, T>>
@ -129,7 +132,7 @@ Norm<T> for Vec2<T>
{
let l = self.norm();
vec2(self.x / l, self.y / l)
Vec2::new(self.x / l, self.y / l)
}
fn normalize(&mut self) -> T
@ -146,13 +149,13 @@ Norm<T> for Vec2<T>
impl<T:Copy + Mul<T, T> + Sub<T, T>> Cross<Vec1<T>> for Vec2<T>
{
fn cross(&self, other : &Vec2<T>) -> Vec1<T>
{ vec1(self.x * other.y - self.y * other.x) }
{ Vec1::new(self.x * other.y - self.y * other.x) }
}
impl<T:Copy + Neg<T>> Neg<Vec2<T>> for Vec2<T>
{
fn neg(&self) -> Vec2<T>
{ vec2(-self.x, -self.y) }
{ Vec2::new(-self.x, -self.y) }
}
impl<T:Copy + Zero> Zero for Vec2<T>
@ -160,7 +163,7 @@ impl<T:Copy + Zero> Zero for Vec2<T>
fn zero() -> Vec2<T>
{
let _0 = Zero::zero();
vec2(_0, _0)
Vec2::new(_0, _0)
}
fn is_zero(&self) -> bool
@ -172,12 +175,12 @@ impl<T: Copy + One + Zero + Neg<T>> Basis for Vec2<T>
fn canonical_basis() -> ~[Vec2<T>]
{
// FIXME: this should be static
~[ vec2(One::one(), Zero::zero()),
vec2(Zero::zero(), One::one()) ]
~[ Vec2::new(One::one(), Zero::zero()),
Vec2::new(Zero::zero(), One::one()) ]
}
fn orthogonal_subspace_basis(&self) -> ~[Vec2<T>]
{ ~[ vec2(-self.y, self.x) ] }
{ ~[ Vec2::new(-self.y, self.x) ] }
}
impl<T:ApproxEq<T>> ApproxEq<T> for Vec2<T>
@ -198,5 +201,5 @@ impl<T:ApproxEq<T>> ApproxEq<T> for Vec2<T>
impl<T:Rand + Copy> Rand for Vec2<T>
{
fn rand<R: Rng>(rng: &mut R) -> Vec2<T>
{ vec2(rng.gen(), rng.gen()) }
{ Vec2::new(rng.gen(), rng.gen()) }
}

View File

@ -6,7 +6,7 @@ use traits::dim::Dim;
use traits::inv::Inv;
use traits::transpose::Transpose;
use traits::workarounds::rlmul::{RMul, LMul};
use dim3::vec3::{Vec3, vec3};
use dim3::vec3::Vec3;
#[deriving(Eq, ToStr)]
pub struct Mat3<T>
@ -16,15 +16,18 @@ pub struct Mat3<T>
m31: T, m32: T, m33: T
}
pub fn mat3<T:Copy>(m11: T, m12: T, m13: T,
m21: T, m22: T, m23: T,
m31: T, m32: T, m33: T) -> Mat3<T>
impl<T: Copy> Mat3<T>
{
Mat3
pub fn new(m11: T, m12: T, m13: T,
m21: T, m22: T, m23: T,
m31: T, m32: T, m33: T) -> Mat3<T>
{
m11: m11, m12: m12, m13: m13,
m21: m21, m22: m22, m23: m23,
m31: m31, m32: m32, m33: m33
Mat3
{
m11: m11, m12: m12, m13: m13,
m21: m21, m22: m22, m23: m23,
m31: m31, m32: m32, m33: m33
}
}
}
@ -39,9 +42,9 @@ impl<T:Copy + One + Zero> One for Mat3<T>
fn one() -> Mat3<T>
{
let (_0, _1) = (Zero::zero(), One::one());
return mat3(_1, _0, _0,
_0, _1, _0,
_0, _0, _1)
return Mat3::new(_1, _0, _0,
_0, _1, _0,
_0, _0, _1)
}
}
@ -50,9 +53,9 @@ impl<T:Copy + Zero> Zero for Mat3<T>
fn zero() -> Mat3<T>
{
let _0 = Zero::zero();
return mat3(_0, _0, _0,
_0, _0, _0,
_0, _0, _0)
return Mat3::new(_0, _0, _0,
_0, _0, _0,
_0, _0, _0)
}
fn is_zero(&self) -> bool
@ -67,7 +70,7 @@ impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Mat3<T>, Mat3<T>> for Mat3<T>
{
fn mul(&self, other: &Mat3<T>) -> Mat3<T>
{
mat3(
Mat3::new(
self.m11 * other.m11 + self.m12 * other.m21 + self.m13 * other.m31,
self.m11 * other.m12 + self.m12 * other.m22 + self.m13 * other.m32,
self.m11 * other.m13 + self.m12 * other.m23 + self.m13 * other.m33,
@ -87,7 +90,7 @@ impl<T:Copy + Add<T, T> + Mul<T, T>> RMul<Vec3<T>> for Mat3<T>
{
fn rmul(&self, other: &Vec3<T>) -> Vec3<T>
{
vec3(
Vec3::new(
self.m11 * other.x + self.m12 * other.y + self.m13 * other.z,
self.m21 * other.x + self.m22 * other.y + self.m33 * other.z,
self.m31 * other.x + self.m32 * other.y + self.m33 * other.z
@ -99,7 +102,7 @@ impl<T:Copy + Add<T, T> + Mul<T, T>> LMul<Vec3<T>> for Mat3<T>
{
fn lmul(&self, other: &Vec3<T>) -> Vec3<T>
{
vec3(
Vec3::new(
self.m11 * other.x + self.m21 * other.y + self.m31 * other.z,
self.m12 * other.x + self.m22 * other.y + self.m32 * other.z,
self.m13 * other.x + self.m23 * other.y + self.m33 * other.z
@ -131,7 +134,7 @@ Inv for Mat3<T>
assert!(!det.is_zero());
*self = mat3(
*self = Mat3::new(
(minor_m22_m33 / det),
((self.m13 * self.m32 - self.m33 * self.m12) / det),
((self.m12 * self.m23 - self.m22 * self.m13) / det),
@ -151,9 +154,9 @@ impl<T:Copy> Transpose for Mat3<T>
{
fn transposed(&self) -> Mat3<T>
{
mat3(self.m11, self.m21, self.m31,
self.m12, self.m22, self.m32,
self.m13, self.m23, self.m33)
Mat3::new(self.m11, self.m21, self.m31,
self.m12, self.m22, self.m32,
self.m13, self.m23, self.m33)
}
fn transpose(&mut self)
@ -204,8 +207,8 @@ impl<T:Rand + Copy> Rand for Mat3<T>
{
fn rand<R: Rng>(rng: &mut R) -> Mat3<T>
{
mat3(rng.gen(), rng.gen(), rng.gen(),
rng.gen(), rng.gen(), rng.gen(),
rng.gen(), rng.gen(), rng.gen())
Mat3::new(rng.gen(), rng.gen(), rng.gen(),
rng.gen(), rng.gen(), rng.gen(),
rng.gen(), rng.gen(), rng.gen())
}
}

View File

@ -18,8 +18,11 @@ pub struct Vec3<T>
z : T
}
pub fn vec3<T:Copy>(x: T, y: T, z: T) -> Vec3<T>
{ Vec3 {x: x, y: y, z: z} }
impl<T: Copy> Vec3<T>
{
pub fn new(x: T, y: T, z: T) -> Vec3<T>
{ Vec3 {x: x, y: y, z: z} }
}
impl<T> Dim for Vec3<T>
{
@ -30,13 +33,13 @@ impl<T> Dim for Vec3<T>
impl<T:Copy + Add<T,T>> Add<Vec3<T>, Vec3<T>> for Vec3<T>
{
fn add(&self, other: &Vec3<T>) -> Vec3<T>
{ vec3(self.x + other.x, self.y + other.y, self.z + other.z) }
{ Vec3::new(self.x + other.x, self.y + other.y, self.z + other.z) }
}
impl<T:Copy + Sub<T,T>> Sub<Vec3<T>, Vec3<T>> for Vec3<T>
{
fn sub(&self, other: &Vec3<T>) -> Vec3<T>
{ vec3(self.x - other.x, self.y - other.y, self.z - other.z) }
{ Vec3::new(self.x - other.x, self.y - other.y, self.z - other.z) }
}
impl<T: Copy + Mul<T, T>>
@ -113,7 +116,7 @@ impl<T: Copy + Add<T, T>> Translation<Vec3<T>> for Vec3<T>
impl<T:Copy + Neg<T>> Neg<Vec3<T>> for Vec3<T>
{
fn neg(&self) -> Vec3<T>
{ vec3(-self.x, -self.y, -self.z) }
{ Vec3::new(-self.x, -self.y, -self.z) }
}
impl<T:Copy + Mul<T, T> + Add<T, T>> Dot<T> for Vec3<T>
@ -141,7 +144,7 @@ Norm<T> for Vec3<T>
{
let l = self.norm();
vec3(self.x / l, self.y / l, self.z / l)
Vec3::new(self.x / l, self.y / l, self.z / l)
}
fn normalize(&mut self) -> T
@ -160,7 +163,7 @@ impl<T:Copy + Mul<T, T> + Sub<T, T>> Cross<Vec3<T>> for Vec3<T>
{
fn cross(&self, other : &Vec3<T>) -> Vec3<T>
{
vec3(
Vec3::new(
self.y * other.z - self.z * other.y,
self.z * other.x - self.x * other.z,
self.x * other.y - self.y * other.x
@ -173,7 +176,7 @@ impl<T:Copy + Zero> Zero for Vec3<T>
fn zero() -> Vec3<T>
{
let _0 = Zero::zero();
vec3(_0, _0, _0)
Vec3::new(_0, _0, _0)
}
fn is_zero(&self) -> bool
@ -187,18 +190,18 @@ Basis for Vec3<T>
fn canonical_basis() -> ~[Vec3<T>]
{
// FIXME: this should be static
~[ vec3(One::one(), Zero::zero(), Zero::zero()),
vec3(Zero::zero(), One::one(), Zero::zero()),
vec3(Zero::zero(), Zero::zero(), One::one()) ]
~[ Vec3::new(One::one(), Zero::zero(), Zero::zero()),
Vec3::new(Zero::zero(), One::one(), Zero::zero()),
Vec3::new(Zero::zero(), Zero::zero(), One::one()) ]
}
fn orthogonal_subspace_basis(&self) -> ~[Vec3<T>]
{
let a =
if (abs(self.x) > abs(self.y))
{ vec3(self.z, Zero::zero(), -self.x).normalized() }
{ Vec3::new(self.z, Zero::zero(), -self.x).normalized() }
else
{ vec3(Zero::zero(), -self.z, self.y).normalized() };
{ Vec3::new(Zero::zero(), -self.z, self.y).normalized() };
~[ a, a.cross(self) ]
}
@ -227,5 +230,5 @@ impl<T:ApproxEq<T>> ApproxEq<T> for Vec3<T>
impl<T:Copy + Rand> Rand for Vec3<T>
{
fn rand<R: Rng>(rng: &mut R) -> Vec3<T>
{ vec3(rng.gen(), rng.gen(), rng.gen()) }
{ Vec3::new(rng.gen(), rng.gen(), rng.gen()) }
}

View File

@ -11,7 +11,7 @@ use traits::rotation::Rotation;
// #[test]
// use traits::dim::d7;
#[test]
use dim1::vec1::vec1;
use dim1::vec1::Vec1;
#[test]
use dim1::mat1::Mat1;
#[test]
@ -57,7 +57,7 @@ fn test_rotation2()
for 10000.times
{
let randmat = One::one::<Rotmat<Mat2<f64>>>();
let ang = &vec1(abs::<f64>(random()) % Real::pi());
let ang = &Vec1::new(abs::<f64>(random()) % Real::pi());
assert!(randmat.rotated(ang).rotation().approx_eq(ang));
}