2018-02-02 19:26:35 +08:00
|
|
|
|
use num::{One, Zero};
|
2018-05-19 23:15:15 +08:00
|
|
|
|
use std::ops::{
|
|
|
|
|
Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign,
|
|
|
|
|
};
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2020-03-21 19:16:46 +08:00
|
|
|
|
use simba::scalar::{ClosedAdd, ClosedDiv, ClosedMul, ClosedNeg, ClosedSub};
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2020-03-21 19:16:46 +08:00
|
|
|
|
use crate::base::constraint::{
|
|
|
|
|
AreMultipliable, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint,
|
|
|
|
|
};
|
2021-06-27 00:39:02 +08:00
|
|
|
|
use crate::base::dimension::{Dim, DimName, U1};
|
2019-03-23 21:29:07 +08:00
|
|
|
|
use crate::base::storage::Storage;
|
2021-06-27 00:39:02 +08:00
|
|
|
|
use crate::base::{Const, Matrix, OVector, Scalar, Vector};
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2021-06-27 00:39:02 +08:00
|
|
|
|
use crate::allocator::Allocator;
|
|
|
|
|
use crate::geometry::{OPoint, Point};
|
|
|
|
|
use crate::DefaultAllocator;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
* Indexing.
|
|
|
|
|
*
|
|
|
|
|
*/
|
2021-06-27 00:39:02 +08:00
|
|
|
|
impl<T: Scalar, D: DimName> Index<usize> for OPoint<T, D>
|
|
|
|
|
where
|
|
|
|
|
DefaultAllocator: Allocator<T, D>,
|
|
|
|
|
{
|
2021-04-11 17:00:38 +08:00
|
|
|
|
type Output = T;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn index(&self, i: usize) -> &Self::Output {
|
|
|
|
|
&self.coords[i]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-27 00:39:02 +08:00
|
|
|
|
impl<T: Scalar, D: DimName> IndexMut<usize> for OPoint<T, D>
|
|
|
|
|
where
|
|
|
|
|
DefaultAllocator: Allocator<T, D>,
|
|
|
|
|
{
|
2016-12-05 05:44:42 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn index_mut(&mut self, i: usize) -> &mut Self::Output {
|
|
|
|
|
&mut self.coords[i]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
2017-08-03 01:37:44 +08:00
|
|
|
|
*
|
2016-12-05 05:44:42 +08:00
|
|
|
|
* Neg.
|
|
|
|
|
*
|
|
|
|
|
*/
|
2021-06-27 00:39:02 +08:00
|
|
|
|
impl<T: Scalar + ClosedNeg, D: DimName> Neg for OPoint<T, D>
|
|
|
|
|
where
|
|
|
|
|
DefaultAllocator: Allocator<T, D>,
|
|
|
|
|
{
|
2019-02-17 05:29:41 +08:00
|
|
|
|
type Output = Self;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn neg(self) -> Self::Output {
|
2019-02-17 05:29:41 +08:00
|
|
|
|
Self::Output::from(-self.coords)
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-27 00:39:02 +08:00
|
|
|
|
impl<'a, T: Scalar + ClosedNeg, D: DimName> Neg for &'a OPoint<T, D>
|
|
|
|
|
where
|
|
|
|
|
DefaultAllocator: Allocator<T, D>,
|
|
|
|
|
{
|
|
|
|
|
type Output = OPoint<T, D>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn neg(self) -> Self::Output {
|
2019-02-17 05:29:41 +08:00
|
|
|
|
Self::Output::from(-&self.coords)
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
* Subtraction & Addition.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
// Point - Point
|
2016-12-05 05:44:42 +08:00
|
|
|
|
add_sub_impl!(Sub, sub, ClosedSub;
|
2021-06-27 00:39:02 +08:00
|
|
|
|
(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>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
&self.coords - &right.coords; 'a, 'b);
|
|
|
|
|
|
|
|
|
|
add_sub_impl!(Sub, sub, ClosedSub;
|
2021-06-27 00:39:02 +08:00
|
|
|
|
(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>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
&self.coords - right.coords; 'a);
|
|
|
|
|
|
|
|
|
|
add_sub_impl!(Sub, sub, ClosedSub;
|
2021-06-27 00:39:02 +08:00
|
|
|
|
(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>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
self.coords - &right.coords; 'b);
|
|
|
|
|
|
|
|
|
|
add_sub_impl!(Sub, sub, ClosedSub;
|
2021-06-27 00:39:02 +08:00
|
|
|
|
(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>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
self.coords - right.coords; );
|
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
// Point - Vector
|
2016-12-05 05:44:42 +08:00
|
|
|
|
add_sub_impl!(Sub, sub, ClosedSub;
|
2021-06-27 00:39:02 +08:00
|
|
|
|
(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>;
|
2018-10-24 02:47:42 +08:00
|
|
|
|
Self::Output::from(&self.coords - right); 'a, 'b);
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
add_sub_impl!(Sub, sub, ClosedSub;
|
2021-06-27 00:39:02 +08:00
|
|
|
|
(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>;
|
2020-11-15 23:57:49 +08:00
|
|
|
|
Self::Output::from(&self.coords - &right); 'a); // TODO: should not be a ref to `right`.
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
add_sub_impl!(Sub, sub, ClosedSub;
|
2021-06-27 00:39:02 +08:00
|
|
|
|
(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>;
|
2018-10-24 02:47:42 +08:00
|
|
|
|
Self::Output::from(self.coords - right); 'b);
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
add_sub_impl!(Sub, sub, ClosedSub;
|
2021-06-27 00:39:02 +08:00
|
|
|
|
(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>;
|
2018-10-24 02:47:42 +08:00
|
|
|
|
Self::Output::from(self.coords - right); );
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
// Point + Vector
|
2016-12-05 05:44:42 +08:00
|
|
|
|
add_sub_impl!(Add, add, ClosedAdd;
|
2021-06-27 00:39:02 +08:00
|
|
|
|
(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>;
|
2018-10-24 02:47:42 +08:00
|
|
|
|
Self::Output::from(&self.coords + right); 'a, 'b);
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
add_sub_impl!(Add, add, ClosedAdd;
|
2021-06-27 00:39:02 +08:00
|
|
|
|
(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>;
|
2020-11-15 23:57:49 +08:00
|
|
|
|
Self::Output::from(&self.coords + &right); 'a); // TODO: should not be a ref to `right`.
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
add_sub_impl!(Add, add, ClosedAdd;
|
2021-06-27 00:39:02 +08:00
|
|
|
|
(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>;
|
2018-10-24 02:47:42 +08:00
|
|
|
|
Self::Output::from(self.coords + right); 'b);
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
add_sub_impl!(Add, add, ClosedAdd;
|
2021-06-27 00:39:02 +08:00
|
|
|
|
(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>;
|
2018-10-24 02:47:42 +08:00
|
|
|
|
Self::Output::from(self.coords + right); );
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
2021-04-08 17:53:01 +08:00
|
|
|
|
// TODO: replace by the shared macro: add_sub_assign_impl?
|
2016-12-05 05:44:42 +08:00
|
|
|
|
macro_rules! op_assign_impl(
|
|
|
|
|
($($TraitAssign: ident, $method_assign: ident, $bound: ident);* $(;)*) => {$(
|
2021-06-27 00:39:02 +08:00
|
|
|
|
impl<'b, T, D1: DimName, D2: Dim, SB> $TraitAssign<&'b Vector<T, D2, SB>> for OPoint<T, D1>
|
2021-04-11 17:00:38 +08:00
|
|
|
|
where T: Scalar + $bound,
|
|
|
|
|
SB: Storage<T, D2>,
|
2021-06-27 00:39:02 +08:00
|
|
|
|
ShapeConstraint: SameNumberOfRows<D1, D2>,
|
|
|
|
|
DefaultAllocator: Allocator<T, D1> {
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
fn $method_assign(&mut self, right: &'b Vector<T, D2, SB>) {
|
2016-12-05 05:44:42 +08:00
|
|
|
|
self.coords.$method_assign(right)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-27 00:39:02 +08:00
|
|
|
|
impl<T, D1: DimName, D2: Dim, SB> $TraitAssign<Vector<T, D2, SB>> for OPoint<T, D1>
|
2021-04-11 17:00:38 +08:00
|
|
|
|
where T: Scalar + $bound,
|
|
|
|
|
SB: Storage<T, D2>,
|
2021-06-27 00:39:02 +08:00
|
|
|
|
ShapeConstraint: SameNumberOfRows<D1, D2>,
|
|
|
|
|
DefaultAllocator: Allocator<T, D1> {
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
fn $method_assign(&mut self, right: Vector<T, D2, SB>) {
|
2016-12-05 05:44:42 +08:00
|
|
|
|
self.coords.$method_assign(right)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)*}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
op_assign_impl!(
|
|
|
|
|
AddAssign, add_assign, ClosedAdd;
|
|
|
|
|
SubAssign, sub_assign, ClosedSub;
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
2017-08-03 01:37:44 +08:00
|
|
|
|
* Matrix × Point
|
2016-12-05 05:44:42 +08:00
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
md_impl_all!(
|
|
|
|
|
Mul, mul;
|
2021-04-08 17:53:01 +08:00
|
|
|
|
(Const<R1>, Const<C1>), (Const<D2>, U1)
|
|
|
|
|
const D2, R1, C1;
|
|
|
|
|
for SA;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
where SA: Storage<T, Const<R1>, Const<C1>>,
|
2021-04-08 17:53:01 +08:00
|
|
|
|
ShapeConstraint: AreMultipliable<Const<R1>, Const<C1>, Const<D2>, U1>;
|
2021-04-11 17:00:38 +08:00
|
|
|
|
self: Matrix<T, Const<R1>, Const<C1>, SA>, right: Point<T, D2>, Output = Point<T, R1>;
|
2018-10-24 02:47:42 +08:00
|
|
|
|
[val val] => Point::from(self * right.coords);
|
|
|
|
|
[ref val] => Point::from(self * right.coords);
|
|
|
|
|
[val ref] => Point::from(self * &right.coords);
|
|
|
|
|
[ref ref] => Point::from(self * &right.coords);
|
2016-12-05 05:44:42 +08:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
*
|
2017-08-03 01:37:44 +08:00
|
|
|
|
* Point ×/÷ Scalar
|
2016-12-05 05:44:42 +08:00
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
macro_rules! componentwise_scalarop_impl(
|
|
|
|
|
($Trait: ident, $method: ident, $bound: ident;
|
|
|
|
|
$TraitAssign: ident, $method_assign: ident) => {
|
2021-06-27 00:39:02 +08:00
|
|
|
|
impl<T: Scalar + $bound, D: DimName> $Trait<T> for OPoint<T, D>
|
|
|
|
|
where DefaultAllocator: Allocator<T, D>
|
2021-04-07 20:29:20 +08:00
|
|
|
|
{
|
2021-06-27 00:39:02 +08:00
|
|
|
|
type Output = OPoint<T, D>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
fn $method(self, right: T) -> Self::Output {
|
2021-06-27 00:39:02 +08:00
|
|
|
|
OPoint::from(self.coords.$method(right))
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-27 00:39:02 +08:00
|
|
|
|
impl<'a, T: Scalar + $bound, D: DimName> $Trait<T> for &'a OPoint<T, D>
|
|
|
|
|
where DefaultAllocator: Allocator<T, D>
|
2021-04-07 20:29:20 +08:00
|
|
|
|
{
|
2021-06-27 00:39:02 +08:00
|
|
|
|
type Output = OPoint<T, D>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
fn $method(self, right: T) -> Self::Output {
|
2021-06-27 00:39:02 +08:00
|
|
|
|
OPoint::from((&self.coords).$method(right))
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-27 00:39:02 +08:00
|
|
|
|
impl<T: Scalar + $bound, D: DimName> $TraitAssign<T> for OPoint<T, D>
|
|
|
|
|
where DefaultAllocator: Allocator<T, D>
|
2021-04-07 20:29:20 +08:00
|
|
|
|
{
|
2016-12-05 05:44:42 +08:00
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
fn $method_assign(&mut self, right: T) {
|
2016-12-05 05:44:42 +08:00
|
|
|
|
self.coords.$method_assign(right)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
componentwise_scalarop_impl!(Mul, mul, ClosedMul; MulAssign, mul_assign);
|
|
|
|
|
componentwise_scalarop_impl!(Div, div, ClosedDiv; DivAssign, div_assign);
|
|
|
|
|
|
|
|
|
|
macro_rules! left_scalar_mul_impl(
|
|
|
|
|
($($T: ty),* $(,)*) => {$(
|
2021-06-27 00:39:02 +08:00
|
|
|
|
impl<D: DimName> Mul<OPoint<$T, D>> for $T
|
|
|
|
|
where DefaultAllocator: Allocator<$T, D>
|
2021-04-07 20:29:20 +08:00
|
|
|
|
{
|
2021-06-27 00:39:02 +08:00
|
|
|
|
type Output = OPoint<$T, D>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
#[inline]
|
2021-06-27 00:39:02 +08:00
|
|
|
|
fn mul(self, right: OPoint<$T, D>) -> Self::Output {
|
|
|
|
|
OPoint::from(self * right.coords)
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-27 00:39:02 +08:00
|
|
|
|
impl<'b, D: DimName> Mul<&'b OPoint<$T, D>> for $T
|
|
|
|
|
where DefaultAllocator: Allocator<$T, D>
|
2021-04-07 20:29:20 +08:00
|
|
|
|
{
|
2021-06-27 00:39:02 +08:00
|
|
|
|
type Output = OPoint<$T, D>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
|
|
#[inline]
|
2021-06-27 00:39:02 +08:00
|
|
|
|
fn mul(self, right: &'b OPoint<$T, D>) -> Self::Output {
|
|
|
|
|
OPoint::from(self * &right.coords)
|
2016-12-05 05:44:42 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)*}
|
|
|
|
|
);
|
|
|
|
|
|
2018-02-02 19:26:35 +08:00
|
|
|
|
left_scalar_mul_impl!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize, f32, f64);
|