Merge pull request #943 from dimforge/point_dim_name

Add a OPoint type that takes type-level integers instead of const-generics
This commit is contained in:
Sébastien Crozet 2021-07-10 11:40:31 +02:00 committed by GitHub
commit 7bcb54641d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 271 additions and 182 deletions

View File

@ -4,6 +4,11 @@ documented here.
This project adheres to [Semantic Versioning](https://semver.org/).
## [0.28.0]
### Modified
- The `Point::new` constructors are no longer const-fn. This is due to some limitations in const-fn
not allowing custom trait-bounds. Use the `point!` macro instead to build points in const environments.
## [0.27.1]
### Fixed
- Fixed a bug in the conversion from `glam::Vec2` or `glam::DVec2` to `Isometry2`.

View File

@ -17,7 +17,7 @@ use simba::simd::SimdPartialOrd;
use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1};
use crate::base::iter::{MatrixIter, MatrixIterMut};
use crate::base::{Const, DefaultAllocator, OVector, SVector, Scalar};
use crate::base::{Const, DefaultAllocator, OVector, Scalar};
/// A point in an euclidean space.
///
@ -40,35 +40,53 @@ use crate::base::{Const, DefaultAllocator, OVector, SVector, Scalar};
/// of said transformations for details.
#[repr(C)]
#[derive(Debug, Clone)]
pub struct Point<T, const D: usize> {
pub struct OPoint<T: Scalar, D: DimName>
where
DefaultAllocator: Allocator<T, D>,
{
/// The coordinates of this point, i.e., the shift from the origin.
pub coords: SVector<T, D>,
pub coords: OVector<T, D>,
}
impl<T: Scalar + hash::Hash, const D: usize> hash::Hash for Point<T, D> {
impl<T: Scalar + hash::Hash, D: DimName> hash::Hash for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
{
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.coords.hash(state)
}
}
impl<T: Scalar + Copy, const D: usize> Copy for Point<T, D> {}
#[cfg(feature = "bytemuck")]
unsafe impl<T: Scalar, const D: usize> bytemuck::Zeroable for Point<T, D> where
SVector<T, D>: bytemuck::Zeroable
impl<T: Scalar + Copy, D: DimName> Copy for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
OVector<T, D>: Copy,
{
}
#[cfg(feature = "bytemuck")]
unsafe impl<T: Scalar, const D: usize> bytemuck::Pod for Point<T, D>
unsafe impl<T: Scalar, D: DimName> bytemuck::Zeroable for OPoint<T, D>
where
OVector<T, D>: bytemuck::Zeroable,
DefaultAllocator: Allocator<T, D>,
{
}
#[cfg(feature = "bytemuck")]
unsafe impl<T: Scalar, D: DimName> bytemuck::Pod for OPoint<T, D>
where
T: Copy,
SVector<T, D>: bytemuck::Pod,
OVector<T, D>: bytemuck::Pod,
DefaultAllocator: Allocator<T, D>,
{
}
#[cfg(feature = "serde-serialize-no-std")]
impl<T: Scalar + Serialize, const D: usize> Serialize for Point<T, D> {
impl<T: Scalar + Serialize, D: DimName> Serialize for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
<DefaultAllocator as Allocator<T, D>>::Buffer: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
@ -78,22 +96,27 @@ impl<T: Scalar + Serialize, const D: usize> Serialize for Point<T, D> {
}
#[cfg(feature = "serde-serialize-no-std")]
impl<'a, T: Scalar + Deserialize<'a>, const D: usize> Deserialize<'a> for Point<T, D> {
impl<'a, T: Scalar + Deserialize<'a>, D: DimName> Deserialize<'a> for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
<DefaultAllocator as Allocator<T, D>>::Buffer: Deserialize<'a>,
{
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
where
Des: Deserializer<'a>,
{
let coords = SVector::<T, D>::deserialize(deserializer)?;
let coords = OVector::<T, D>::deserialize(deserializer)?;
Ok(Self::from(coords))
}
}
#[cfg(feature = "abomonation-serialize")]
impl<T, const D: usize> Abomonation for Point<T, D>
impl<T, D: DimName> Abomonation for OPoint<T, D>
where
T: Scalar,
SVector<T, D>: Abomonation,
OVector<T, D>: Abomonation,
DefaultAllocator: Allocator<T, D>,
{
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
self.coords.entomb(writer)
@ -108,7 +131,10 @@ where
}
}
impl<T: Scalar, const D: usize> Point<T, D> {
impl<T: Scalar, D: DimName> OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
{
/// Returns a point containing the result of `f` applied to each of its entries.
///
/// # Example
@ -123,7 +149,10 @@ impl<T: Scalar, const D: usize> Point<T, D> {
/// ```
#[inline]
#[must_use]
pub fn map<T2: Scalar, F: FnMut(T) -> T2>(&self, f: F) -> Point<T2, D> {
pub fn map<T2: Scalar, F: FnMut(T) -> T2>(&self, f: F) -> OPoint<T2, D>
where
DefaultAllocator: Allocator<T2, D>,
{
self.coords.map(f).into()
}
@ -163,20 +192,21 @@ impl<T: Scalar, const D: usize> Point<T, D> {
/// ```
#[inline]
#[must_use]
pub fn to_homogeneous(&self) -> OVector<T, DimNameSum<Const<D>, U1>>
pub fn to_homogeneous(&self) -> OVector<T, DimNameSum<D, U1>>
where
T: One,
Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>>,
D: DimNameAdd<U1>,
DefaultAllocator: Allocator<T, DimNameSum<D, U1>>,
{
let mut res = unsafe {
crate::unimplemented_or_uninitialized_generic!(
<DimNameSum<Const<D>, U1> as DimName>::name(),
<DimNameSum<D, U1> as DimName>::name(),
Const::<1>
)
};
res.fixed_slice_mut::<D, 1>(0, 0).copy_from(&self.coords);
res[(D, 0)] = T::one();
res.generic_slice_mut((0, 0), (D::name(), Const::<1>))
.copy_from(&self.coords);
res[(D::dim(), 0)] = T::one();
res
}
@ -184,7 +214,7 @@ impl<T: Scalar, const D: usize> Point<T, D> {
/// Creates a new point with the given coordinates.
#[deprecated(note = "Use Point::from(vector) instead.")]
#[inline]
pub fn from_coordinates(coords: SVector<T, D>) -> Self {
pub fn from_coordinates(coords: OVector<T, D>) -> Self {
Self { coords }
}
@ -243,8 +273,7 @@ impl<T: Scalar, const D: usize> Point<T, D> {
#[inline]
pub fn iter(
&self,
) -> MatrixIter<T, Const<D>, Const<1>, <DefaultAllocator as Allocator<T, Const<D>>>::Buffer>
{
) -> MatrixIter<T, D, Const<1>, <DefaultAllocator as Allocator<T, D>>::Buffer> {
self.coords.iter()
}
@ -270,8 +299,7 @@ impl<T: Scalar, const D: usize> Point<T, D> {
#[inline]
pub fn iter_mut(
&mut self,
) -> MatrixIterMut<T, Const<D>, Const<1>, <DefaultAllocator as Allocator<T, Const<D>>>::Buffer>
{
) -> MatrixIterMut<T, D, Const<1>, <DefaultAllocator as Allocator<T, D>>::Buffer> {
self.coords.iter_mut()
}
@ -289,9 +317,10 @@ impl<T: Scalar, const D: usize> Point<T, D> {
}
}
impl<T: Scalar + AbsDiffEq, const D: usize> AbsDiffEq for Point<T, D>
impl<T: Scalar + AbsDiffEq, D: DimName> AbsDiffEq for OPoint<T, D>
where
T::Epsilon: Copy,
DefaultAllocator: Allocator<T, D>,
{
type Epsilon = T::Epsilon;
@ -306,9 +335,10 @@ where
}
}
impl<T: Scalar + RelativeEq, const D: usize> RelativeEq for Point<T, D>
impl<T: Scalar + RelativeEq, D: DimName> RelativeEq for OPoint<T, D>
where
T::Epsilon: Copy,
DefaultAllocator: Allocator<T, D>,
{
#[inline]
fn default_max_relative() -> Self::Epsilon {
@ -327,9 +357,10 @@ where
}
}
impl<T: Scalar + UlpsEq, const D: usize> UlpsEq for Point<T, D>
impl<T: Scalar + UlpsEq, D: DimName> UlpsEq for OPoint<T, D>
where
T::Epsilon: Copy,
DefaultAllocator: Allocator<T, D>,
{
#[inline]
fn default_max_ulps() -> u32 {
@ -342,16 +373,22 @@ where
}
}
impl<T: Scalar + Eq, const D: usize> Eq for Point<T, D> {}
impl<T: Scalar + Eq, D: DimName> Eq for OPoint<T, D> where DefaultAllocator: Allocator<T, D> {}
impl<T: Scalar, const D: usize> PartialEq for Point<T, D> {
impl<T: Scalar, D: DimName> PartialEq for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
{
#[inline]
fn eq(&self, right: &Self) -> bool {
self.coords == right.coords
}
}
impl<T: Scalar + PartialOrd, const D: usize> PartialOrd for Point<T, D> {
impl<T: Scalar + PartialOrd, D: DimName> PartialOrd for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
{
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.coords.partial_cmp(&other.coords)
@ -381,25 +418,28 @@ impl<T: Scalar + PartialOrd, const D: usize> PartialOrd for Point<T, D> {
/*
* inf/sup
*/
impl<T: Scalar + SimdPartialOrd, const D: usize> Point<T, D> {
impl<T: Scalar + SimdPartialOrd, D: DimName> OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
{
/// Computes the infimum (aka. componentwise min) of two points.
#[inline]
#[must_use]
pub fn inf(&self, other: &Self) -> Point<T, D> {
pub fn inf(&self, other: &Self) -> OPoint<T, D> {
self.coords.inf(&other.coords).into()
}
/// Computes the supremum (aka. componentwise max) of two points.
#[inline]
#[must_use]
pub fn sup(&self, other: &Self) -> Point<T, D> {
pub fn sup(&self, other: &Self) -> OPoint<T, D> {
self.coords.sup(&other.coords).into()
}
/// Computes the (infimum, supremum) of two points.
#[inline]
#[must_use]
pub fn inf_sup(&self, other: &Self) -> (Point<T, D>, Point<T, D>) {
pub fn inf_sup(&self, other: &Self) -> (OPoint<T, D>, OPoint<T, D>) {
let (inf, sup) = self.coords.inf_sup(&other.coords);
(inf.into(), sup.into())
}
@ -410,7 +450,10 @@ impl<T: Scalar + SimdPartialOrd, const D: usize> Point<T, D> {
* Display
*
*/
impl<T: Scalar + fmt::Display, const D: usize> fmt::Display for Point<T, D> {
impl<T: Scalar + fmt::Display, D: DimName> fmt::Display for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{{")?;

View File

@ -1,4 +1,8 @@
use crate::geometry::Point;
use crate::geometry::OPoint;
use crate::Const;
/// A point with `D` elements.
pub type Point<T, const D: usize> = OPoint<T, Const<D>>;
/// A statically sized 1-dimensional column point.
///

View File

@ -10,22 +10,26 @@ use rand::{
use crate::base::allocator::Allocator;
use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
use crate::base::{DefaultAllocator, SVector, Scalar};
use crate::base::{DefaultAllocator, Scalar};
use crate::{
Const, OVector, Point1, Point2, Point3, Point4, Point5, Point6, Vector1, Vector2, Vector3,
Vector4, Vector5, Vector6,
Const, DimName, OPoint, OVector, Point1, Point2, Point3, Point4, Point5, Point6, Vector1,
Vector2, Vector3, Vector4, Vector5, Vector6,
};
use simba::scalar::{ClosedDiv, SupersetOf};
use crate::geometry::Point;
/// # Other construction methods
impl<T: Scalar, const D: usize> Point<T, D> {
impl<T: Scalar, D: DimName> OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
{
/// Creates a new point with uninitialized coordinates.
#[inline]
pub unsafe fn new_uninitialized() -> Self {
Self::from(crate::unimplemented_or_uninitialized_generic!(
Const::<D>, Const::<1>
D::name(),
Const::<1>
))
}
@ -49,7 +53,7 @@ impl<T: Scalar, const D: usize> Point<T, D> {
where
T: Zero,
{
Self::from(SVector::from_element(T::zero()))
Self::from(OVector::from_element(T::zero()))
}
/// Creates a new point from a slice.
@ -68,7 +72,7 @@ impl<T: Scalar, const D: usize> Point<T, D> {
/// ```
#[inline]
pub fn from_slice(components: &[T]) -> Self {
Self::from(SVector::from_row_slice(components))
Self::from(OVector::from_row_slice(components))
}
/// Creates a new point from its homogeneous vector representation.
@ -102,14 +106,15 @@ impl<T: Scalar, const D: usize> Point<T, D> {
/// assert_eq!(pt, Some(Point2::new(1.0, 2.0)));
/// ```
#[inline]
pub fn from_homogeneous(v: OVector<T, DimNameSum<Const<D>, U1>>) -> Option<Self>
pub fn from_homogeneous(v: OVector<T, DimNameSum<D, U1>>) -> Option<Self>
where
T: Scalar + Zero + One + ClosedDiv,
Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>>,
D: DimNameAdd<U1>,
DefaultAllocator: Allocator<T, DimNameSum<D, U1>>,
{
if !v[D].is_zero() {
let coords = v.fixed_slice::<D, 1>(0, 0) / v[D].inlined_clone();
if !v[D::dim()].is_zero() {
let coords =
v.generic_slice((0, 0), (D::name(), Const::<1>)) / v[D::dim()].inlined_clone();
Some(Self::from(coords))
} else {
None
@ -125,9 +130,10 @@ impl<T: Scalar, const D: usize> Point<T, D> {
/// let pt2 = pt.cast::<f32>();
/// assert_eq!(pt2, Point2::new(1.0f32, 2.0));
/// ```
pub fn cast<To: Scalar>(self) -> Point<To, D>
pub fn cast<To: Scalar>(self) -> OPoint<To, D>
where
Point<To, D>: SupersetOf<Self>,
OPoint<To, D>: SupersetOf<Self>,
DefaultAllocator: Allocator<To, D>,
{
crate::convert(self)
}
@ -138,38 +144,43 @@ impl<T: Scalar, const D: usize> Point<T, D> {
* Traits that build points.
*
*/
impl<T: Scalar + Bounded, const D: usize> Bounded for Point<T, D> {
impl<T: Scalar + Bounded, D: DimName> Bounded for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
{
#[inline]
fn max_value() -> Self {
Self::from(SVector::max_value())
Self::from(OVector::max_value())
}
#[inline]
fn min_value() -> Self {
Self::from(SVector::min_value())
Self::from(OVector::min_value())
}
}
#[cfg(feature = "rand-no-std")]
impl<T: Scalar, const D: usize> Distribution<Point<T, D>> for Standard
impl<T: Scalar, D: DimName> Distribution<OPoint<T, D>> for Standard
where
Standard: Distribution<T>,
DefaultAllocator: Allocator<T, D>,
{
/// Generate a `Point` where each coordinate is an independent variate from `[0, 1)`.
#[inline]
fn sample<'a, G: Rng + ?Sized>(&self, rng: &mut G) -> Point<T, D> {
Point::from(rng.gen::<SVector<T, D>>())
fn sample<'a, G: Rng + ?Sized>(&self, rng: &mut G) -> OPoint<T, D> {
OPoint::from(rng.gen::<OVector<T, D>>())
}
}
#[cfg(feature = "arbitrary")]
impl<T: Scalar + Arbitrary + Send, const D: usize> Arbitrary for Point<T, D>
impl<T: Scalar + Arbitrary + Send, D: DimName> Arbitrary for OPoint<T, D>
where
<DefaultAllocator as Allocator<T, Const<D>>>::Buffer: Send,
<DefaultAllocator as Allocator<T, D>>::Buffer: Send,
DefaultAllocator: Allocator<T, D>,
{
#[inline]
fn arbitrary(g: &mut Gen) -> Self {
Self::from(SVector::arbitrary(g))
Self::from(OVector::arbitrary(g))
}
}
@ -181,7 +192,7 @@ where
// NOTE: the impl for Point1 is not with the others so that we
// can add a section with the impl block comment.
/// # Construction from individual components
impl<T> Point1<T> {
impl<T: Scalar> Point1<T> {
/// Initializes this point from its components.
///
/// # Example
@ -192,7 +203,7 @@ impl<T> Point1<T> {
/// assert_eq!(p.x, 1.0);
/// ```
#[inline]
pub const fn new(x: T) -> Self {
pub fn new(x: T) -> Self {
Point {
coords: Vector1::new(x),
}
@ -200,13 +211,13 @@ impl<T> Point1<T> {
}
macro_rules! componentwise_constructors_impl(
($($doc: expr; $Point: ident, $Vector: ident, $($args: ident:$irow: expr),*);* $(;)*) => {$(
impl<T> $Point<T> {
impl<T: Scalar> $Point<T> {
#[doc = "Initializes this point from its components."]
#[doc = "# Example\n```"]
#[doc = $doc]
#[doc = "```"]
#[inline]
pub const fn new($($args: T),*) -> Self {
pub fn new($($args: T),*) -> Self {
Point { coords: $Vector::new($($args),*) }
}
}

View File

@ -7,6 +7,7 @@ use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
use crate::base::{Const, DefaultAllocator, Matrix, OVector, Scalar};
use crate::geometry::Point;
use crate::{DimName, OPoint};
/*
* This file provides the following conversions:
@ -16,67 +17,69 @@ use crate::geometry::Point;
* Point -> Vector (homogeneous)
*/
impl<T1, T2, const D: usize> SubsetOf<Point<T2, D>> for Point<T1, D>
impl<T1, T2, D: DimName> SubsetOf<OPoint<T2, D>> for OPoint<T1, D>
where
T1: Scalar,
T2: Scalar + SupersetOf<T1>,
DefaultAllocator: Allocator<T1, D> + Allocator<T2, D>,
{
#[inline]
fn to_superset(&self) -> Point<T2, D> {
Point::from(self.coords.to_superset())
fn to_superset(&self) -> OPoint<T2, D> {
OPoint::from(self.coords.to_superset())
}
#[inline]
fn is_in_subset(m: &Point<T2, D>) -> bool {
fn is_in_subset(m: &OPoint<T2, D>) -> bool {
// TODO: is there a way to reuse the `.is_in_subset` from the matrix implementation of
// SubsetOf?
m.iter().all(|e| e.is_in_subset())
}
#[inline]
fn from_superset_unchecked(m: &Point<T2, D>) -> Self {
fn from_superset_unchecked(m: &OPoint<T2, D>) -> Self {
Self::from(Matrix::from_superset_unchecked(&m.coords))
}
}
impl<T1, T2, const D: usize> SubsetOf<OVector<T2, DimNameSum<Const<D>, U1>>> for Point<T1, D>
impl<T1, T2, D> SubsetOf<OVector<T2, DimNameSum<D, U1>>> for OPoint<T1, D>
where
Const<D>: DimNameAdd<U1>,
D: DimNameAdd<U1>,
T1: Scalar,
T2: Scalar + Zero + One + ClosedDiv + SupersetOf<T1>,
DefaultAllocator:
Allocator<T1, DimNameSum<Const<D>, U1>> + Allocator<T2, DimNameSum<Const<D>, U1>>,
DefaultAllocator: Allocator<T1, D>
+ Allocator<T2, D>
+ Allocator<T1, DimNameSum<D, U1>>
+ Allocator<T2, DimNameSum<D, U1>>,
// + Allocator<T1, D>
// + Allocator<T2, D>,
{
#[inline]
fn to_superset(&self) -> OVector<T2, DimNameSum<Const<D>, U1>> {
let p: Point<T2, D> = self.to_superset();
fn to_superset(&self) -> OVector<T2, DimNameSum<D, U1>> {
let p: OPoint<T2, D> = self.to_superset();
p.to_homogeneous()
}
#[inline]
fn is_in_subset(v: &OVector<T2, DimNameSum<Const<D>, U1>>) -> bool {
crate::is_convertible::<_, OVector<T1, DimNameSum<Const<D>, U1>>>(v) && !v[D].is_zero()
fn is_in_subset(v: &OVector<T2, DimNameSum<D, U1>>) -> bool {
crate::is_convertible::<_, OVector<T1, DimNameSum<D, U1>>>(v) && !v[D::dim()].is_zero()
}
#[inline]
fn from_superset_unchecked(v: &OVector<T2, DimNameSum<Const<D>, U1>>) -> Self {
let coords = v.fixed_slice::<D, 1>(0, 0) / v[D].inlined_clone();
fn from_superset_unchecked(v: &OVector<T2, DimNameSum<D, U1>>) -> Self {
let coords = v.generic_slice((0, 0), (D::name(), Const::<1>)) / v[D::dim()].inlined_clone();
Self {
coords: crate::convert_unchecked(coords),
}
}
}
impl<T: Scalar + Zero + One, const D: usize> From<Point<T, D>>
for OVector<T, DimNameSum<Const<D>, U1>>
impl<T: Scalar + Zero + One, D: DimName> From<OPoint<T, D>> for OVector<T, DimNameSum<D, U1>>
where
Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>>,
D: DimNameAdd<U1>,
DefaultAllocator: Allocator<T, DimNameSum<D, U1>> + Allocator<T, D>,
{
#[inline]
fn from(t: Point<T, D>) -> Self {
fn from(t: OPoint<T, D>) -> Self {
t.to_homogeneous()
}
}
@ -97,10 +100,13 @@ impl<T: Scalar, const D: usize> From<Point<T, D>> for [T; D] {
}
}
impl<T: Scalar, const D: usize> From<OVector<T, Const<D>>> for Point<T, D> {
impl<T: Scalar, D: DimName> From<OVector<T, D>> for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
{
#[inline]
fn from(coords: OVector<T, Const<D>>) -> Self {
Point { coords }
fn from(coords: OVector<T, D>) -> Self {
OPoint { coords }
}
}

View File

@ -1,9 +1,9 @@
use std::ops::{Deref, DerefMut};
use crate::base::coordinates::{X, XY, XYZ, XYZW, XYZWA, XYZWAB};
use crate::base::Scalar;
use crate::base::{Scalar, U1, U2, U3, U4, U5, U6};
use crate::geometry::Point;
use crate::geometry::OPoint;
/*
*
@ -12,8 +12,8 @@ use crate::geometry::Point;
*/
macro_rules! deref_impl(
($D: expr, $Target: ident $(, $comps: ident)*) => {
impl<T: Scalar> Deref for Point<T, $D>
($D: ty, $Target: ident $(, $comps: ident)*) => {
impl<T: Scalar> Deref for OPoint<T, $D>
{
type Target = $Target<T>;
@ -23,7 +23,7 @@ macro_rules! deref_impl(
}
}
impl<T: Scalar> DerefMut for Point<T, $D>
impl<T: Scalar> DerefMut for OPoint<T, $D>
{
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
@ -33,9 +33,9 @@ macro_rules! deref_impl(
}
);
deref_impl!(1, X, x);
deref_impl!(2, XY, x, y);
deref_impl!(3, XYZ, x, y, z);
deref_impl!(4, XYZW, x, y, z, w);
deref_impl!(5, XYZWA, x, y, z, w, a);
deref_impl!(6, XYZWAB, x, y, z, w, a, b);
deref_impl!(U1, X, x);
deref_impl!(U2, XY, x, y);
deref_impl!(U3, XYZ, x, y, z);
deref_impl!(U4, XYZW, x, y, z, w);
deref_impl!(U5, XYZWA, x, y, z, w, a);
deref_impl!(U6, XYZWAB, x, y, z, w, a, b);

View File

@ -8,18 +8,23 @@ use simba::scalar::{ClosedAdd, ClosedDiv, ClosedMul, ClosedNeg, ClosedSub};
use crate::base::constraint::{
AreMultipliable, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint,
};
use crate::base::dimension::{Dim, U1};
use crate::base::dimension::{Dim, DimName, U1};
use crate::base::storage::Storage;
use crate::base::{Const, Matrix, SVector, Scalar, Vector};
use crate::base::{Const, Matrix, OVector, Scalar, Vector};
use crate::geometry::Point;
use crate::allocator::Allocator;
use crate::geometry::{OPoint, Point};
use crate::DefaultAllocator;
/*
*
* Indexing.
*
*/
impl<T: Scalar, const D: usize> Index<usize> for Point<T, D> {
impl<T: Scalar, D: DimName> Index<usize> for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
{
type Output = T;
#[inline]
@ -28,7 +33,10 @@ impl<T: Scalar, const D: usize> Index<usize> for Point<T, D> {
}
}
impl<T: Scalar, const D: usize> IndexMut<usize> for Point<T, D> {
impl<T: Scalar, D: DimName> IndexMut<usize> for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
{
#[inline]
fn index_mut(&mut self, i: usize) -> &mut Self::Output {
&mut self.coords[i]
@ -40,7 +48,10 @@ impl<T: Scalar, const D: usize> IndexMut<usize> for Point<T, D> {
* Neg.
*
*/
impl<T: Scalar + ClosedNeg, const D: usize> Neg for Point<T, D> {
impl<T: Scalar + ClosedNeg, D: DimName> Neg for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
{
type Output = Self;
#[inline]
@ -49,8 +60,11 @@ impl<T: Scalar + ClosedNeg, const D: usize> Neg for Point<T, D> {
}
}
impl<'a, T: Scalar + ClosedNeg, const D: usize> Neg for &'a Point<T, D> {
type Output = Point<T, D>;
impl<'a, T: Scalar + ClosedNeg, D: DimName> Neg for &'a OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
{
type Output = OPoint<T, D>;
#[inline]
fn neg(self) -> Self::Output {
@ -66,102 +80,103 @@ impl<'a, T: Scalar + ClosedNeg, const D: usize> Neg for &'a Point<T, D> {
// Point - Point
add_sub_impl!(Sub, sub, ClosedSub;
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
const D; for; where;
self: &'a Point<T, D>, right: &'b Point<T, D>, Output = SVector<T, D>;
(D, U1), (D, U1) -> (D, U1)
const; for D; where D: DimName, DefaultAllocator: Allocator<T, D>;
self: &'a OPoint<T, D>, right: &'b OPoint<T, D>, Output = OVector<T, D>;
&self.coords - &right.coords; 'a, 'b);
add_sub_impl!(Sub, sub, ClosedSub;
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
const D; for; where;
self: &'a Point<T, D>, right: Point<T, D>, Output = SVector<T, D>;
(D, U1), (D, U1) -> (D, U1)
const; for D; where D: DimName, DefaultAllocator: Allocator<T, D>;
self: &'a OPoint<T, D>, right: OPoint<T, D>, Output = OVector<T, D>;
&self.coords - right.coords; 'a);
add_sub_impl!(Sub, sub, ClosedSub;
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
const D; for; where;
self: Point<T, D>, right: &'b Point<T, D>, Output = SVector<T, D>;
(D, U1), (D, U1) -> (D, U1)
const; for D; where D: DimName, DefaultAllocator: Allocator<T, D>;
self: OPoint<T, D>, right: &'b OPoint<T, D>, Output = OVector<T, D>;
self.coords - &right.coords; 'b);
add_sub_impl!(Sub, sub, ClosedSub;
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
const D; for; where;
self: Point<T, D>, right: Point<T, D>, Output = SVector<T, D>;
(D, U1), (D, U1) -> (D, U1)
const; for D; where D: DimName, DefaultAllocator: Allocator<T, D>;
self: OPoint<T, D>, right: OPoint<T, D>, Output = OVector<T, D>;
self.coords - right.coords; );
// Point - Vector
add_sub_impl!(Sub, sub, ClosedSub;
(Const<D1>, U1), (D2, U1) -> (Const<D1>, U1)
const D1;
for D2, SB;
where D2: Dim, SB: Storage<T, D2>;
self: &'a Point<T, D1>, right: &'b Vector<T, D2, SB>, Output = Point<T, D1>;
(D1, U1), (D2, U1) -> (D1, U1)
const;
for D1, D2, SB;
where D1: DimName, D2: Dim, SB: Storage<T, D2>, DefaultAllocator: Allocator<T, D1>;
self: &'a OPoint<T, D1>, right: &'b Vector<T, D2, SB>, Output = OPoint<T, D1>;
Self::Output::from(&self.coords - right); 'a, 'b);
add_sub_impl!(Sub, sub, ClosedSub;
(Const<D1>, U1), (D2, U1) -> (Const<D1>, U1)
const D1;
for D2, SB;
where D2: Dim, SB: Storage<T, D2>;
self: &'a Point<T, D1>, right: Vector<T, D2, SB>, Output = Point<T, D1>;
(D1, U1), (D2, U1) -> (D1, U1)
const;
for D1, D2, SB;
where D1: DimName, D2: Dim, SB: Storage<T, D2>, DefaultAllocator: Allocator<T, D1>;
self: &'a OPoint<T, D1>, right: Vector<T, D2, SB>, Output = OPoint<T, D1>;
Self::Output::from(&self.coords - &right); 'a); // TODO: should not be a ref to `right`.
add_sub_impl!(Sub, sub, ClosedSub;
(Const<D1>, U1), (D2, U1) -> (Const<D1>, U1)
const D1;
for D2, SB;
where D2: Dim, SB: Storage<T, D2>;
self: Point<T, D1>, right: &'b Vector<T, D2, SB>, Output = Point<T, D1>;
(D1, U1), (D2, U1) -> (D1, U1)
const;
for D1, D2, SB;
where D1: DimName, D2: Dim, SB: Storage<T, D2>, DefaultAllocator: Allocator<T, D1>;
self: OPoint<T, D1>, right: &'b Vector<T, D2, SB>, Output = OPoint<T, D1>;
Self::Output::from(self.coords - right); 'b);
add_sub_impl!(Sub, sub, ClosedSub;
(Const<D1>, U1), (D2, U1) -> (Const<D1>, U1)
const D1;
for D2, SB;
where D2: Dim, SB: Storage<T, D2>;
self: Point<T, D1>, right: Vector<T, D2, SB>, Output = Point<T, D1>;
(D1, U1), (D2, U1) -> (D1, U1)
const;
for D1, D2, SB;
where D1: DimName, D2: Dim, SB: Storage<T, D2>, DefaultAllocator: Allocator<T, D1>;
self: OPoint<T, D1>, right: Vector<T, D2, SB>, Output = OPoint<T, D1>;
Self::Output::from(self.coords - right); );
// Point + Vector
add_sub_impl!(Add, add, ClosedAdd;
(Const<D1>, U1), (D2, U1) -> (Const<D1>, U1)
const D1;
for D2, SB;
where D2: Dim, SB: Storage<T, D2>;
self: &'a Point<T, D1>, right: &'b Vector<T, D2, SB>, Output = Point<T, D1>;
(D1, U1), (D2, U1) -> (D1, U1)
const;
for D1, D2, SB;
where D1: DimName, D2: Dim, SB: Storage<T, D2>, DefaultAllocator: Allocator<T, D1>;
self: &'a OPoint<T, D1>, right: &'b Vector<T, D2, SB>, Output = OPoint<T, D1>;
Self::Output::from(&self.coords + right); 'a, 'b);
add_sub_impl!(Add, add, ClosedAdd;
(Const<D1>, U1), (D2, U1) -> (Const<D1>, U1)
const D1;
for D2, SB;
where D2: Dim, SB: Storage<T, D2>;
self: &'a Point<T, D1>, right: Vector<T, D2, SB>, Output = Point<T, D1>;
(D1, U1), (D2, U1) -> (D1, U1)
const;
for D1, D2, SB;
where D1: DimName, D2: Dim, SB: Storage<T, D2>, DefaultAllocator: Allocator<T, D1>;
self: &'a OPoint<T, D1>, right: Vector<T, D2, SB>, Output = OPoint<T, D1>;
Self::Output::from(&self.coords + &right); 'a); // TODO: should not be a ref to `right`.
add_sub_impl!(Add, add, ClosedAdd;
(Const<D1>, U1), (D2, U1) -> (Const<D1>, U1)
const D1;
for D2, SB;
where D2: Dim, SB: Storage<T, D2>;
self: Point<T, D1>, right: &'b Vector<T, D2, SB>, Output = Point<T, D1>;
(D1, U1), (D2, U1) -> (D1, U1)
const;
for D1, D2, SB;
where D1: DimName, D2: Dim, SB: Storage<T, D2>, DefaultAllocator: Allocator<T, D1>;
self: OPoint<T, D1>, right: &'b Vector<T, D2, SB>, Output = OPoint<T, D1>;
Self::Output::from(self.coords + right); 'b);
add_sub_impl!(Add, add, ClosedAdd;
(Const<D1>, U1), (D2, U1) -> (Const<D1>, U1)
const D1;
for D2, SB;
where D2: Dim, SB: Storage<T, D2>;
self: Point<T, D1>, right: Vector<T, D2, SB>, Output = Point<T, D1>;
(D1, U1), (D2, U1) -> (D1, U1)
const;
for D1, D2, SB;
where D1: DimName, D2: Dim, SB: Storage<T, D2>, DefaultAllocator: Allocator<T, D1>;
self: OPoint<T, D1>, right: Vector<T, D2, SB>, Output = OPoint<T, D1>;
Self::Output::from(self.coords + right); );
// TODO: replace by the shared macro: add_sub_assign_impl?
macro_rules! op_assign_impl(
($($TraitAssign: ident, $method_assign: ident, $bound: ident);* $(;)*) => {$(
impl<'b, T, D2: Dim, SB, const D1: usize> $TraitAssign<&'b Vector<T, D2, SB>> for Point<T, D1>
impl<'b, T, D1: DimName, D2: Dim, SB> $TraitAssign<&'b Vector<T, D2, SB>> for OPoint<T, D1>
where T: Scalar + $bound,
SB: Storage<T, D2>,
ShapeConstraint: SameNumberOfRows<Const<D1>, D2> {
ShapeConstraint: SameNumberOfRows<D1, D2>,
DefaultAllocator: Allocator<T, D1> {
#[inline]
fn $method_assign(&mut self, right: &'b Vector<T, D2, SB>) {
@ -169,10 +184,11 @@ macro_rules! op_assign_impl(
}
}
impl<T, D2: Dim, SB, const D1: usize> $TraitAssign<Vector<T, D2, SB>> for Point<T, D1>
impl<T, D1: DimName, D2: Dim, SB> $TraitAssign<Vector<T, D2, SB>> for OPoint<T, D1>
where T: Scalar + $bound,
SB: Storage<T, D2>,
ShapeConstraint: SameNumberOfRows<Const<D1>, D2> {
ShapeConstraint: SameNumberOfRows<D1, D2>,
DefaultAllocator: Allocator<T, D1> {
#[inline]
fn $method_assign(&mut self, right: Vector<T, D2, SB>) {
@ -214,28 +230,30 @@ md_impl_all!(
macro_rules! componentwise_scalarop_impl(
($Trait: ident, $method: ident, $bound: ident;
$TraitAssign: ident, $method_assign: ident) => {
impl<T: Scalar + $bound, const D: usize> $Trait<T> for Point<T, D>
impl<T: Scalar + $bound, D: DimName> $Trait<T> for OPoint<T, D>
where DefaultAllocator: Allocator<T, D>
{
type Output = Point<T, D>;
type Output = OPoint<T, D>;
#[inline]
fn $method(self, right: T) -> Self::Output {
Point::from(self.coords.$method(right))
OPoint::from(self.coords.$method(right))
}
}
impl<'a, T: Scalar + $bound, const D: usize> $Trait<T> for &'a Point<T, D>
impl<'a, T: Scalar + $bound, D: DimName> $Trait<T> for &'a OPoint<T, D>
where DefaultAllocator: Allocator<T, D>
{
type Output = Point<T, D>;
type Output = OPoint<T, D>;
#[inline]
fn $method(self, right: T) -> Self::Output {
Point::from((&self.coords).$method(right))
OPoint::from((&self.coords).$method(right))
}
}
impl<T: Scalar + $bound, const D: usize> $TraitAssign<T> for Point<T, D>
/* where DefaultAllocator: Allocator<T, D> */
impl<T: Scalar + $bound, D: DimName> $TraitAssign<T> for OPoint<T, D>
where DefaultAllocator: Allocator<T, D>
{
#[inline]
fn $method_assign(&mut self, right: T) {
@ -250,23 +268,25 @@ componentwise_scalarop_impl!(Div, div, ClosedDiv; DivAssign, div_assign);
macro_rules! left_scalar_mul_impl(
($($T: ty),* $(,)*) => {$(
impl<const D: usize> Mul<Point<$T, D>> for $T
impl<D: DimName> Mul<OPoint<$T, D>> for $T
where DefaultAllocator: Allocator<$T, D>
{
type Output = Point<$T, D>;
type Output = OPoint<$T, D>;
#[inline]
fn mul(self, right: Point<$T, D>) -> Self::Output {
Point::from(self * right.coords)
fn mul(self, right: OPoint<$T, D>) -> Self::Output {
OPoint::from(self * right.coords)
}
}
impl<'b, const D: usize> Mul<&'b Point<$T, D>> for $T
impl<'b, D: DimName> Mul<&'b OPoint<$T, D>> for $T
where DefaultAllocator: Allocator<$T, D>
{
type Output = Point<$T, D>;
type Output = OPoint<$T, D>;
#[inline]
fn mul(self, right: &'b Point<$T, D>) -> Self::Output {
Point::from(self * &right.coords)
fn mul(self, right: &'b OPoint<$T, D>) -> Self::Output {
OPoint::from(self * &right.coords)
}
}
)*}