use crate::prelude::*;
use approx::{AbsDiffEq, UlpsEq};
use num_traits::float::FloatCore;
pub fn test_xyz<T: HasXYZ + Approx>(x: T::Scalar, y: T::Scalar, z: T::Scalar) {
let v0 = T::new_3d(x, y, z);
assert_eq!(v0.x(), x);
assert_eq!(v0.y(), y);
assert_eq!(v0.z(), z);
let mult = 6.0.into();
let mut v1 = v0;
*v1.x_mut() = x * mult;
*v1.y_mut() = y * mult;
*v1.z_mut() = z * mult;
assert_eq!(v1.x(), x * mult);
assert_eq!(v1.y(), y * mult);
assert_eq!(v1.z(), z * mult);
v1.set_x(x * mult);
v1.set_y(y * mult);
v1.set_z(z * mult);
assert_eq!(v1.x(), x * mult);
assert_eq!(v1.y(), y * mult);
assert_eq!(v1.z(), z * mult);
let v0 = T::new_3d(T::Scalar::ONE, T::Scalar::TWO, T::Scalar::THREE);
let v1 = T::new_3d(T::Scalar::ONE, T::Scalar::TWO, T::Scalar::THREE);
assert!(v0.is_ulps_eq(
v1,
T::Scalar::default_epsilon(),
T::Scalar::default_max_ulps()
));
assert!(v0.is_abs_diff_eq(v1, T::Scalar::default_epsilon()));
}
pub fn test_gxyz<T: GenericVector3>(x: T::Scalar, y: T::Scalar, z: T::Scalar) {
let v0 = T::new_3d(x, y, z);
assert_eq!(v0.x(), x);
assert_eq!(v0.y(), y);
assert_eq!(v0.z(), z);
let v1 = v0.to_2d();
assert_eq!(v1.x(), x);
assert_eq!(v1.y(), y);
let mult = 6.0.into();
let mut v1 = v0;
v1.set_x(x * mult);
v1.set_y(y * mult);
v1.set_z(z * mult);
assert_eq!(v1.x(), x * mult);
assert_eq!(v1.y(), y * mult);
assert_eq!(v1.z(), z * mult);
let center = (v0 + v1) / T::Scalar::TWO;
assert!(center.x().ulps_eq(
&((x + x * 6.0.into()) / 2.0.into()),
T::Scalar::default_epsilon(),
T::Scalar::default_max_ulps()
));
assert!(center.y().ulps_eq(
&((y + y * 6.0.into()) / 2.0.into()),
T::Scalar::default_epsilon(),
T::Scalar::default_max_ulps()
));
assert!(center.z().ulps_eq(
&((z + z * 6.0.into()) / 2.0.into()),
T::Scalar::default_epsilon(),
T::Scalar::default_max_ulps()
));
let x = v0.x();
let y = v0.y();
let z = v0.z();
let min_value = T::new_3d(1.0.into(), 2.0.into(), 3.0.into());
let max_value = T::new_3d(8.0.into(), 9.0.into(), 10.0.into());
let min_vec = v0.min(min_value);
assert!(min_vec.x().ulps_eq(
&x.min(min_value.x()),
T::Scalar::default_epsilon(),
T::Scalar::default_max_ulps()
));
assert!(min_vec.y().ulps_eq(
&y.min(min_value.y()),
T::Scalar::default_epsilon(),
T::Scalar::default_max_ulps()
));
assert!(min_vec.z().ulps_eq(
&z.min(min_value.z()),
T::Scalar::default_epsilon(),
T::Scalar::default_max_ulps()
));
let max_vec = v0.max(max_value);
assert!(max_vec.x().ulps_eq(
&x.max(max_value.x()),
T::Scalar::default_epsilon(),
T::Scalar::default_max_ulps()
));
assert!(max_vec.y().ulps_eq(
&y.max(max_value.y()),
T::Scalar::default_epsilon(),
T::Scalar::default_max_ulps()
));
assert!(max_vec.z().ulps_eq(
&z.max(max_value.z()),
T::Scalar::default_epsilon(),
T::Scalar::default_max_ulps()
));
let clamped_vec = v0.clamp(min_value, max_value);
assert!(clamped_vec.x().ulps_eq(
&x.clamp(min_value.x(), max_value.x()),
T::Scalar::default_epsilon(),
T::Scalar::default_max_ulps()
));
assert!(clamped_vec.y().ulps_eq(
&y.clamp(min_value.y(), max_value.y()),
T::Scalar::default_epsilon(),
T::Scalar::default_max_ulps()
));
assert!(clamped_vec.z().ulps_eq(
&z.clamp(min_value.z(), max_value.z()),
T::Scalar::default_epsilon(),
T::Scalar::default_max_ulps()
));
let mut v0 = T::new_3d(x, y, z);
let five = 5.0.into();
v0[0] *= five;
v0[1] *= five;
v0[2] *= five;
assert_eq!(v0[0], x * five);
assert_eq!(v0[1], y * five);
assert_eq!(v0[2], z * five);
}
pub fn test_generic_xyz<T: GenericVector3>(
x: T::Scalar,
y: T::Scalar,
z: T::Scalar,
_w: T::Scalar, epsilon: T::Scalar,
) {
let v0 = T::new_3d(x, y, z);
assert_eq!(v0.x(), x);
assert_eq!(v0.y(), y);
assert_eq!(v0.z(), z);
let mut v1 = v0;
let mult: T::Scalar = 6.0.into();
v1.set_x(v1.x() * mult);
v1.set_y(v1.y() * mult);
v1.set_z(v1.z() * mult);
assert_eq!(v1.x(), x * mult);
assert_eq!(v1.y(), y * mult);
assert_eq!(v1.z(), z * mult);
let v2 = (v0 * mult).to_2d();
assert_eq!(v2.x(), x * mult);
assert_eq!(v2.y(), y * mult);
assert!(!v0.is_ulps_eq(
v1,
T::Scalar::default_epsilon(),
T::Scalar::default_max_ulps()
));
assert!(!v0.is_abs_diff_eq(v1, T::Scalar::default_epsilon()));
let magnitude = v0.magnitude();
let magnitude_sq = v0.magnitude_sq();
assert!(
(magnitude * magnitude - magnitude_sq).abs() < epsilon,
"{} != {}",
magnitude * magnitude,
magnitude_sq
);
let dot = v0.dot(v1);
assert_eq!(dot, (x * x * mult + y * y * mult + z * z * mult));
let cross_product = v0.cross(v1);
assert_eq!(
cross_product,
T::new_3d(T::Scalar::ZERO, T::Scalar::ZERO, T::Scalar::ZERO)
);
let distance = v0.distance(v1);
let distance_sq = v0.distance_sq(v1);
assert!(
(distance * distance - distance_sq).abs() < epsilon,
"{} != {}",
distance * distance,
distance_sq
);
let normalized = v0.normalize();
assert!(
(normalized.magnitude() - T::Scalar::ONE) < epsilon,
"{} != {}",
normalized.magnitude(),
T::Scalar::ONE
);
if let Some(v) = v0.try_normalize(T::Scalar::EPSILON) {
assert!(
(v.magnitude() - T::Scalar::ONE) < epsilon,
"{} != {}",
v.magnitude(),
T::Scalar::from(1.0)
)
};
let v0 = T::new_3d(T::Scalar::ZERO, T::Scalar::ZERO, T::Scalar::ZERO);
assert!(v0.try_normalize(T::Scalar::EPSILON).is_none());
assert!(v0.is_ulps_eq(
v0,
T::Scalar::default_epsilon(),
T::Scalar::default_max_ulps()
));
assert!(v0.is_abs_diff_eq(v0, T::Scalar::default_epsilon()));
let v0 = T::splat(T::Scalar::THREE);
assert!(v0.is_ulps_eq(
T::new(T::Scalar::THREE, T::Scalar::THREE, T::Scalar::THREE),
T::Scalar::default_epsilon(),
T::Scalar::default_max_ulps()
));
let _7: T::Scalar = 7.0.into();
let v0 = T::new_2d(T::Scalar::nan(), _7);
assert!(!v0.is_finite());
let v0 = T::new_3d(_7, T::Scalar::nan(), _7);
assert!(!v0.is_finite());
let v0 = T::new_3d(_7, _7, T::Scalar::nan());
assert!(!v0.is_finite());
let v0 = T::new_2d(T::Scalar::infinity(), _7);
assert!(!v0.is_finite());
let v0 = T::new_3d(_7, T::Scalar::infinity(), _7);
assert!(!v0.is_finite());
let v0 = T::new_3d(_7, _7, T::Scalar::infinity());
assert!(!v0.is_finite());
}
pub fn test_simd_conversion<T: SimdUpgradable>() {
let vec3 = T::new_3d(1.0.into(), 2.0.into(), 3.0.into());
let vec3a = vec3.to_simd();
assert_eq!(vec3a.x(), vec3.x());
assert_eq!(vec3a.y(), vec3.y());
assert_eq!(vec3a.z(), vec3.z());
let vec3_round_trip = T::from_simd(vec3a);
assert_eq!(vec3_round_trip.x(), vec3.x());
assert_eq!(vec3_round_trip.y(), vec3.y());
assert_eq!(vec3_round_trip.z(), vec3.z());
}