forked from M-Labs/nalgebra
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:
commit
7bcb54641d
@ -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`.
|
||||
|
@ -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, "{{")?;
|
||||
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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),*) }
|
||||
}
|
||||
}
|
||||
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
)*}
|
||||
|
Loading…
Reference in New Issue
Block a user