Skip to content

Commit 5769ee3

Browse files
committed
Add Euclidean trait
1 parent 1e05f0e commit 5769ee3

File tree

3 files changed

+73
-4
lines changed

3 files changed

+73
-4
lines changed

core/src/math/point.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ use core::{
66
ops::{AddAssign, DivAssign, MulAssign, SubAssign},
77
};
88

9-
use super::{Affine, ApproxEq, Linear, Vector, space::Real, vary::ZDiv};
9+
use super::{
10+
Affine, ApproxEq, Linear, Vector,
11+
space::{Euclidean, Real},
12+
vary::ZDiv,
13+
};
1014

1115
#[repr(transparent)]
1216
pub struct Point<Repr, Space = ()>(pub Repr, Pd<Space>);
@@ -259,6 +263,20 @@ where
259263
}
260264
}
261265

266+
impl<B, const N: usize> Euclidean for Point<[f32; N], Real<N, B>> {
267+
fn origin() -> Self {
268+
Point::origin()
269+
}
270+
271+
fn distance(&self, other: &Self) -> f32 {
272+
other.sub(self).len()
273+
}
274+
275+
fn approach(&self, other: &Self, d: f32) -> Self {
276+
self.approach(other, d)
277+
}
278+
}
279+
262280
impl<Sc, Sp, const N: usize> ZDiv for Point<[Sc; N], Sp>
263281
where
264282
Sc: ZDiv + Copy,

core/src/math/space.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use core::fmt::{Debug, Formatter};
66
use core::iter::zip;
77
use core::marker::PhantomData;
88

9-
use crate::math::vary::{Iter, Vary, ZDiv};
9+
use super::vary::{Iter, Vary, ZDiv};
1010

1111
/// Trait for types representing elements of an affine space.
1212
///
@@ -92,6 +92,24 @@ pub trait Linear: Affine<Diff = Self> {
9292
fn mul(&self, scalar: Self::Scalar) -> Self;
9393
}
9494

95+
pub trait Euclidean: Affine {
96+
/// Returns the canonical origin of this Euclidean space.
97+
fn origin() -> Self;
98+
99+
/// Returns the length of the translation vector between two points.
100+
fn distance(&self, other: &Self) -> f32;
101+
102+
/// Returns `self`, moved towards another point by an offset.
103+
///
104+
/// If the distance to `other` is less than `d`, returns `other`. That is,
105+
/// this method never "overshoots" the target. Negative values of `d` result
106+
/// in moving away from `other`. If `self` equals `other`, returns `other`
107+
/// independent of the value of `d`.
108+
///
109+
/// To translate by a *relative* offset instead, use [`lerp`][super::Lerp::lerp].
110+
fn approach(&self, other: &Self, d: f32) -> Self;
111+
}
112+
95113
/// Tag type for real vector spaces and Euclidean spaces.
96114
///
97115
/// For example, the type `Real<3>` corresponds to ℝ³.
@@ -136,6 +154,26 @@ impl Linear for f32 {
136154
}
137155
}
138156

157+
impl Euclidean for f32 {
158+
fn origin() -> Self {
159+
0.0
160+
}
161+
162+
fn distance(&self, other: &Self) -> f32 {
163+
(other - self).abs()
164+
}
165+
166+
fn approach(&self, other: &Self, d: f32) -> Self {
167+
let diff = other - self;
168+
let dist = diff.abs();
169+
if d < dist && dist != 0.0 {
170+
self + d * diff.signum()
171+
} else {
172+
*other
173+
}
174+
}
175+
}
176+
139177
impl Affine for i32 {
140178
type Space = ();
141179
type Diff = Self;

core/src/math/vec.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ use core::{
1313

1414
use crate::math::{
1515
Affine, ApproxEq, Linear, Point,
16-
space::{Proj3, Real},
16+
space::{Euclidean, Proj3, Real},
1717
vary::ZDiv,
1818
};
19-
2019
//
2120
// Types
2221
//
@@ -576,6 +575,20 @@ where
576575
}
577576
}
578577

578+
impl<B, const N: usize> Euclidean for Vector<[f32; N], Real<N, B>> {
579+
fn origin() -> Self {
580+
Vector::zero()
581+
}
582+
583+
fn distance(&self, other: &Self) -> f32 {
584+
other.sub(self).len()
585+
}
586+
587+
fn approach(&self, other: &Self, d: f32) -> Self {
588+
self.to_pt().approach(&other.to_pt(), d).to_vec()
589+
}
590+
}
591+
579592
impl<Sc, Sp, const N: usize> ZDiv for Vector<[Sc; N], Sp>
580593
where
581594
Sc: ZDiv + Copy,

0 commit comments

Comments
 (0)