Remove Float bound from MetricSpace and InnerSpace; move Float bound to individual methods
This makes it possible to call methods like `dot` on integers.
This commit is contained in:
parent
9dcd9fc3dd
commit
8d0e3f4eae
2 changed files with 31 additions and 26 deletions
|
@ -195,7 +195,7 @@ where
|
||||||
/// Examples are vectors, points, and quaternions.
|
/// Examples are vectors, points, and quaternions.
|
||||||
pub trait MetricSpace: Sized {
|
pub trait MetricSpace: Sized {
|
||||||
/// The metric to be returned by the `distance` function.
|
/// The metric to be returned by the `distance` function.
|
||||||
type Metric: Float;
|
type Metric;
|
||||||
|
|
||||||
/// Returns the squared distance.
|
/// Returns the squared distance.
|
||||||
///
|
///
|
||||||
|
@ -205,7 +205,7 @@ pub trait MetricSpace: Sized {
|
||||||
fn distance2(self, other: Self) -> Self::Metric;
|
fn distance2(self, other: Self) -> Self::Metric;
|
||||||
|
|
||||||
/// The distance between two values.
|
/// The distance between two values.
|
||||||
fn distance(self, other: Self) -> Self::Metric {
|
fn distance(self, other: Self) -> Self::Metric where Self::Metric: Float {
|
||||||
Float::sqrt(Self::distance2(self, other))
|
Float::sqrt(Self::distance2(self, other))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,6 @@ pub trait MetricSpace: Sized {
|
||||||
/// Examples include vectors and quaternions.
|
/// Examples include vectors and quaternions.
|
||||||
pub trait InnerSpace: VectorSpace
|
pub trait InnerSpace: VectorSpace
|
||||||
where
|
where
|
||||||
Self::Scalar: Float,
|
|
||||||
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
||||||
Self: MetricSpace<Metric = <Self as VectorSpace>::Scalar>
|
Self: MetricSpace<Metric = <Self as VectorSpace>::Scalar>
|
||||||
{
|
{
|
||||||
|
@ -242,29 +241,11 @@ where
|
||||||
Self::dot(self, self)
|
Self::dot(self, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The distance from the tail to the tip of the vector.
|
|
||||||
#[inline]
|
|
||||||
fn magnitude(self) -> Self::Scalar {
|
|
||||||
Float::sqrt(self.magnitude2())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the angle between two vectors in radians.
|
/// Returns the angle between two vectors in radians.
|
||||||
fn angle(self, other: Self) -> Rad<Self::Scalar> where Self::Scalar: BaseFloat {
|
fn angle(self, other: Self) -> Rad<Self::Scalar> where Self::Scalar: BaseFloat {
|
||||||
Rad::acos(Self::dot(self, other) / (self.magnitude() * other.magnitude()))
|
Rad::acos(Self::dot(self, other) / (self.magnitude() * other.magnitude()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a vector with the same direction, but with a magnitude of `1`.
|
|
||||||
#[inline]
|
|
||||||
fn normalize(self) -> Self {
|
|
||||||
self.normalize_to(Self::Scalar::one())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a vector with the same direction and a given magnitude.
|
|
||||||
#[inline]
|
|
||||||
fn normalize_to(self, magnitude: Self::Scalar) -> Self {
|
|
||||||
self * (magnitude / self.magnitude())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the
|
/// Returns the
|
||||||
/// [vector projection](https://en.wikipedia.org/wiki/Vector_projection)
|
/// [vector projection](https://en.wikipedia.org/wiki/Vector_projection)
|
||||||
/// of the current inner space projected onto the supplied argument.
|
/// of the current inner space projected onto the supplied argument.
|
||||||
|
@ -272,6 +253,24 @@ where
|
||||||
fn project_on(self, other: Self) -> Self {
|
fn project_on(self, other: Self) -> Self {
|
||||||
other * (self.dot(other) / other.magnitude2())
|
other * (self.dot(other) / other.magnitude2())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The distance from the tail to the tip of the vector.
|
||||||
|
#[inline]
|
||||||
|
fn magnitude(self) -> Self::Scalar where Self::Scalar: Float {
|
||||||
|
Float::sqrt(self.magnitude2())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a vector with the same direction, but with a magnitude of `1`.
|
||||||
|
#[inline]
|
||||||
|
fn normalize(self) -> Self where Self::Scalar: Float {
|
||||||
|
self.normalize_to(Self::Scalar::one())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a vector with the same direction and a given magnitude.
|
||||||
|
#[inline]
|
||||||
|
fn normalize_to(self, magnitude: Self::Scalar) -> Self where Self::Scalar: Float {
|
||||||
|
self * (magnitude / self.magnitude())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Points in a [Euclidean space](https://en.wikipedia.org/wiki/Euclidean_space)
|
/// Points in a [Euclidean space](https://en.wikipedia.org/wiki/Euclidean_space)
|
||||||
|
|
|
@ -139,7 +139,7 @@ macro_rules! impl_vector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum + Float> MetricSpace for $VectorN<S> {
|
impl<S: BaseNum> MetricSpace for $VectorN<S> {
|
||||||
type Metric = S;
|
type Metric = S;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -525,14 +525,14 @@ where
|
||||||
V::dot(a, b)
|
V::dot(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum + Float> InnerSpace for Vector1<S> {
|
impl<S: BaseNum> InnerSpace for Vector1<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn dot(self, other: Vector1<S>) -> S {
|
fn dot(self, other: Vector1<S>) -> S {
|
||||||
Vector1::mul_element_wise(self, other).sum()
|
Vector1::mul_element_wise(self, other).sum()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum + Float> InnerSpace for Vector2<S> {
|
impl<S: BaseNum> InnerSpace for Vector2<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn dot(self, other: Vector2<S>) -> S {
|
fn dot(self, other: Vector2<S>) -> S {
|
||||||
Vector2::mul_element_wise(self, other).sum()
|
Vector2::mul_element_wise(self, other).sum()
|
||||||
|
@ -544,7 +544,7 @@ impl<S: BaseNum + Float> InnerSpace for Vector2<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum + Float> InnerSpace for Vector3<S> {
|
impl<S: BaseNum> InnerSpace for Vector3<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn dot(self, other: Vector3<S>) -> S {
|
fn dot(self, other: Vector3<S>) -> S {
|
||||||
Vector3::mul_element_wise(self, other).sum()
|
Vector3::mul_element_wise(self, other).sum()
|
||||||
|
@ -556,7 +556,7 @@ impl<S: BaseNum + Float> InnerSpace for Vector3<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: BaseNum + Float> InnerSpace for Vector4<S> {
|
impl<S: BaseNum> InnerSpace for Vector4<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn dot(self, other: Vector4<S>) -> S {
|
fn dot(self, other: Vector4<S>) -> S {
|
||||||
Vector4::mul_element_wise(self, other).sum()
|
Vector4::mul_element_wise(self, other).sum()
|
||||||
|
@ -966,5 +966,11 @@ mod tests {
|
||||||
Vector4::new(-2, 1, 0, 1).zip(Vector4::new(-1, -1, -1, -1), |a, b| a < b)
|
Vector4::new(-2, 1, 0, 1).zip(Vector4::new(-1, -1, -1, -1), |a, b| a < b)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_dot() {
|
||||||
|
assert_eq!(vec3(1.0, 2.0, 3.0).dot(vec3(4.0, 5.0, 6.0)), 32.0);
|
||||||
|
assert_eq!(vec3(1, 2, 3).dot(vec3(4, 5, 6)), 32);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue