#![doc = " Trait implementations for conformal2."]
#![doc = ""]
#![doc = " This file is auto-generated by clifford-codegen."]
#![doc = " Do not edit manually."]
use super::types::{Circle, FlatPoint, Line, Motor, PointPair, Pseudoscalar, RoundPoint, Scalar};
#[allow(unused_imports)]
use crate::ops::{
Antidot, Antireverse, Antisandwich, Antiwedge, BulkContract, BulkExpand, Dot,
InverseAntisandwich, InverseSandwich, Involute, LeftContract, Reverse, RightComplement,
RightContract, Sandwich, ScalarProduct, Transform, Versor, VersorInverse, Wedge,
WeightContract, WeightDual, WeightExpand,
};
use crate::scalar::Float;
#[allow(unused_imports)]
use crate::wrappers::Unit;
use approx::{AbsDiffEq, RelativeEq, UlpsEq};
use std::ops::{Add, Mul, Neg, Sub};
impl<T: Float> Add for Circle<T> {
type Output = Self;
#[inline]
fn add(self, rhs: Self) -> Self {
Self::new_unchecked(
self.w() + rhs.w(),
self.e12em() + rhs.e12em(),
self.e1epem() + rhs.e1epem(),
self.e2epem() + rhs.e2epem(),
)
}
}
impl<T: Float> Sub for Circle<T> {
type Output = Self;
#[inline]
fn sub(self, rhs: Self) -> Self {
Self::new_unchecked(
self.w() - rhs.w(),
self.e12em() - rhs.e12em(),
self.e1epem() - rhs.e1epem(),
self.e2epem() - rhs.e2epem(),
)
}
}
impl<T: Float> Neg for Circle<T> {
type Output = Self;
#[inline]
fn neg(self) -> Self {
Self::new_unchecked(-self.w(), -self.e12em(), -self.e1epem(), -self.e2epem())
}
}
impl<T: Float> Mul<T> for Circle<T> {
type Output = Self;
#[inline]
fn mul(self, scalar: T) -> Self {
self.scale(scalar)
}
}
impl Mul<Circle<f32>> for f32 {
type Output = Circle<f32>;
#[inline]
fn mul(self, v: Circle<f32>) -> Circle<f32> {
v.scale(self)
}
}
impl Mul<Circle<f64>> for f64 {
type Output = Circle<f64>;
#[inline]
fn mul(self, v: Circle<f64>) -> Circle<f64> {
v.scale(self)
}
}
impl<T: Float> Mul<Pseudoscalar<T>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn mul(self, rhs: Pseudoscalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.ps() * self.e2epem()),
rhs.ps() * self.e1epem(),
-(rhs.ps() * self.e12em()),
-(rhs.ps() * self.w()),
)
}
}
impl<T: Float> Mul<Scalar<T>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn mul(self, rhs: Scalar<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.s() * self.w(),
rhs.s() * self.e12em(),
rhs.s() * self.e1epem(),
rhs.s() * self.e2epem(),
)
}
}
impl<T: Float> Add for FlatPoint<T> {
type Output = Self;
#[inline]
fn add(self, rhs: Self) -> Self {
Self::new_unchecked(
self.e1em() + rhs.e1em(),
self.e2em() + rhs.e2em(),
self.epem() + rhs.epem(),
)
}
}
impl<T: Float> Sub for FlatPoint<T> {
type Output = Self;
#[inline]
fn sub(self, rhs: Self) -> Self {
Self::new_unchecked(
self.e1em() - rhs.e1em(),
self.e2em() - rhs.e2em(),
self.epem() - rhs.epem(),
)
}
}
impl<T: Float> Neg for FlatPoint<T> {
type Output = Self;
#[inline]
fn neg(self) -> Self {
Self::new_unchecked(-self.e1em(), -self.e2em(), -self.epem())
}
}
impl<T: Float> Mul<T> for FlatPoint<T> {
type Output = Self;
#[inline]
fn mul(self, scalar: T) -> Self {
self.scale(scalar)
}
}
impl Mul<FlatPoint<f32>> for f32 {
type Output = FlatPoint<f32>;
#[inline]
fn mul(self, v: FlatPoint<f32>) -> FlatPoint<f32> {
v.scale(self)
}
}
impl Mul<FlatPoint<f64>> for f64 {
type Output = FlatPoint<f64>;
#[inline]
fn mul(self, v: FlatPoint<f64>) -> FlatPoint<f64> {
v.scale(self)
}
}
impl<T: Float> Mul<Motor<T>> for FlatPoint<T> {
type Output = Motor<T>;
#[inline]
fn mul(self, rhs: Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(rhs.e1ep() * self.e2em()) + rhs.e2ep() * self.e1em() + rhs.m() * self.epem(),
-(rhs.s() * self.epem()) + rhs.e1ep() * self.e1em() + rhs.e2ep() * self.e2em(),
-(rhs.m() * self.e1em()) + rhs.e2ep() * self.epem() + rhs.s() * self.e2em(),
-(rhs.e1ep() * self.epem()) + -(rhs.m() * self.e2em()) + -(rhs.s() * self.e1em()),
-(rhs.epem() * self.e2em()) + rhs.e2em() * self.epem() + rhs.ps() * self.e1em(),
-(rhs.e1em() * self.epem()) + rhs.epem() * self.e1em() + rhs.ps() * self.e2em(),
-(rhs.e2em() * self.e1em()) + rhs.e1em() * self.e2em() + rhs.ps() * self.epem(),
-(rhs.e1em() * self.e1em()) + -(rhs.e2em() * self.e2em()) + -(rhs.epem() * self.epem()),
)
}
}
impl<T: Float> Mul<PointPair<T>> for FlatPoint<T> {
type Output = Motor<T>;
#[inline]
fn mul(self, rhs: PointPair<T>) -> Motor<T> {
Motor::new_unchecked(
rhs.e1em() * self.e1em() + rhs.e2em() * self.e2em() + rhs.epem() * self.epem(),
-(rhs.e1em() * self.e2em()) + rhs.e2em() * self.e1em(),
-(rhs.e1em() * self.epem()) + rhs.epem() * self.e1em(),
-(rhs.e2em() * self.epem()) + rhs.epem() * self.e2em(),
-(rhs.e1ep() * self.epem()) + -(rhs.m() * self.e2em()),
-(rhs.e2ep() * self.epem()) + rhs.m() * self.e1em(),
rhs.e1ep() * self.e1em() + rhs.e2ep() * self.e2em(),
-(rhs.e1ep() * self.e2em()) + rhs.e2ep() * self.e1em() + rhs.m() * self.epem(),
)
}
}
impl<T: Float> Mul<Scalar<T>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn mul(self, rhs: Scalar<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.s() * self.e1em(),
rhs.s() * self.e2em(),
rhs.s() * self.epem(),
)
}
}
impl<T: Float> Add for Line<T> {
type Output = Self;
#[inline]
fn add(self, rhs: Self) -> Self {
Self::new_unchecked(
self.nx() + rhs.nx(),
self.ny() + rhs.ny(),
self.d() + rhs.d(),
)
}
}
impl<T: Float> Sub for Line<T> {
type Output = Self;
#[inline]
fn sub(self, rhs: Self) -> Self {
Self::new_unchecked(
self.nx() - rhs.nx(),
self.ny() - rhs.ny(),
self.d() - rhs.d(),
)
}
}
impl<T: Float> Neg for Line<T> {
type Output = Self;
#[inline]
fn neg(self) -> Self {
Self::new_unchecked(-self.nx(), -self.ny(), -self.d())
}
}
impl<T: Float> Mul<T> for Line<T> {
type Output = Self;
#[inline]
fn mul(self, scalar: T) -> Self {
self.scale(scalar)
}
}
impl Mul<Line<f32>> for f32 {
type Output = Line<f32>;
#[inline]
fn mul(self, v: Line<f32>) -> Line<f32> {
v.scale(self)
}
}
impl Mul<Line<f64>> for f64 {
type Output = Line<f64>;
#[inline]
fn mul(self, v: Line<f64>) -> Line<f64> {
v.scale(self)
}
}
impl<T: Float> Mul<Scalar<T>> for Line<T> {
type Output = Line<T>;
#[inline]
fn mul(self, rhs: Scalar<T>) -> Line<T> {
Line::new_unchecked(rhs.s() * self.nx(), rhs.s() * self.ny(), rhs.s() * self.d())
}
}
impl<T: Float> Add for Motor<T> {
type Output = Self;
#[inline]
fn add(self, rhs: Self) -> Self {
Self::new_unchecked(
self.s() + rhs.s(),
self.m() + rhs.m(),
self.e1ep() + rhs.e1ep(),
self.e2ep() + rhs.e2ep(),
self.e1em() + rhs.e1em(),
self.e2em() + rhs.e2em(),
self.epem() + rhs.epem(),
self.ps() + rhs.ps(),
)
}
}
impl<T: Float> Sub for Motor<T> {
type Output = Self;
#[inline]
fn sub(self, rhs: Self) -> Self {
Self::new_unchecked(
self.s() - rhs.s(),
self.m() - rhs.m(),
self.e1ep() - rhs.e1ep(),
self.e2ep() - rhs.e2ep(),
self.e1em() - rhs.e1em(),
self.e2em() - rhs.e2em(),
self.epem() - rhs.epem(),
self.ps() - rhs.ps(),
)
}
}
impl<T: Float> Neg for Motor<T> {
type Output = Self;
#[inline]
fn neg(self) -> Self {
Self::new_unchecked(
-self.s(),
-self.m(),
-self.e1ep(),
-self.e2ep(),
-self.e1em(),
-self.e2em(),
-self.epem(),
-self.ps(),
)
}
}
impl<T: Float> Mul<T> for Motor<T> {
type Output = Self;
#[inline]
fn mul(self, scalar: T) -> Self {
self.scale(scalar)
}
}
impl Mul<Motor<f32>> for f32 {
type Output = Motor<f32>;
#[inline]
fn mul(self, v: Motor<f32>) -> Motor<f32> {
v.scale(self)
}
}
impl Mul<Motor<f64>> for f64 {
type Output = Motor<f64>;
#[inline]
fn mul(self, v: Motor<f64>) -> Motor<f64> {
v.scale(self)
}
}
impl<T: Float> Mul<FlatPoint<T>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn mul(self, rhs: FlatPoint<T>) -> Motor<T> {
Motor::new_unchecked(
-(rhs.e2em() * self.e1ep()) + rhs.e1em() * self.e2ep() + rhs.epem() * self.m(),
-(rhs.e1em() * self.e1ep()) + -(rhs.e2em() * self.e2ep()) + -(rhs.epem() * self.s()),
-(rhs.epem() * self.e2ep()) + rhs.e1em() * self.m() + rhs.e2em() * self.s(),
-(rhs.e1em() * self.s()) + rhs.e2em() * self.m() + rhs.epem() * self.e1ep(),
-(rhs.epem() * self.e2em()) + rhs.e1em() * self.ps() + rhs.e2em() * self.epem(),
-(rhs.e1em() * self.epem()) + rhs.e2em() * self.ps() + rhs.epem() * self.e1em(),
-(rhs.e2em() * self.e1em()) + rhs.e1em() * self.e2em() + rhs.epem() * self.ps(),
-(rhs.e1em() * self.e1em()) + -(rhs.e2em() * self.e2em()) + -(rhs.epem() * self.epem()),
)
}
}
impl<T: Float> Mul<Motor<T>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn mul(self, rhs: Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(rhs.e1ep() * self.e2em())
+ -(rhs.e2em() * self.e1ep())
+ rhs.e1em() * self.e2ep()
+ rhs.e2ep() * self.e1em()
+ rhs.epem() * self.m()
+ rhs.m() * self.epem()
+ rhs.ps() * self.s()
+ rhs.s() * self.ps(),
-(rhs.e1em() * self.e1ep())
+ -(rhs.e2em() * self.e2ep())
+ -(rhs.epem() * self.s())
+ -(rhs.s() * self.epem())
+ rhs.e1ep() * self.e1em()
+ rhs.e2ep() * self.e2em()
+ rhs.m() * self.ps()
+ rhs.ps() * self.m(),
-(rhs.epem() * self.e2ep())
+ -(rhs.m() * self.e1em())
+ rhs.e1em() * self.m()
+ rhs.e1ep() * self.ps()
+ rhs.e2em() * self.s()
+ rhs.e2ep() * self.epem()
+ rhs.ps() * self.e1ep()
+ rhs.s() * self.e2em(),
-(rhs.e1em() * self.s())
+ -(rhs.e1ep() * self.epem())
+ -(rhs.m() * self.e2em())
+ -(rhs.s() * self.e1em())
+ rhs.e2em() * self.m()
+ rhs.e2ep() * self.ps()
+ rhs.epem() * self.e1ep()
+ rhs.ps() * self.e2ep(),
-(rhs.epem() * self.e2em())
+ -(rhs.m() * self.e1ep())
+ rhs.e1em() * self.ps()
+ rhs.e1ep() * self.m()
+ rhs.e2em() * self.epem()
+ rhs.e2ep() * self.s()
+ rhs.ps() * self.e1em()
+ rhs.s() * self.e2ep(),
-(rhs.e1em() * self.epem())
+ -(rhs.e1ep() * self.s())
+ -(rhs.m() * self.e2ep())
+ -(rhs.s() * self.e1ep())
+ rhs.e2em() * self.ps()
+ rhs.e2ep() * self.m()
+ rhs.epem() * self.e1em()
+ rhs.ps() * self.e2em(),
-(rhs.e1ep() * self.e2ep())
+ -(rhs.e2em() * self.e1em())
+ rhs.e1em() * self.e2em()
+ rhs.e2ep() * self.e1ep()
+ rhs.epem() * self.ps()
+ rhs.m() * self.s()
+ rhs.ps() * self.epem()
+ rhs.s() * self.m(),
-(rhs.e1em() * self.e1em())
+ -(rhs.e2em() * self.e2em())
+ -(rhs.epem() * self.epem())
+ -(rhs.s() * self.s())
+ rhs.e1ep() * self.e1ep()
+ rhs.e2ep() * self.e2ep()
+ rhs.m() * self.m()
+ rhs.ps() * self.ps(),
)
}
}
impl<T: Float> Mul<PointPair<T>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn mul(self, rhs: PointPair<T>) -> Motor<T> {
Motor::new_unchecked(
-(rhs.e1ep() * self.e1ep())
+ -(rhs.e2ep() * self.e2ep())
+ -(rhs.m() * self.m())
+ rhs.e1em() * self.e1em()
+ rhs.e2em() * self.e2em()
+ rhs.epem() * self.epem(),
-(rhs.e1em() * self.e2em())
+ -(rhs.e2ep() * self.e1ep())
+ rhs.e1ep() * self.e2ep()
+ rhs.e2em() * self.e1em()
+ rhs.epem() * self.ps()
+ rhs.m() * self.s(),
-(rhs.e1em() * self.epem())
+ -(rhs.e2em() * self.ps())
+ -(rhs.m() * self.e2ep())
+ rhs.e1ep() * self.s()
+ rhs.e2ep() * self.m()
+ rhs.epem() * self.e1em(),
-(rhs.e1ep() * self.m())
+ -(rhs.e2em() * self.epem())
+ rhs.e1em() * self.ps()
+ rhs.e2ep() * self.s()
+ rhs.epem() * self.e2em()
+ rhs.m() * self.e1ep(),
-(rhs.e1ep() * self.epem())
+ -(rhs.e2ep() * self.ps())
+ -(rhs.m() * self.e2em())
+ rhs.e1em() * self.s()
+ rhs.e2em() * self.m()
+ rhs.epem() * self.e1ep(),
-(rhs.e1em() * self.m())
+ -(rhs.e2ep() * self.epem())
+ rhs.e1ep() * self.ps()
+ rhs.e2em() * self.s()
+ rhs.epem() * self.e2ep()
+ rhs.m() * self.e1em(),
-(rhs.e1em() * self.e1ep())
+ -(rhs.e2em() * self.e2ep())
+ -(rhs.m() * self.ps())
+ rhs.e1ep() * self.e1em()
+ rhs.e2ep() * self.e2em()
+ rhs.epem() * self.s(),
-(rhs.e1ep() * self.e2em())
+ -(rhs.e2em() * self.e1ep())
+ rhs.e1em() * self.e2ep()
+ rhs.e2ep() * self.e1em()
+ rhs.epem() * self.m()
+ rhs.m() * self.epem(),
)
}
}
impl<T: Float> Mul<Pseudoscalar<T>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn mul(self, rhs: Pseudoscalar<T>) -> Motor<T> {
Motor::new_unchecked(
-(rhs.ps() * self.ps()),
rhs.ps() * self.epem(),
-(rhs.ps() * self.e2em()),
rhs.ps() * self.e1em(),
-(rhs.ps() * self.e2ep()),
rhs.ps() * self.e1ep(),
-(rhs.ps() * self.m()),
rhs.ps() * self.s(),
)
}
}
impl<T: Float> Mul<Scalar<T>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn mul(self, rhs: Scalar<T>) -> Motor<T> {
Motor::new_unchecked(
rhs.s() * self.s(),
rhs.s() * self.m(),
rhs.s() * self.e1ep(),
rhs.s() * self.e2ep(),
rhs.s() * self.e1em(),
rhs.s() * self.e2em(),
rhs.s() * self.epem(),
rhs.s() * self.ps(),
)
}
}
impl<T: Float> Add for PointPair<T> {
type Output = Self;
#[inline]
fn add(self, rhs: Self) -> Self {
Self::new_unchecked(
self.m() + rhs.m(),
self.e1ep() + rhs.e1ep(),
self.e2ep() + rhs.e2ep(),
self.e1em() + rhs.e1em(),
self.e2em() + rhs.e2em(),
self.epem() + rhs.epem(),
)
}
}
impl<T: Float> Sub for PointPair<T> {
type Output = Self;
#[inline]
fn sub(self, rhs: Self) -> Self {
Self::new_unchecked(
self.m() - rhs.m(),
self.e1ep() - rhs.e1ep(),
self.e2ep() - rhs.e2ep(),
self.e1em() - rhs.e1em(),
self.e2em() - rhs.e2em(),
self.epem() - rhs.epem(),
)
}
}
impl<T: Float> Neg for PointPair<T> {
type Output = Self;
#[inline]
fn neg(self) -> Self {
Self::new_unchecked(
-self.m(),
-self.e1ep(),
-self.e2ep(),
-self.e1em(),
-self.e2em(),
-self.epem(),
)
}
}
impl<T: Float> Mul<T> for PointPair<T> {
type Output = Self;
#[inline]
fn mul(self, scalar: T) -> Self {
self.scale(scalar)
}
}
impl Mul<PointPair<f32>> for f32 {
type Output = PointPair<f32>;
#[inline]
fn mul(self, v: PointPair<f32>) -> PointPair<f32> {
v.scale(self)
}
}
impl Mul<PointPair<f64>> for f64 {
type Output = PointPair<f64>;
#[inline]
fn mul(self, v: PointPair<f64>) -> PointPair<f64> {
v.scale(self)
}
}
impl<T: Float> Mul<FlatPoint<T>> for PointPair<T> {
type Output = Motor<T>;
#[inline]
fn mul(self, rhs: FlatPoint<T>) -> Motor<T> {
Motor::new_unchecked(
rhs.e1em() * self.e1em() + rhs.e2em() * self.e2em() + rhs.epem() * self.epem(),
-(rhs.e1em() * self.e2em()) + rhs.e2em() * self.e1em(),
-(rhs.e1em() * self.epem()) + rhs.epem() * self.e1em(),
-(rhs.e2em() * self.epem()) + rhs.epem() * self.e2em(),
rhs.e2em() * self.m() + rhs.epem() * self.e1ep(),
-(rhs.e1em() * self.m()) + rhs.epem() * self.e2ep(),
-(rhs.e1em() * self.e1ep()) + -(rhs.e2em() * self.e2ep()),
-(rhs.e2em() * self.e1ep()) + rhs.e1em() * self.e2ep() + rhs.epem() * self.m(),
)
}
}
impl<T: Float> Mul<Motor<T>> for PointPair<T> {
type Output = Motor<T>;
#[inline]
fn mul(self, rhs: Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(rhs.e1ep() * self.e1ep())
+ -(rhs.e2ep() * self.e2ep())
+ -(rhs.m() * self.m())
+ rhs.e1em() * self.e1em()
+ rhs.e2em() * self.e2em()
+ rhs.epem() * self.epem(),
-(rhs.e1em() * self.e2em())
+ -(rhs.e2ep() * self.e1ep())
+ rhs.e1ep() * self.e2ep()
+ rhs.e2em() * self.e1em()
+ rhs.ps() * self.epem()
+ rhs.s() * self.m(),
-(rhs.e1em() * self.epem())
+ -(rhs.m() * self.e2ep())
+ -(rhs.ps() * self.e2em())
+ rhs.e2ep() * self.m()
+ rhs.epem() * self.e1em()
+ rhs.s() * self.e1ep(),
-(rhs.e1ep() * self.m())
+ -(rhs.e2em() * self.epem())
+ rhs.epem() * self.e2em()
+ rhs.m() * self.e1ep()
+ rhs.ps() * self.e1em()
+ rhs.s() * self.e2ep(),
-(rhs.e1ep() * self.epem())
+ -(rhs.m() * self.e2em())
+ -(rhs.ps() * self.e2ep())
+ rhs.e2em() * self.m()
+ rhs.epem() * self.e1ep()
+ rhs.s() * self.e1em(),
-(rhs.e1em() * self.m())
+ -(rhs.e2ep() * self.epem())
+ rhs.epem() * self.e2ep()
+ rhs.m() * self.e1em()
+ rhs.ps() * self.e1ep()
+ rhs.s() * self.e2em(),
-(rhs.e1em() * self.e1ep())
+ -(rhs.e2em() * self.e2ep())
+ -(rhs.ps() * self.m())
+ rhs.e1ep() * self.e1em()
+ rhs.e2ep() * self.e2em()
+ rhs.s() * self.epem(),
-(rhs.e1ep() * self.e2em())
+ -(rhs.e2em() * self.e1ep())
+ rhs.e1em() * self.e2ep()
+ rhs.e2ep() * self.e1em()
+ rhs.epem() * self.m()
+ rhs.m() * self.epem(),
)
}
}
impl<T: Float> Mul<PointPair<T>> for PointPair<T> {
type Output = Motor<T>;
#[inline]
fn mul(self, rhs: PointPair<T>) -> Motor<T> {
Motor::new_unchecked(
-(rhs.e1ep() * self.e1ep())
+ -(rhs.e2ep() * self.e2ep())
+ -(rhs.m() * self.m())
+ rhs.e1em() * self.e1em()
+ rhs.e2em() * self.e2em()
+ rhs.epem() * self.epem(),
-(rhs.e1em() * self.e2em())
+ -(rhs.e2ep() * self.e1ep())
+ rhs.e1ep() * self.e2ep()
+ rhs.e2em() * self.e1em(),
-(rhs.e1em() * self.epem())
+ -(rhs.m() * self.e2ep())
+ rhs.e2ep() * self.m()
+ rhs.epem() * self.e1em(),
-(rhs.e1ep() * self.m())
+ -(rhs.e2em() * self.epem())
+ rhs.epem() * self.e2em()
+ rhs.m() * self.e1ep(),
-(rhs.e1ep() * self.epem())
+ -(rhs.m() * self.e2em())
+ rhs.e2em() * self.m()
+ rhs.epem() * self.e1ep(),
-(rhs.e1em() * self.m())
+ -(rhs.e2ep() * self.epem())
+ rhs.epem() * self.e2ep()
+ rhs.m() * self.e1em(),
-(rhs.e1em() * self.e1ep())
+ -(rhs.e2em() * self.e2ep())
+ rhs.e1ep() * self.e1em()
+ rhs.e2ep() * self.e2em(),
-(rhs.e1ep() * self.e2em())
+ -(rhs.e2em() * self.e1ep())
+ rhs.e1em() * self.e2ep()
+ rhs.e2ep() * self.e1em()
+ rhs.epem() * self.m()
+ rhs.m() * self.epem(),
)
}
}
impl<T: Float> Mul<Pseudoscalar<T>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn mul(self, rhs: Pseudoscalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.ps() * self.epem(),
-(rhs.ps() * self.e2em()),
rhs.ps() * self.e1em(),
-(rhs.ps() * self.e2ep()),
rhs.ps() * self.e1ep(),
-(rhs.ps() * self.m()),
)
}
}
impl<T: Float> Mul<Scalar<T>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn mul(self, rhs: Scalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.s() * self.m(),
rhs.s() * self.e1ep(),
rhs.s() * self.e2ep(),
rhs.s() * self.e1em(),
rhs.s() * self.e2em(),
rhs.s() * self.epem(),
)
}
}
impl<T: Float> Add for Pseudoscalar<T> {
type Output = Self;
#[inline]
fn add(self, rhs: Self) -> Self {
Self::new_unchecked(self.ps() + rhs.ps())
}
}
impl<T: Float> Sub for Pseudoscalar<T> {
type Output = Self;
#[inline]
fn sub(self, rhs: Self) -> Self {
Self::new_unchecked(self.ps() - rhs.ps())
}
}
impl<T: Float> Neg for Pseudoscalar<T> {
type Output = Self;
#[inline]
fn neg(self) -> Self {
Self::new_unchecked(-self.ps())
}
}
impl<T: Float> Mul<T> for Pseudoscalar<T> {
type Output = Self;
#[inline]
fn mul(self, scalar: T) -> Self {
self.scale(scalar)
}
}
impl Mul<Pseudoscalar<f32>> for f32 {
type Output = Pseudoscalar<f32>;
#[inline]
fn mul(self, v: Pseudoscalar<f32>) -> Pseudoscalar<f32> {
v.scale(self)
}
}
impl Mul<Pseudoscalar<f64>> for f64 {
type Output = Pseudoscalar<f64>;
#[inline]
fn mul(self, v: Pseudoscalar<f64>) -> Pseudoscalar<f64> {
v.scale(self)
}
}
impl<T: Float> Mul<Circle<T>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn mul(self, rhs: Circle<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.e2epem() * self.ps(),
-(rhs.e1epem() * self.ps()),
rhs.e12em() * self.ps(),
rhs.w() * self.ps(),
)
}
}
impl<T: Float> Mul<Motor<T>> for Pseudoscalar<T> {
type Output = Motor<T>;
#[inline]
fn mul(self, rhs: Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(rhs.ps() * self.ps()),
rhs.epem() * self.ps(),
-(rhs.e2em() * self.ps()),
rhs.e1em() * self.ps(),
-(rhs.e2ep() * self.ps()),
rhs.e1ep() * self.ps(),
-(rhs.m() * self.ps()),
rhs.s() * self.ps(),
)
}
}
impl<T: Float> Mul<PointPair<T>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn mul(self, rhs: PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.epem() * self.ps(),
-(rhs.e2em() * self.ps()),
rhs.e1em() * self.ps(),
-(rhs.e2ep() * self.ps()),
rhs.e1ep() * self.ps(),
-(rhs.m() * self.ps()),
)
}
}
impl<T: Float> Mul<Pseudoscalar<T>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn mul(self, rhs: Pseudoscalar<T>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.ps() * self.ps()))
}
}
impl<T: Float> Mul<RoundPoint<T>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn mul(self, rhs: RoundPoint<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.em() * self.ps()),
-(rhs.ep() * self.ps()),
rhs.y() * self.ps(),
-(rhs.x() * self.ps()),
)
}
}
impl<T: Float> Mul<Scalar<T>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn mul(self, rhs: Scalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.s() * self.ps())
}
}
impl<T: Float> Add for RoundPoint<T> {
type Output = Self;
#[inline]
fn add(self, rhs: Self) -> Self {
Self::new_unchecked(
self.x() + rhs.x(),
self.y() + rhs.y(),
self.ep() + rhs.ep(),
self.em() + rhs.em(),
)
}
}
impl<T: Float> Sub for RoundPoint<T> {
type Output = Self;
#[inline]
fn sub(self, rhs: Self) -> Self {
Self::new_unchecked(
self.x() - rhs.x(),
self.y() - rhs.y(),
self.ep() - rhs.ep(),
self.em() - rhs.em(),
)
}
}
impl<T: Float> Neg for RoundPoint<T> {
type Output = Self;
#[inline]
fn neg(self) -> Self {
Self::new_unchecked(-self.x(), -self.y(), -self.ep(), -self.em())
}
}
impl<T: Float> Mul<T> for RoundPoint<T> {
type Output = Self;
#[inline]
fn mul(self, scalar: T) -> Self {
self.scale(scalar)
}
}
impl Mul<RoundPoint<f32>> for f32 {
type Output = RoundPoint<f32>;
#[inline]
fn mul(self, v: RoundPoint<f32>) -> RoundPoint<f32> {
v.scale(self)
}
}
impl Mul<RoundPoint<f64>> for f64 {
type Output = RoundPoint<f64>;
#[inline]
fn mul(self, v: RoundPoint<f64>) -> RoundPoint<f64> {
v.scale(self)
}
}
impl<T: Float> Mul<Pseudoscalar<T>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn mul(self, rhs: Pseudoscalar<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.ps() * self.em(),
rhs.ps() * self.ep(),
-(rhs.ps() * self.y()),
rhs.ps() * self.x(),
)
}
}
impl<T: Float> Mul<Scalar<T>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn mul(self, rhs: Scalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.s() * self.x(),
rhs.s() * self.y(),
rhs.s() * self.ep(),
rhs.s() * self.em(),
)
}
}
impl<T: Float> Add for Scalar<T> {
type Output = Self;
#[inline]
fn add(self, rhs: Self) -> Self {
Self::new_unchecked(self.s() + rhs.s())
}
}
impl<T: Float> Sub for Scalar<T> {
type Output = Self;
#[inline]
fn sub(self, rhs: Self) -> Self {
Self::new_unchecked(self.s() - rhs.s())
}
}
impl<T: Float> Neg for Scalar<T> {
type Output = Self;
#[inline]
fn neg(self) -> Self {
Self::new_unchecked(-self.s())
}
}
impl<T: Float> Mul<T> for Scalar<T> {
type Output = Self;
#[inline]
fn mul(self, scalar: T) -> Self {
self.scale(scalar)
}
}
impl Mul<Scalar<f32>> for f32 {
type Output = Scalar<f32>;
#[inline]
fn mul(self, v: Scalar<f32>) -> Scalar<f32> {
v.scale(self)
}
}
impl Mul<Scalar<f64>> for f64 {
type Output = Scalar<f64>;
#[inline]
fn mul(self, v: Scalar<f64>) -> Scalar<f64> {
v.scale(self)
}
}
impl<T: Float> Mul<Circle<T>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn mul(self, rhs: Circle<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.w() * self.s(),
rhs.e12em() * self.s(),
rhs.e1epem() * self.s(),
rhs.e2epem() * self.s(),
)
}
}
impl<T: Float> Mul<FlatPoint<T>> for Scalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn mul(self, rhs: FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.e1em() * self.s(),
rhs.e2em() * self.s(),
rhs.epem() * self.s(),
)
}
}
impl<T: Float> Mul<Line<T>> for Scalar<T> {
type Output = Line<T>;
#[inline]
fn mul(self, rhs: Line<T>) -> Line<T> {
Line::new_unchecked(rhs.nx() * self.s(), rhs.ny() * self.s(), rhs.d() * self.s())
}
}
impl<T: Float> Mul<Motor<T>> for Scalar<T> {
type Output = Motor<T>;
#[inline]
fn mul(self, rhs: Motor<T>) -> Motor<T> {
Motor::new_unchecked(
rhs.s() * self.s(),
rhs.m() * self.s(),
rhs.e1ep() * self.s(),
rhs.e2ep() * self.s(),
rhs.e1em() * self.s(),
rhs.e2em() * self.s(),
rhs.epem() * self.s(),
rhs.ps() * self.s(),
)
}
}
impl<T: Float> Mul<PointPair<T>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn mul(self, rhs: PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.m() * self.s(),
rhs.e1ep() * self.s(),
rhs.e2ep() * self.s(),
rhs.e1em() * self.s(),
rhs.e2em() * self.s(),
rhs.epem() * self.s(),
)
}
}
impl<T: Float> Mul<Pseudoscalar<T>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn mul(self, rhs: Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.ps() * self.s())
}
}
impl<T: Float> Mul<RoundPoint<T>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn mul(self, rhs: RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.x() * self.s(),
rhs.y() * self.s(),
rhs.ep() * self.s(),
rhs.em() * self.s(),
)
}
}
impl<T: Float> Mul<Scalar<T>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn mul(self, rhs: Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.s() * self.s())
}
}
#[doc = "Wedge (exterior/outer) product of [`Circle`] and [`RoundPoint`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<RoundPoint<T>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &RoundPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.ep() * self.e12em())
+ -(rhs.x() * self.e2epem())
+ rhs.em() * self.w()
+ rhs.y() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<RoundPoint<T>> for Unit<Circle<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &RoundPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.ep() * self.as_inner().e12em())
+ -(rhs.x() * self.as_inner().e2epem())
+ rhs.em() * self.as_inner().w()
+ rhs.y() * self.as_inner().e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<RoundPoint<T>>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<RoundPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().ep() * self.e12em())
+ -(rhs.as_inner().x() * self.e2epem())
+ rhs.as_inner().em() * self.w()
+ rhs.as_inner().y() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<RoundPoint<T>>> for Unit<Circle<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<RoundPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().ep() * self.as_inner().e12em())
+ -(rhs.as_inner().x() * self.as_inner().e2epem())
+ rhs.as_inner().em() * self.as_inner().w()
+ rhs.as_inner().y() * self.as_inner().e1epem(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`Circle`] and [`Scalar`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<Scalar<T>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn wedge(&self, rhs: &Scalar<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.s() * self.w(),
rhs.s() * self.e12em(),
rhs.s() * self.e1epem(),
rhs.s() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Scalar<T>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn wedge(&self, rhs: &Scalar<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.s() * self.as_inner().w(),
rhs.s() * self.as_inner().e12em(),
rhs.s() * self.as_inner().e1epem(),
rhs.s() * self.as_inner().e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Scalar<T>>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Scalar<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().s() * self.w(),
rhs.as_inner().s() * self.e12em(),
rhs.as_inner().s() * self.e1epem(),
rhs.as_inner().s() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Scalar<T>>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Scalar<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().s() * self.as_inner().w(),
rhs.as_inner().s() * self.as_inner().e12em(),
rhs.as_inner().s() * self.as_inner().e1epem(),
rhs.as_inner().s() * self.as_inner().e2epem(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`FlatPoint`] and [`PointPair`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<PointPair<T>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &PointPair<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e1ep() * self.e2em()) + rhs.e2ep() * self.e1em() + rhs.m() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<PointPair<T>> for Unit<FlatPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &PointPair<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e1ep() * self.as_inner().e2em())
+ rhs.e2ep() * self.as_inner().e1em()
+ rhs.m() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<PointPair<T>>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<PointPair<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e1ep() * self.e2em())
+ rhs.as_inner().e2ep() * self.e1em()
+ rhs.as_inner().m() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<PointPair<T>>> for Unit<FlatPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<PointPair<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e1ep() * self.as_inner().e2em())
+ rhs.as_inner().e2ep() * self.as_inner().e1em()
+ rhs.as_inner().m() * self.as_inner().epem(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`FlatPoint`] and [`RoundPoint`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<RoundPoint<T>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn wedge(&self, rhs: &RoundPoint<T>) -> Line<T> {
Line::new_unchecked(
-(rhs.y() * self.e1em()) + rhs.x() * self.e2em(),
-(rhs.ep() * self.e1em()) + rhs.x() * self.epem(),
-(rhs.ep() * self.e2em()) + rhs.y() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<RoundPoint<T>> for Unit<FlatPoint<T>> {
type Output = Line<T>;
#[inline]
fn wedge(&self, rhs: &RoundPoint<T>) -> Line<T> {
Line::new_unchecked(
-(rhs.y() * self.as_inner().e1em()) + rhs.x() * self.as_inner().e2em(),
-(rhs.ep() * self.as_inner().e1em()) + rhs.x() * self.as_inner().epem(),
-(rhs.ep() * self.as_inner().e2em()) + rhs.y() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<RoundPoint<T>>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn wedge(&self, rhs: &Unit<RoundPoint<T>>) -> Line<T> {
Line::new_unchecked(
-(rhs.as_inner().y() * self.e1em()) + rhs.as_inner().x() * self.e2em(),
-(rhs.as_inner().ep() * self.e1em()) + rhs.as_inner().x() * self.epem(),
-(rhs.as_inner().ep() * self.e2em()) + rhs.as_inner().y() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<RoundPoint<T>>> for Unit<FlatPoint<T>> {
type Output = Line<T>;
#[inline]
fn wedge(&self, rhs: &Unit<RoundPoint<T>>) -> Line<T> {
Line::new_unchecked(
-(rhs.as_inner().y() * self.as_inner().e1em())
+ rhs.as_inner().x() * self.as_inner().e2em(),
-(rhs.as_inner().ep() * self.as_inner().e1em())
+ rhs.as_inner().x() * self.as_inner().epem(),
-(rhs.as_inner().ep() * self.as_inner().e2em())
+ rhs.as_inner().y() * self.as_inner().epem(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`FlatPoint`] and [`Scalar`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<Scalar<T>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn wedge(&self, rhs: &Scalar<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.s() * self.e1em(),
rhs.s() * self.e2em(),
rhs.s() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Scalar<T>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn wedge(&self, rhs: &Scalar<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.s() * self.as_inner().e1em(),
rhs.s() * self.as_inner().e2em(),
rhs.s() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Scalar<T>>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Scalar<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.as_inner().s() * self.e1em(),
rhs.as_inner().s() * self.e2em(),
rhs.as_inner().s() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Scalar<T>>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Scalar<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.as_inner().s() * self.as_inner().e1em(),
rhs.as_inner().s() * self.as_inner().e2em(),
rhs.as_inner().s() * self.as_inner().epem(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`Line`] and [`RoundPoint`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<RoundPoint<T>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &RoundPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.ep() * self.nx()) + -(rhs.x() * self.d()) + rhs.y() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<RoundPoint<T>> for Unit<Line<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &RoundPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.ep() * self.as_inner().nx())
+ -(rhs.x() * self.as_inner().d())
+ rhs.y() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<RoundPoint<T>>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<RoundPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().ep() * self.nx())
+ -(rhs.as_inner().x() * self.d())
+ rhs.as_inner().y() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<RoundPoint<T>>> for Unit<Line<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<RoundPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().ep() * self.as_inner().nx())
+ -(rhs.as_inner().x() * self.as_inner().d())
+ rhs.as_inner().y() * self.as_inner().ny(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`Line`] and [`Scalar`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<Scalar<T>> for Line<T> {
type Output = Line<T>;
#[inline]
fn wedge(&self, rhs: &Scalar<T>) -> Line<T> {
Line::new_unchecked(rhs.s() * self.nx(), rhs.s() * self.ny(), rhs.s() * self.d())
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Scalar<T>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn wedge(&self, rhs: &Scalar<T>) -> Line<T> {
Line::new_unchecked(
rhs.s() * self.as_inner().nx(),
rhs.s() * self.as_inner().ny(),
rhs.s() * self.as_inner().d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Scalar<T>>> for Line<T> {
type Output = Line<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Scalar<T>>) -> Line<T> {
Line::new_unchecked(
rhs.as_inner().s() * self.nx(),
rhs.as_inner().s() * self.ny(),
rhs.as_inner().s() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Scalar<T>>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Scalar<T>>) -> Line<T> {
Line::new_unchecked(
rhs.as_inner().s() * self.as_inner().nx(),
rhs.as_inner().s() * self.as_inner().ny(),
rhs.as_inner().s() * self.as_inner().d(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`PointPair`] and [`FlatPoint`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<FlatPoint<T>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &FlatPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e2em() * self.e1ep()) + rhs.e1em() * self.e2ep() + rhs.epem() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<FlatPoint<T>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &FlatPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e2em() * self.as_inner().e1ep())
+ rhs.e1em() * self.as_inner().e2ep()
+ rhs.epem() * self.as_inner().m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<FlatPoint<T>>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<FlatPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e2em() * self.e1ep())
+ rhs.as_inner().e1em() * self.e2ep()
+ rhs.as_inner().epem() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<FlatPoint<T>>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<FlatPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e2em() * self.as_inner().e1ep())
+ rhs.as_inner().e1em() * self.as_inner().e2ep()
+ rhs.as_inner().epem() * self.as_inner().m(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`PointPair`] and [`PointPair`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<PointPair<T>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &PointPair<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e1ep() * self.e2em())
+ -(rhs.e2em() * self.e1ep())
+ rhs.e1em() * self.e2ep()
+ rhs.e2ep() * self.e1em()
+ rhs.epem() * self.m()
+ rhs.m() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<PointPair<T>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &PointPair<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e1ep() * self.as_inner().e2em())
+ -(rhs.e2em() * self.as_inner().e1ep())
+ rhs.e1em() * self.as_inner().e2ep()
+ rhs.e2ep() * self.as_inner().e1em()
+ rhs.epem() * self.as_inner().m()
+ rhs.m() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<PointPair<T>>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<PointPair<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e1ep() * self.e2em())
+ -(rhs.as_inner().e2em() * self.e1ep())
+ rhs.as_inner().e1em() * self.e2ep()
+ rhs.as_inner().e2ep() * self.e1em()
+ rhs.as_inner().epem() * self.m()
+ rhs.as_inner().m() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<PointPair<T>>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<PointPair<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e1ep() * self.as_inner().e2em())
+ -(rhs.as_inner().e2em() * self.as_inner().e1ep())
+ rhs.as_inner().e1em() * self.as_inner().e2ep()
+ rhs.as_inner().e2ep() * self.as_inner().e1em()
+ rhs.as_inner().epem() * self.as_inner().m()
+ rhs.as_inner().m() * self.as_inner().epem(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`PointPair`] and [`RoundPoint`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<RoundPoint<T>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn wedge(&self, rhs: &RoundPoint<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.y() * self.e1ep()) + rhs.ep() * self.m() + rhs.x() * self.e2ep(),
-(rhs.y() * self.e1em()) + rhs.em() * self.m() + rhs.x() * self.e2em(),
-(rhs.ep() * self.e1em()) + rhs.em() * self.e1ep() + rhs.x() * self.epem(),
-(rhs.ep() * self.e2em()) + rhs.em() * self.e2ep() + rhs.y() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<RoundPoint<T>> for Unit<PointPair<T>> {
type Output = Circle<T>;
#[inline]
fn wedge(&self, rhs: &RoundPoint<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.y() * self.as_inner().e1ep())
+ rhs.ep() * self.as_inner().m()
+ rhs.x() * self.as_inner().e2ep(),
-(rhs.y() * self.as_inner().e1em())
+ rhs.em() * self.as_inner().m()
+ rhs.x() * self.as_inner().e2em(),
-(rhs.ep() * self.as_inner().e1em())
+ rhs.em() * self.as_inner().e1ep()
+ rhs.x() * self.as_inner().epem(),
-(rhs.ep() * self.as_inner().e2em())
+ rhs.em() * self.as_inner().e2ep()
+ rhs.y() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<RoundPoint<T>>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn wedge(&self, rhs: &Unit<RoundPoint<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().y() * self.e1ep())
+ rhs.as_inner().ep() * self.m()
+ rhs.as_inner().x() * self.e2ep(),
-(rhs.as_inner().y() * self.e1em())
+ rhs.as_inner().em() * self.m()
+ rhs.as_inner().x() * self.e2em(),
-(rhs.as_inner().ep() * self.e1em())
+ rhs.as_inner().em() * self.e1ep()
+ rhs.as_inner().x() * self.epem(),
-(rhs.as_inner().ep() * self.e2em())
+ rhs.as_inner().em() * self.e2ep()
+ rhs.as_inner().y() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<RoundPoint<T>>> for Unit<PointPair<T>> {
type Output = Circle<T>;
#[inline]
fn wedge(&self, rhs: &Unit<RoundPoint<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().y() * self.as_inner().e1ep())
+ rhs.as_inner().ep() * self.as_inner().m()
+ rhs.as_inner().x() * self.as_inner().e2ep(),
-(rhs.as_inner().y() * self.as_inner().e1em())
+ rhs.as_inner().em() * self.as_inner().m()
+ rhs.as_inner().x() * self.as_inner().e2em(),
-(rhs.as_inner().ep() * self.as_inner().e1em())
+ rhs.as_inner().em() * self.as_inner().e1ep()
+ rhs.as_inner().x() * self.as_inner().epem(),
-(rhs.as_inner().ep() * self.as_inner().e2em())
+ rhs.as_inner().em() * self.as_inner().e2ep()
+ rhs.as_inner().y() * self.as_inner().epem(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`PointPair`] and [`Scalar`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<Scalar<T>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn wedge(&self, rhs: &Scalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.s() * self.m(),
rhs.s() * self.e1ep(),
rhs.s() * self.e2ep(),
rhs.s() * self.e1em(),
rhs.s() * self.e2em(),
rhs.s() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Scalar<T>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn wedge(&self, rhs: &Scalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.s() * self.as_inner().m(),
rhs.s() * self.as_inner().e1ep(),
rhs.s() * self.as_inner().e2ep(),
rhs.s() * self.as_inner().e1em(),
rhs.s() * self.as_inner().e2em(),
rhs.s() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Scalar<T>>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Scalar<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().s() * self.m(),
rhs.as_inner().s() * self.e1ep(),
rhs.as_inner().s() * self.e2ep(),
rhs.as_inner().s() * self.e1em(),
rhs.as_inner().s() * self.e2em(),
rhs.as_inner().s() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Scalar<T>>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Scalar<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().s() * self.as_inner().m(),
rhs.as_inner().s() * self.as_inner().e1ep(),
rhs.as_inner().s() * self.as_inner().e2ep(),
rhs.as_inner().s() * self.as_inner().e1em(),
rhs.as_inner().s() * self.as_inner().e2em(),
rhs.as_inner().s() * self.as_inner().epem(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`Pseudoscalar`] and [`Scalar`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<Scalar<T>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Scalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.s() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Scalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Scalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.s() * self.as_inner().ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Scalar<T>>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Scalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.as_inner().s() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Scalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Scalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.as_inner().s() * self.as_inner().ps())
}
}
#[doc = "Wedge (exterior/outer) product of [`RoundPoint`] and [`Circle`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<Circle<T>> for RoundPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Circle<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e1epem() * self.y())
+ -(rhs.w() * self.em())
+ rhs.e12em() * self.ep()
+ rhs.e2epem() * self.x(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Circle<T>> for Unit<RoundPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Circle<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e1epem() * self.as_inner().y())
+ -(rhs.w() * self.as_inner().em())
+ rhs.e12em() * self.as_inner().ep()
+ rhs.e2epem() * self.as_inner().x(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Circle<T>>> for RoundPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Circle<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e1epem() * self.y())
+ -(rhs.as_inner().w() * self.em())
+ rhs.as_inner().e12em() * self.ep()
+ rhs.as_inner().e2epem() * self.x(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Circle<T>>> for Unit<RoundPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Circle<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e1epem() * self.as_inner().y())
+ -(rhs.as_inner().w() * self.as_inner().em())
+ rhs.as_inner().e12em() * self.as_inner().ep()
+ rhs.as_inner().e2epem() * self.as_inner().x(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`RoundPoint`] and [`FlatPoint`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<FlatPoint<T>> for RoundPoint<T> {
type Output = Line<T>;
#[inline]
fn wedge(&self, rhs: &FlatPoint<T>) -> Line<T> {
Line::new_unchecked(
-(rhs.e1em() * self.y()) + rhs.e2em() * self.x(),
-(rhs.e1em() * self.ep()) + rhs.epem() * self.x(),
-(rhs.e2em() * self.ep()) + rhs.epem() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<FlatPoint<T>> for Unit<RoundPoint<T>> {
type Output = Line<T>;
#[inline]
fn wedge(&self, rhs: &FlatPoint<T>) -> Line<T> {
Line::new_unchecked(
-(rhs.e1em() * self.as_inner().y()) + rhs.e2em() * self.as_inner().x(),
-(rhs.e1em() * self.as_inner().ep()) + rhs.epem() * self.as_inner().x(),
-(rhs.e2em() * self.as_inner().ep()) + rhs.epem() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<FlatPoint<T>>> for RoundPoint<T> {
type Output = Line<T>;
#[inline]
fn wedge(&self, rhs: &Unit<FlatPoint<T>>) -> Line<T> {
Line::new_unchecked(
-(rhs.as_inner().e1em() * self.y()) + rhs.as_inner().e2em() * self.x(),
-(rhs.as_inner().e1em() * self.ep()) + rhs.as_inner().epem() * self.x(),
-(rhs.as_inner().e2em() * self.ep()) + rhs.as_inner().epem() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<FlatPoint<T>>> for Unit<RoundPoint<T>> {
type Output = Line<T>;
#[inline]
fn wedge(&self, rhs: &Unit<FlatPoint<T>>) -> Line<T> {
Line::new_unchecked(
-(rhs.as_inner().e1em() * self.as_inner().y())
+ rhs.as_inner().e2em() * self.as_inner().x(),
-(rhs.as_inner().e1em() * self.as_inner().ep())
+ rhs.as_inner().epem() * self.as_inner().x(),
-(rhs.as_inner().e2em() * self.as_inner().ep())
+ rhs.as_inner().epem() * self.as_inner().y(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`RoundPoint`] and [`Line`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<Line<T>> for RoundPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Line<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.ny() * self.y()) + rhs.d() * self.x() + rhs.nx() * self.ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Line<T>> for Unit<RoundPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Line<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.ny() * self.as_inner().y())
+ rhs.d() * self.as_inner().x()
+ rhs.nx() * self.as_inner().ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Line<T>>> for RoundPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Line<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().ny() * self.y())
+ rhs.as_inner().d() * self.x()
+ rhs.as_inner().nx() * self.ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Line<T>>> for Unit<RoundPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Line<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().ny() * self.as_inner().y())
+ rhs.as_inner().d() * self.as_inner().x()
+ rhs.as_inner().nx() * self.as_inner().ep(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`RoundPoint`] and [`PointPair`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<PointPair<T>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn wedge(&self, rhs: &PointPair<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.e1ep() * self.y()) + rhs.e2ep() * self.x() + rhs.m() * self.ep(),
-(rhs.e1em() * self.y()) + rhs.e2em() * self.x() + rhs.m() * self.em(),
-(rhs.e1em() * self.ep()) + rhs.e1ep() * self.em() + rhs.epem() * self.x(),
-(rhs.e2em() * self.ep()) + rhs.e2ep() * self.em() + rhs.epem() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<PointPair<T>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn wedge(&self, rhs: &PointPair<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.e1ep() * self.as_inner().y())
+ rhs.e2ep() * self.as_inner().x()
+ rhs.m() * self.as_inner().ep(),
-(rhs.e1em() * self.as_inner().y())
+ rhs.e2em() * self.as_inner().x()
+ rhs.m() * self.as_inner().em(),
-(rhs.e1em() * self.as_inner().ep())
+ rhs.e1ep() * self.as_inner().em()
+ rhs.epem() * self.as_inner().x(),
-(rhs.e2em() * self.as_inner().ep())
+ rhs.e2ep() * self.as_inner().em()
+ rhs.epem() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<PointPair<T>>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn wedge(&self, rhs: &Unit<PointPair<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().e1ep() * self.y())
+ rhs.as_inner().e2ep() * self.x()
+ rhs.as_inner().m() * self.ep(),
-(rhs.as_inner().e1em() * self.y())
+ rhs.as_inner().e2em() * self.x()
+ rhs.as_inner().m() * self.em(),
-(rhs.as_inner().e1em() * self.ep())
+ rhs.as_inner().e1ep() * self.em()
+ rhs.as_inner().epem() * self.x(),
-(rhs.as_inner().e2em() * self.ep())
+ rhs.as_inner().e2ep() * self.em()
+ rhs.as_inner().epem() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<PointPair<T>>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn wedge(&self, rhs: &Unit<PointPair<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().e1ep() * self.as_inner().y())
+ rhs.as_inner().e2ep() * self.as_inner().x()
+ rhs.as_inner().m() * self.as_inner().ep(),
-(rhs.as_inner().e1em() * self.as_inner().y())
+ rhs.as_inner().e2em() * self.as_inner().x()
+ rhs.as_inner().m() * self.as_inner().em(),
-(rhs.as_inner().e1em() * self.as_inner().ep())
+ rhs.as_inner().e1ep() * self.as_inner().em()
+ rhs.as_inner().epem() * self.as_inner().x(),
-(rhs.as_inner().e2em() * self.as_inner().ep())
+ rhs.as_inner().e2ep() * self.as_inner().em()
+ rhs.as_inner().epem() * self.as_inner().y(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`RoundPoint`] and [`RoundPoint`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<RoundPoint<T>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn wedge(&self, rhs: &RoundPoint<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.x() * self.y()) + rhs.y() * self.x(),
-(rhs.x() * self.ep()) + rhs.ep() * self.x(),
-(rhs.y() * self.ep()) + rhs.ep() * self.y(),
-(rhs.x() * self.em()) + rhs.em() * self.x(),
-(rhs.y() * self.em()) + rhs.em() * self.y(),
-(rhs.ep() * self.em()) + rhs.em() * self.ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<RoundPoint<T>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn wedge(&self, rhs: &RoundPoint<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.x() * self.as_inner().y()) + rhs.y() * self.as_inner().x(),
-(rhs.x() * self.as_inner().ep()) + rhs.ep() * self.as_inner().x(),
-(rhs.y() * self.as_inner().ep()) + rhs.ep() * self.as_inner().y(),
-(rhs.x() * self.as_inner().em()) + rhs.em() * self.as_inner().x(),
-(rhs.y() * self.as_inner().em()) + rhs.em() * self.as_inner().y(),
-(rhs.ep() * self.as_inner().em()) + rhs.em() * self.as_inner().ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<RoundPoint<T>>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn wedge(&self, rhs: &Unit<RoundPoint<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().x() * self.y()) + rhs.as_inner().y() * self.x(),
-(rhs.as_inner().x() * self.ep()) + rhs.as_inner().ep() * self.x(),
-(rhs.as_inner().y() * self.ep()) + rhs.as_inner().ep() * self.y(),
-(rhs.as_inner().x() * self.em()) + rhs.as_inner().em() * self.x(),
-(rhs.as_inner().y() * self.em()) + rhs.as_inner().em() * self.y(),
-(rhs.as_inner().ep() * self.em()) + rhs.as_inner().em() * self.ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<RoundPoint<T>>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn wedge(&self, rhs: &Unit<RoundPoint<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().x() * self.as_inner().y()) + rhs.as_inner().y() * self.as_inner().x(),
-(rhs.as_inner().x() * self.as_inner().ep())
+ rhs.as_inner().ep() * self.as_inner().x(),
-(rhs.as_inner().y() * self.as_inner().ep())
+ rhs.as_inner().ep() * self.as_inner().y(),
-(rhs.as_inner().x() * self.as_inner().em())
+ rhs.as_inner().em() * self.as_inner().x(),
-(rhs.as_inner().y() * self.as_inner().em())
+ rhs.as_inner().em() * self.as_inner().y(),
-(rhs.as_inner().ep() * self.as_inner().em())
+ rhs.as_inner().em() * self.as_inner().ep(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`RoundPoint`] and [`Scalar`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<Scalar<T>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn wedge(&self, rhs: &Scalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.s() * self.x(),
rhs.s() * self.y(),
rhs.s() * self.ep(),
rhs.s() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Scalar<T>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn wedge(&self, rhs: &Scalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.s() * self.as_inner().x(),
rhs.s() * self.as_inner().y(),
rhs.s() * self.as_inner().ep(),
rhs.s() * self.as_inner().em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Scalar<T>>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Scalar<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().s() * self.x(),
rhs.as_inner().s() * self.y(),
rhs.as_inner().s() * self.ep(),
rhs.as_inner().s() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Scalar<T>>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Scalar<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().s() * self.as_inner().x(),
rhs.as_inner().s() * self.as_inner().y(),
rhs.as_inner().s() * self.as_inner().ep(),
rhs.as_inner().s() * self.as_inner().em(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`Scalar`] and [`Circle`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<Circle<T>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn wedge(&self, rhs: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.w() * self.s(),
rhs.e12em() * self.s(),
rhs.e1epem() * self.s(),
rhs.e2epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Circle<T>> for Unit<Scalar<T>> {
type Output = Circle<T>;
#[inline]
fn wedge(&self, rhs: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.w() * self.as_inner().s(),
rhs.e12em() * self.as_inner().s(),
rhs.e1epem() * self.as_inner().s(),
rhs.e2epem() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Circle<T>>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().w() * self.s(),
rhs.as_inner().e12em() * self.s(),
rhs.as_inner().e1epem() * self.s(),
rhs.as_inner().e2epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Circle<T>>> for Unit<Scalar<T>> {
type Output = Circle<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().w() * self.as_inner().s(),
rhs.as_inner().e12em() * self.as_inner().s(),
rhs.as_inner().e1epem() * self.as_inner().s(),
rhs.as_inner().e2epem() * self.as_inner().s(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`Scalar`] and [`FlatPoint`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<FlatPoint<T>> for Scalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn wedge(&self, rhs: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.e1em() * self.s(),
rhs.e2em() * self.s(),
rhs.epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<FlatPoint<T>> for Unit<Scalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn wedge(&self, rhs: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.e1em() * self.as_inner().s(),
rhs.e2em() * self.as_inner().s(),
rhs.epem() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<FlatPoint<T>>> for Scalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn wedge(&self, rhs: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.as_inner().e1em() * self.s(),
rhs.as_inner().e2em() * self.s(),
rhs.as_inner().epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<FlatPoint<T>>> for Unit<Scalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn wedge(&self, rhs: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().s(),
rhs.as_inner().e2em() * self.as_inner().s(),
rhs.as_inner().epem() * self.as_inner().s(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`Scalar`] and [`Line`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<Line<T>> for Scalar<T> {
type Output = Line<T>;
#[inline]
fn wedge(&self, rhs: &Line<T>) -> Line<T> {
Line::new_unchecked(rhs.nx() * self.s(), rhs.ny() * self.s(), rhs.d() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Line<T>> for Unit<Scalar<T>> {
type Output = Line<T>;
#[inline]
fn wedge(&self, rhs: &Line<T>) -> Line<T> {
Line::new_unchecked(
rhs.nx() * self.as_inner().s(),
rhs.ny() * self.as_inner().s(),
rhs.d() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Line<T>>> for Scalar<T> {
type Output = Line<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
rhs.as_inner().nx() * self.s(),
rhs.as_inner().ny() * self.s(),
rhs.as_inner().d() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Line<T>>> for Unit<Scalar<T>> {
type Output = Line<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
rhs.as_inner().nx() * self.as_inner().s(),
rhs.as_inner().ny() * self.as_inner().s(),
rhs.as_inner().d() * self.as_inner().s(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`Scalar`] and [`PointPair`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<PointPair<T>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn wedge(&self, rhs: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.m() * self.s(),
rhs.e1ep() * self.s(),
rhs.e2ep() * self.s(),
rhs.e1em() * self.s(),
rhs.e2em() * self.s(),
rhs.epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<PointPair<T>> for Unit<Scalar<T>> {
type Output = PointPair<T>;
#[inline]
fn wedge(&self, rhs: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.m() * self.as_inner().s(),
rhs.e1ep() * self.as_inner().s(),
rhs.e2ep() * self.as_inner().s(),
rhs.e1em() * self.as_inner().s(),
rhs.e2em() * self.as_inner().s(),
rhs.epem() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<PointPair<T>>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn wedge(&self, rhs: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().m() * self.s(),
rhs.as_inner().e1ep() * self.s(),
rhs.as_inner().e2ep() * self.s(),
rhs.as_inner().e1em() * self.s(),
rhs.as_inner().e2em() * self.s(),
rhs.as_inner().epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<PointPair<T>>> for Unit<Scalar<T>> {
type Output = PointPair<T>;
#[inline]
fn wedge(&self, rhs: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().m() * self.as_inner().s(),
rhs.as_inner().e1ep() * self.as_inner().s(),
rhs.as_inner().e2ep() * self.as_inner().s(),
rhs.as_inner().e1em() * self.as_inner().s(),
rhs.as_inner().e2em() * self.as_inner().s(),
rhs.as_inner().epem() * self.as_inner().s(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`Scalar`] and [`Pseudoscalar`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<Pseudoscalar<T>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.ps() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Pseudoscalar<T>> for Unit<Scalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.ps() * self.as_inner().s())
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Pseudoscalar<T>>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.as_inner().ps() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Pseudoscalar<T>>> for Unit<Scalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.as_inner().ps() * self.as_inner().s())
}
}
#[doc = "Wedge (exterior/outer) product of [`Scalar`] and [`RoundPoint`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<RoundPoint<T>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn wedge(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.x() * self.s(),
rhs.y() * self.s(),
rhs.ep() * self.s(),
rhs.em() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<RoundPoint<T>> for Unit<Scalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn wedge(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.x() * self.as_inner().s(),
rhs.y() * self.as_inner().s(),
rhs.ep() * self.as_inner().s(),
rhs.em() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<RoundPoint<T>>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn wedge(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().x() * self.s(),
rhs.as_inner().y() * self.s(),
rhs.as_inner().ep() * self.s(),
rhs.as_inner().em() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<RoundPoint<T>>> for Unit<Scalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn wedge(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().x() * self.as_inner().s(),
rhs.as_inner().y() * self.as_inner().s(),
rhs.as_inner().ep() * self.as_inner().s(),
rhs.as_inner().em() * self.as_inner().s(),
)
}
}
#[doc = "Wedge (exterior/outer) product of [`Scalar`] and [`Scalar`].\n\nThe wedge product `a ^ b` computes the outer product, which represents\nthe oriented subspace spanned by both operands. The result grade is the\nsum of the input grades (or zero if they share common factors)."]
impl<T: Float> Wedge<Scalar<T>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn wedge(&self, rhs: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.s() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Scalar<T>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn wedge(&self, rhs: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.s() * self.as_inner().s())
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Scalar<T>>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(rhs.as_inner().s() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> Wedge<Unit<Scalar<T>>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn wedge(&self, rhs: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(rhs.as_inner().s() * self.as_inner().s())
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Circle`] and [`Circle`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Circle<T>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Circle<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.w() * self.e12em()) + rhs.e12em() * self.w(),
-(rhs.w() * self.e1epem()) + rhs.e1epem() * self.w(),
-(rhs.w() * self.e2epem()) + rhs.e2epem() * self.w(),
-(rhs.e12em() * self.e1epem()) + rhs.e1epem() * self.e12em(),
-(rhs.e12em() * self.e2epem()) + rhs.e2epem() * self.e12em(),
-(rhs.e1epem() * self.e2epem()) + rhs.e2epem() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Circle<T>> for Unit<Circle<T>> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Circle<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.w() * self.as_inner().e12em()) + rhs.e12em() * self.as_inner().w(),
-(rhs.w() * self.as_inner().e1epem()) + rhs.e1epem() * self.as_inner().w(),
-(rhs.w() * self.as_inner().e2epem()) + rhs.e2epem() * self.as_inner().w(),
-(rhs.e12em() * self.as_inner().e1epem()) + rhs.e1epem() * self.as_inner().e12em(),
-(rhs.e12em() * self.as_inner().e2epem()) + rhs.e2epem() * self.as_inner().e12em(),
-(rhs.e1epem() * self.as_inner().e2epem()) + rhs.e2epem() * self.as_inner().e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Circle<T>>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Circle<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().w() * self.e12em()) + rhs.as_inner().e12em() * self.w(),
-(rhs.as_inner().w() * self.e1epem()) + rhs.as_inner().e1epem() * self.w(),
-(rhs.as_inner().w() * self.e2epem()) + rhs.as_inner().e2epem() * self.w(),
-(rhs.as_inner().e12em() * self.e1epem()) + rhs.as_inner().e1epem() * self.e12em(),
-(rhs.as_inner().e12em() * self.e2epem()) + rhs.as_inner().e2epem() * self.e12em(),
-(rhs.as_inner().e1epem() * self.e2epem()) + rhs.as_inner().e2epem() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Circle<T>>> for Unit<Circle<T>> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Circle<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().w() * self.as_inner().e12em())
+ rhs.as_inner().e12em() * self.as_inner().w(),
-(rhs.as_inner().w() * self.as_inner().e1epem())
+ rhs.as_inner().e1epem() * self.as_inner().w(),
-(rhs.as_inner().w() * self.as_inner().e2epem())
+ rhs.as_inner().e2epem() * self.as_inner().w(),
-(rhs.as_inner().e12em() * self.as_inner().e1epem())
+ rhs.as_inner().e1epem() * self.as_inner().e12em(),
-(rhs.as_inner().e12em() * self.as_inner().e2epem())
+ rhs.as_inner().e2epem() * self.as_inner().e12em(),
-(rhs.as_inner().e1epem() * self.as_inner().e2epem())
+ rhs.as_inner().e2epem() * self.as_inner().e1epem(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Circle`] and [`FlatPoint`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<FlatPoint<T>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &FlatPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e1em() * self.w()),
-(rhs.e2em() * self.w()),
-(rhs.epem() * self.w()),
-(rhs.e1em() * self.e2epem())
+ -(rhs.epem() * self.e12em())
+ rhs.e2em() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<FlatPoint<T>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &FlatPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e1em() * self.as_inner().w()),
-(rhs.e2em() * self.as_inner().w()),
-(rhs.epem() * self.as_inner().w()),
-(rhs.e1em() * self.as_inner().e2epem())
+ -(rhs.epem() * self.as_inner().e12em())
+ rhs.e2em() * self.as_inner().e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<FlatPoint<T>>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<FlatPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e1em() * self.w()),
-(rhs.as_inner().e2em() * self.w()),
-(rhs.as_inner().epem() * self.w()),
-(rhs.as_inner().e1em() * self.e2epem())
+ -(rhs.as_inner().epem() * self.e12em())
+ rhs.as_inner().e2em() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<FlatPoint<T>>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<FlatPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e1em() * self.as_inner().w()),
-(rhs.as_inner().e2em() * self.as_inner().w()),
-(rhs.as_inner().epem() * self.as_inner().w()),
-(rhs.as_inner().e1em() * self.as_inner().e2epem())
+ -(rhs.as_inner().epem() * self.as_inner().e12em())
+ rhs.as_inner().e2em() * self.as_inner().e1epem(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Circle`] and [`Line`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Line<T>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Line<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.nx() * self.w(),
rhs.ny() * self.w(),
rhs.d() * self.w(),
-(rhs.nx() * self.e1epem()) + rhs.ny() * self.e12em(),
-(rhs.nx() * self.e2epem()) + rhs.d() * self.e12em(),
-(rhs.ny() * self.e2epem()) + rhs.d() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Line<T>> for Unit<Circle<T>> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Line<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.nx() * self.as_inner().w(),
rhs.ny() * self.as_inner().w(),
rhs.d() * self.as_inner().w(),
-(rhs.nx() * self.as_inner().e1epem()) + rhs.ny() * self.as_inner().e12em(),
-(rhs.nx() * self.as_inner().e2epem()) + rhs.d() * self.as_inner().e12em(),
-(rhs.ny() * self.as_inner().e2epem()) + rhs.d() * self.as_inner().e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Line<T>>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Line<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().nx() * self.w(),
rhs.as_inner().ny() * self.w(),
rhs.as_inner().d() * self.w(),
-(rhs.as_inner().nx() * self.e1epem()) + rhs.as_inner().ny() * self.e12em(),
-(rhs.as_inner().nx() * self.e2epem()) + rhs.as_inner().d() * self.e12em(),
-(rhs.as_inner().ny() * self.e2epem()) + rhs.as_inner().d() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Line<T>>> for Unit<Circle<T>> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Line<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().nx() * self.as_inner().w(),
rhs.as_inner().ny() * self.as_inner().w(),
rhs.as_inner().d() * self.as_inner().w(),
-(rhs.as_inner().nx() * self.as_inner().e1epem())
+ rhs.as_inner().ny() * self.as_inner().e12em(),
-(rhs.as_inner().nx() * self.as_inner().e2epem())
+ rhs.as_inner().d() * self.as_inner().e12em(),
-(rhs.as_inner().ny() * self.as_inner().e2epem())
+ rhs.as_inner().d() * self.as_inner().e1epem(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Circle`] and [`PointPair`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<PointPair<T>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e1em() * self.w()) + -(rhs.m() * self.e1epem()) + rhs.e1ep() * self.e12em(),
-(rhs.e2em() * self.w()) + -(rhs.m() * self.e2epem()) + rhs.e2ep() * self.e12em(),
-(rhs.e1ep() * self.e2epem()) + -(rhs.epem() * self.w()) + rhs.e2ep() * self.e1epem(),
-(rhs.e1em() * self.e2epem())
+ -(rhs.epem() * self.e12em())
+ rhs.e2em() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<PointPair<T>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e1em() * self.as_inner().w())
+ -(rhs.m() * self.as_inner().e1epem())
+ rhs.e1ep() * self.as_inner().e12em(),
-(rhs.e2em() * self.as_inner().w())
+ -(rhs.m() * self.as_inner().e2epem())
+ rhs.e2ep() * self.as_inner().e12em(),
-(rhs.e1ep() * self.as_inner().e2epem())
+ -(rhs.epem() * self.as_inner().w())
+ rhs.e2ep() * self.as_inner().e1epem(),
-(rhs.e1em() * self.as_inner().e2epem())
+ -(rhs.epem() * self.as_inner().e12em())
+ rhs.e2em() * self.as_inner().e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<PointPair<T>>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e1em() * self.w())
+ -(rhs.as_inner().m() * self.e1epem())
+ rhs.as_inner().e1ep() * self.e12em(),
-(rhs.as_inner().e2em() * self.w())
+ -(rhs.as_inner().m() * self.e2epem())
+ rhs.as_inner().e2ep() * self.e12em(),
-(rhs.as_inner().e1ep() * self.e2epem())
+ -(rhs.as_inner().epem() * self.w())
+ rhs.as_inner().e2ep() * self.e1epem(),
-(rhs.as_inner().e1em() * self.e2epem())
+ -(rhs.as_inner().epem() * self.e12em())
+ rhs.as_inner().e2em() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<PointPair<T>>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e1em() * self.as_inner().w())
+ -(rhs.as_inner().m() * self.as_inner().e1epem())
+ rhs.as_inner().e1ep() * self.as_inner().e12em(),
-(rhs.as_inner().e2em() * self.as_inner().w())
+ -(rhs.as_inner().m() * self.as_inner().e2epem())
+ rhs.as_inner().e2ep() * self.as_inner().e12em(),
-(rhs.as_inner().e1ep() * self.as_inner().e2epem())
+ -(rhs.as_inner().epem() * self.as_inner().w())
+ rhs.as_inner().e2ep() * self.as_inner().e1epem(),
-(rhs.as_inner().e1em() * self.as_inner().e2epem())
+ -(rhs.as_inner().epem() * self.as_inner().e12em())
+ rhs.as_inner().e2em() * self.as_inner().e1epem(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Circle`] and [`Pseudoscalar`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Pseudoscalar<T>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn antiwedge(&self, rhs: &Pseudoscalar<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.ps() * self.w()),
-(rhs.ps() * self.e12em()),
-(rhs.ps() * self.e1epem()),
-(rhs.ps() * self.e2epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Pseudoscalar<T>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn antiwedge(&self, rhs: &Pseudoscalar<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.ps() * self.as_inner().w()),
-(rhs.ps() * self.as_inner().e12em()),
-(rhs.ps() * self.as_inner().e1epem()),
-(rhs.ps() * self.as_inner().e2epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Pseudoscalar<T>>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Pseudoscalar<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().ps() * self.w()),
-(rhs.as_inner().ps() * self.e12em()),
-(rhs.as_inner().ps() * self.e1epem()),
-(rhs.as_inner().ps() * self.e2epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Pseudoscalar<T>>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Pseudoscalar<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().ps() * self.as_inner().w()),
-(rhs.as_inner().ps() * self.as_inner().e12em()),
-(rhs.as_inner().ps() * self.as_inner().e1epem()),
-(rhs.as_inner().ps() * self.as_inner().e2epem()),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Circle`] and [`RoundPoint`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<RoundPoint<T>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &RoundPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.ep() * self.e12em())
+ -(rhs.x() * self.e2epem())
+ rhs.em() * self.w()
+ rhs.y() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<RoundPoint<T>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &RoundPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.ep() * self.as_inner().e12em())
+ -(rhs.x() * self.as_inner().e2epem())
+ rhs.em() * self.as_inner().w()
+ rhs.y() * self.as_inner().e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<RoundPoint<T>>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<RoundPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().ep() * self.e12em())
+ -(rhs.as_inner().x() * self.e2epem())
+ rhs.as_inner().em() * self.w()
+ rhs.as_inner().y() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<RoundPoint<T>>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<RoundPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().ep() * self.as_inner().e12em())
+ -(rhs.as_inner().x() * self.as_inner().e2epem())
+ rhs.as_inner().em() * self.as_inner().w()
+ rhs.as_inner().y() * self.as_inner().e1epem(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`FlatPoint`] and [`Circle`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Circle<T>> for FlatPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Circle<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.w() * self.e1em()),
-(rhs.w() * self.e2em()),
-(rhs.w() * self.epem()),
-(rhs.e12em() * self.epem())
+ -(rhs.e2epem() * self.e1em())
+ rhs.e1epem() * self.e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Circle<T>> for Unit<FlatPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Circle<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.w() * self.as_inner().e1em()),
-(rhs.w() * self.as_inner().e2em()),
-(rhs.w() * self.as_inner().epem()),
-(rhs.e12em() * self.as_inner().epem())
+ -(rhs.e2epem() * self.as_inner().e1em())
+ rhs.e1epem() * self.as_inner().e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Circle<T>>> for FlatPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Circle<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().w() * self.e1em()),
-(rhs.as_inner().w() * self.e2em()),
-(rhs.as_inner().w() * self.epem()),
-(rhs.as_inner().e12em() * self.epem())
+ -(rhs.as_inner().e2epem() * self.e1em())
+ rhs.as_inner().e1epem() * self.e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Circle<T>>> for Unit<FlatPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Circle<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().w() * self.as_inner().e1em()),
-(rhs.as_inner().w() * self.as_inner().e2em()),
-(rhs.as_inner().w() * self.as_inner().epem()),
-(rhs.as_inner().e12em() * self.as_inner().epem())
+ -(rhs.as_inner().e2epem() * self.as_inner().e1em())
+ rhs.as_inner().e1epem() * self.as_inner().e2em(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`FlatPoint`] and [`PointPair`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<PointPair<T>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1ep() * self.e2em()) + rhs.e2ep() * self.e1em() + rhs.m() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<PointPair<T>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1ep() * self.as_inner().e2em())
+ rhs.e2ep() * self.as_inner().e1em()
+ rhs.m() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<PointPair<T>>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1ep() * self.e2em())
+ rhs.as_inner().e2ep() * self.e1em()
+ rhs.as_inner().m() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<PointPair<T>>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1ep() * self.as_inner().e2em())
+ rhs.as_inner().e2ep() * self.as_inner().e1em()
+ rhs.as_inner().m() * self.as_inner().epem(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`FlatPoint`] and [`Pseudoscalar`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Pseudoscalar<T>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Pseudoscalar<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.ps() * self.e1em(),
rhs.ps() * self.e2em(),
rhs.ps() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Pseudoscalar<T>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Pseudoscalar<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.ps() * self.as_inner().e1em(),
rhs.ps() * self.as_inner().e2em(),
rhs.ps() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Pseudoscalar<T>>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Pseudoscalar<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.as_inner().ps() * self.e1em(),
rhs.as_inner().ps() * self.e2em(),
rhs.as_inner().ps() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Pseudoscalar<T>>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Pseudoscalar<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.as_inner().ps() * self.as_inner().e1em(),
rhs.as_inner().ps() * self.as_inner().e2em(),
rhs.as_inner().ps() * self.as_inner().epem(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Line`] and [`Circle`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Circle<T>> for Line<T> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Circle<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.w() * self.nx()),
-(rhs.w() * self.ny()),
-(rhs.w() * self.d()),
-(rhs.e12em() * self.ny()) + rhs.e1epem() * self.nx(),
-(rhs.e12em() * self.d()) + rhs.e2epem() * self.nx(),
-(rhs.e1epem() * self.d()) + rhs.e2epem() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Circle<T>> for Unit<Line<T>> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Circle<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.w() * self.as_inner().nx()),
-(rhs.w() * self.as_inner().ny()),
-(rhs.w() * self.as_inner().d()),
-(rhs.e12em() * self.as_inner().ny()) + rhs.e1epem() * self.as_inner().nx(),
-(rhs.e12em() * self.as_inner().d()) + rhs.e2epem() * self.as_inner().nx(),
-(rhs.e1epem() * self.as_inner().d()) + rhs.e2epem() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Circle<T>>> for Line<T> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Circle<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().w() * self.nx()),
-(rhs.as_inner().w() * self.ny()),
-(rhs.as_inner().w() * self.d()),
-(rhs.as_inner().e12em() * self.ny()) + rhs.as_inner().e1epem() * self.nx(),
-(rhs.as_inner().e12em() * self.d()) + rhs.as_inner().e2epem() * self.nx(),
-(rhs.as_inner().e1epem() * self.d()) + rhs.as_inner().e2epem() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Circle<T>>> for Unit<Line<T>> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Circle<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().w() * self.as_inner().nx()),
-(rhs.as_inner().w() * self.as_inner().ny()),
-(rhs.as_inner().w() * self.as_inner().d()),
-(rhs.as_inner().e12em() * self.as_inner().ny())
+ rhs.as_inner().e1epem() * self.as_inner().nx(),
-(rhs.as_inner().e12em() * self.as_inner().d())
+ rhs.as_inner().e2epem() * self.as_inner().nx(),
-(rhs.as_inner().e1epem() * self.as_inner().d())
+ rhs.as_inner().e2epem() * self.as_inner().ny(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Line`] and [`Line`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Line<T>> for Line<T> {
type Output = FlatPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Line<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(rhs.nx() * self.ny()) + rhs.ny() * self.nx(),
-(rhs.nx() * self.d()) + rhs.d() * self.nx(),
-(rhs.ny() * self.d()) + rhs.d() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Line<T>> for Unit<Line<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Line<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(rhs.nx() * self.as_inner().ny()) + rhs.ny() * self.as_inner().nx(),
-(rhs.nx() * self.as_inner().d()) + rhs.d() * self.as_inner().nx(),
-(rhs.ny() * self.as_inner().d()) + rhs.d() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Line<T>>> for Line<T> {
type Output = FlatPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Line<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(rhs.as_inner().nx() * self.ny()) + rhs.as_inner().ny() * self.nx(),
-(rhs.as_inner().nx() * self.d()) + rhs.as_inner().d() * self.nx(),
-(rhs.as_inner().ny() * self.d()) + rhs.as_inner().d() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Line<T>>> for Unit<Line<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Line<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(rhs.as_inner().nx() * self.as_inner().ny())
+ rhs.as_inner().ny() * self.as_inner().nx(),
-(rhs.as_inner().nx() * self.as_inner().d())
+ rhs.as_inner().d() * self.as_inner().nx(),
-(rhs.as_inner().ny() * self.as_inner().d())
+ rhs.as_inner().d() * self.as_inner().ny(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Line`] and [`PointPair`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<PointPair<T>> for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.m() * self.ny()) + rhs.e1ep() * self.nx(),
-(rhs.m() * self.d()) + rhs.e2ep() * self.nx(),
-(rhs.e1ep() * self.d()) + rhs.e2ep() * self.ny(),
-(rhs.e1em() * self.d()) + -(rhs.epem() * self.nx()) + rhs.e2em() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<PointPair<T>> for Unit<Line<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.m() * self.as_inner().ny()) + rhs.e1ep() * self.as_inner().nx(),
-(rhs.m() * self.as_inner().d()) + rhs.e2ep() * self.as_inner().nx(),
-(rhs.e1ep() * self.as_inner().d()) + rhs.e2ep() * self.as_inner().ny(),
-(rhs.e1em() * self.as_inner().d())
+ -(rhs.epem() * self.as_inner().nx())
+ rhs.e2em() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<PointPair<T>>> for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().m() * self.ny()) + rhs.as_inner().e1ep() * self.nx(),
-(rhs.as_inner().m() * self.d()) + rhs.as_inner().e2ep() * self.nx(),
-(rhs.as_inner().e1ep() * self.d()) + rhs.as_inner().e2ep() * self.ny(),
-(rhs.as_inner().e1em() * self.d())
+ -(rhs.as_inner().epem() * self.nx())
+ rhs.as_inner().e2em() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<PointPair<T>>> for Unit<Line<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().m() * self.as_inner().ny())
+ rhs.as_inner().e1ep() * self.as_inner().nx(),
-(rhs.as_inner().m() * self.as_inner().d())
+ rhs.as_inner().e2ep() * self.as_inner().nx(),
-(rhs.as_inner().e1ep() * self.as_inner().d())
+ rhs.as_inner().e2ep() * self.as_inner().ny(),
-(rhs.as_inner().e1em() * self.as_inner().d())
+ -(rhs.as_inner().epem() * self.as_inner().nx())
+ rhs.as_inner().e2em() * self.as_inner().ny(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Line`] and [`Pseudoscalar`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Pseudoscalar<T>> for Line<T> {
type Output = Line<T>;
#[inline]
fn antiwedge(&self, rhs: &Pseudoscalar<T>) -> Line<T> {
Line::new_unchecked(
-(rhs.ps() * self.nx()),
-(rhs.ps() * self.ny()),
-(rhs.ps() * self.d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Pseudoscalar<T>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn antiwedge(&self, rhs: &Pseudoscalar<T>) -> Line<T> {
Line::new_unchecked(
-(rhs.ps() * self.as_inner().nx()),
-(rhs.ps() * self.as_inner().ny()),
-(rhs.ps() * self.as_inner().d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Pseudoscalar<T>>> for Line<T> {
type Output = Line<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Pseudoscalar<T>>) -> Line<T> {
Line::new_unchecked(
-(rhs.as_inner().ps() * self.nx()),
-(rhs.as_inner().ps() * self.ny()),
-(rhs.as_inner().ps() * self.d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Pseudoscalar<T>>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Pseudoscalar<T>>) -> Line<T> {
Line::new_unchecked(
-(rhs.as_inner().ps() * self.as_inner().nx()),
-(rhs.as_inner().ps() * self.as_inner().ny()),
-(rhs.as_inner().ps() * self.as_inner().d()),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Line`] and [`RoundPoint`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<RoundPoint<T>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &RoundPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.ep() * self.nx()) + -(rhs.x() * self.d()) + rhs.y() * self.ny())
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<RoundPoint<T>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &RoundPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.ep() * self.as_inner().nx())
+ -(rhs.x() * self.as_inner().d())
+ rhs.y() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<RoundPoint<T>>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<RoundPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().ep() * self.nx())
+ -(rhs.as_inner().x() * self.d())
+ rhs.as_inner().y() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<RoundPoint<T>>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<RoundPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().ep() * self.as_inner().nx())
+ -(rhs.as_inner().x() * self.as_inner().d())
+ rhs.as_inner().y() * self.as_inner().ny(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`PointPair`] and [`Circle`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Circle<T>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Circle<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e1epem() * self.m()) + -(rhs.w() * self.e1em()) + rhs.e12em() * self.e1ep(),
-(rhs.e2epem() * self.m()) + -(rhs.w() * self.e2em()) + rhs.e12em() * self.e2ep(),
-(rhs.e2epem() * self.e1ep()) + -(rhs.w() * self.epem()) + rhs.e1epem() * self.e2ep(),
-(rhs.e12em() * self.epem())
+ -(rhs.e2epem() * self.e1em())
+ rhs.e1epem() * self.e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Circle<T>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Circle<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e1epem() * self.as_inner().m())
+ -(rhs.w() * self.as_inner().e1em())
+ rhs.e12em() * self.as_inner().e1ep(),
-(rhs.e2epem() * self.as_inner().m())
+ -(rhs.w() * self.as_inner().e2em())
+ rhs.e12em() * self.as_inner().e2ep(),
-(rhs.e2epem() * self.as_inner().e1ep())
+ -(rhs.w() * self.as_inner().epem())
+ rhs.e1epem() * self.as_inner().e2ep(),
-(rhs.e12em() * self.as_inner().epem())
+ -(rhs.e2epem() * self.as_inner().e1em())
+ rhs.e1epem() * self.as_inner().e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Circle<T>>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Circle<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e1epem() * self.m())
+ -(rhs.as_inner().w() * self.e1em())
+ rhs.as_inner().e12em() * self.e1ep(),
-(rhs.as_inner().e2epem() * self.m())
+ -(rhs.as_inner().w() * self.e2em())
+ rhs.as_inner().e12em() * self.e2ep(),
-(rhs.as_inner().e2epem() * self.e1ep())
+ -(rhs.as_inner().w() * self.epem())
+ rhs.as_inner().e1epem() * self.e2ep(),
-(rhs.as_inner().e12em() * self.epem())
+ -(rhs.as_inner().e2epem() * self.e1em())
+ rhs.as_inner().e1epem() * self.e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Circle<T>>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Circle<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e1epem() * self.as_inner().m())
+ -(rhs.as_inner().w() * self.as_inner().e1em())
+ rhs.as_inner().e12em() * self.as_inner().e1ep(),
-(rhs.as_inner().e2epem() * self.as_inner().m())
+ -(rhs.as_inner().w() * self.as_inner().e2em())
+ rhs.as_inner().e12em() * self.as_inner().e2ep(),
-(rhs.as_inner().e2epem() * self.as_inner().e1ep())
+ -(rhs.as_inner().w() * self.as_inner().epem())
+ rhs.as_inner().e1epem() * self.as_inner().e2ep(),
-(rhs.as_inner().e12em() * self.as_inner().epem())
+ -(rhs.as_inner().e2epem() * self.as_inner().e1em())
+ rhs.as_inner().e1epem() * self.as_inner().e2em(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`PointPair`] and [`FlatPoint`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<FlatPoint<T>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e2em() * self.e1ep()) + rhs.e1em() * self.e2ep() + rhs.epem() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<FlatPoint<T>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e2em() * self.as_inner().e1ep())
+ rhs.e1em() * self.as_inner().e2ep()
+ rhs.epem() * self.as_inner().m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<FlatPoint<T>>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e2em() * self.e1ep())
+ rhs.as_inner().e1em() * self.e2ep()
+ rhs.as_inner().epem() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<FlatPoint<T>>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e2em() * self.as_inner().e1ep())
+ rhs.as_inner().e1em() * self.as_inner().e2ep()
+ rhs.as_inner().epem() * self.as_inner().m(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`PointPair`] and [`Line`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Line<T>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Line<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.ny() * self.m()) + rhs.nx() * self.e1ep(),
-(rhs.d() * self.m()) + rhs.nx() * self.e2ep(),
-(rhs.d() * self.e1ep()) + rhs.ny() * self.e2ep(),
-(rhs.d() * self.e1em()) + -(rhs.nx() * self.epem()) + rhs.ny() * self.e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Line<T>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Line<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.ny() * self.as_inner().m()) + rhs.nx() * self.as_inner().e1ep(),
-(rhs.d() * self.as_inner().m()) + rhs.nx() * self.as_inner().e2ep(),
-(rhs.d() * self.as_inner().e1ep()) + rhs.ny() * self.as_inner().e2ep(),
-(rhs.d() * self.as_inner().e1em())
+ -(rhs.nx() * self.as_inner().epem())
+ rhs.ny() * self.as_inner().e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Line<T>>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Line<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().ny() * self.m()) + rhs.as_inner().nx() * self.e1ep(),
-(rhs.as_inner().d() * self.m()) + rhs.as_inner().nx() * self.e2ep(),
-(rhs.as_inner().d() * self.e1ep()) + rhs.as_inner().ny() * self.e2ep(),
-(rhs.as_inner().d() * self.e1em())
+ -(rhs.as_inner().nx() * self.epem())
+ rhs.as_inner().ny() * self.e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Line<T>>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Line<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().ny() * self.as_inner().m())
+ rhs.as_inner().nx() * self.as_inner().e1ep(),
-(rhs.as_inner().d() * self.as_inner().m())
+ rhs.as_inner().nx() * self.as_inner().e2ep(),
-(rhs.as_inner().d() * self.as_inner().e1ep())
+ rhs.as_inner().ny() * self.as_inner().e2ep(),
-(rhs.as_inner().d() * self.as_inner().e1em())
+ -(rhs.as_inner().nx() * self.as_inner().epem())
+ rhs.as_inner().ny() * self.as_inner().e2em(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`PointPair`] and [`PointPair`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<PointPair<T>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1ep() * self.e2em())
+ -(rhs.e2em() * self.e1ep())
+ rhs.e1em() * self.e2ep()
+ rhs.e2ep() * self.e1em()
+ rhs.epem() * self.m()
+ rhs.m() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<PointPair<T>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1ep() * self.as_inner().e2em())
+ -(rhs.e2em() * self.as_inner().e1ep())
+ rhs.e1em() * self.as_inner().e2ep()
+ rhs.e2ep() * self.as_inner().e1em()
+ rhs.epem() * self.as_inner().m()
+ rhs.m() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<PointPair<T>>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1ep() * self.e2em())
+ -(rhs.as_inner().e2em() * self.e1ep())
+ rhs.as_inner().e1em() * self.e2ep()
+ rhs.as_inner().e2ep() * self.e1em()
+ rhs.as_inner().epem() * self.m()
+ rhs.as_inner().m() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<PointPair<T>>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1ep() * self.as_inner().e2em())
+ -(rhs.as_inner().e2em() * self.as_inner().e1ep())
+ rhs.as_inner().e1em() * self.as_inner().e2ep()
+ rhs.as_inner().e2ep() * self.as_inner().e1em()
+ rhs.as_inner().epem() * self.as_inner().m()
+ rhs.as_inner().m() * self.as_inner().epem(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`PointPair`] and [`Pseudoscalar`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Pseudoscalar<T>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Pseudoscalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.ps() * self.m(),
rhs.ps() * self.e1ep(),
rhs.ps() * self.e2ep(),
rhs.ps() * self.e1em(),
rhs.ps() * self.e2em(),
rhs.ps() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Pseudoscalar<T>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Pseudoscalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.ps() * self.as_inner().m(),
rhs.ps() * self.as_inner().e1ep(),
rhs.ps() * self.as_inner().e2ep(),
rhs.ps() * self.as_inner().e1em(),
rhs.ps() * self.as_inner().e2em(),
rhs.ps() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Pseudoscalar<T>>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Pseudoscalar<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().ps() * self.m(),
rhs.as_inner().ps() * self.e1ep(),
rhs.as_inner().ps() * self.e2ep(),
rhs.as_inner().ps() * self.e1em(),
rhs.as_inner().ps() * self.e2em(),
rhs.as_inner().ps() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Pseudoscalar<T>>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Pseudoscalar<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().ps() * self.as_inner().m(),
rhs.as_inner().ps() * self.as_inner().e1ep(),
rhs.as_inner().ps() * self.as_inner().e2ep(),
rhs.as_inner().ps() * self.as_inner().e1em(),
rhs.as_inner().ps() * self.as_inner().e2em(),
rhs.as_inner().ps() * self.as_inner().epem(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Pseudoscalar`] and [`Circle`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Circle<T>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn antiwedge(&self, rhs: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.w() * self.ps()),
-(rhs.e12em() * self.ps()),
-(rhs.e1epem() * self.ps()),
-(rhs.e2epem() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Circle<T>> for Unit<Pseudoscalar<T>> {
type Output = Circle<T>;
#[inline]
fn antiwedge(&self, rhs: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.w() * self.as_inner().ps()),
-(rhs.e12em() * self.as_inner().ps()),
-(rhs.e1epem() * self.as_inner().ps()),
-(rhs.e2epem() * self.as_inner().ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Circle<T>>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().w() * self.ps()),
-(rhs.as_inner().e12em() * self.ps()),
-(rhs.as_inner().e1epem() * self.ps()),
-(rhs.as_inner().e2epem() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Circle<T>>> for Unit<Pseudoscalar<T>> {
type Output = Circle<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().w() * self.as_inner().ps()),
-(rhs.as_inner().e12em() * self.as_inner().ps()),
-(rhs.as_inner().e1epem() * self.as_inner().ps()),
-(rhs.as_inner().e2epem() * self.as_inner().ps()),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Pseudoscalar`] and [`FlatPoint`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<FlatPoint<T>> for Pseudoscalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.e1em() * self.ps(),
rhs.e2em() * self.ps(),
rhs.epem() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<FlatPoint<T>> for Unit<Pseudoscalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.e1em() * self.as_inner().ps(),
rhs.e2em() * self.as_inner().ps(),
rhs.epem() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<FlatPoint<T>>> for Pseudoscalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.as_inner().e1em() * self.ps(),
rhs.as_inner().e2em() * self.ps(),
rhs.as_inner().epem() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<FlatPoint<T>>> for Unit<Pseudoscalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().ps(),
rhs.as_inner().e2em() * self.as_inner().ps(),
rhs.as_inner().epem() * self.as_inner().ps(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Pseudoscalar`] and [`Line`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Line<T>> for Pseudoscalar<T> {
type Output = Line<T>;
#[inline]
fn antiwedge(&self, rhs: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(rhs.nx() * self.ps()),
-(rhs.ny() * self.ps()),
-(rhs.d() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Line<T>> for Unit<Pseudoscalar<T>> {
type Output = Line<T>;
#[inline]
fn antiwedge(&self, rhs: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(rhs.nx() * self.as_inner().ps()),
-(rhs.ny() * self.as_inner().ps()),
-(rhs.d() * self.as_inner().ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Line<T>>> for Pseudoscalar<T> {
type Output = Line<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(rhs.as_inner().nx() * self.ps()),
-(rhs.as_inner().ny() * self.ps()),
-(rhs.as_inner().d() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Line<T>>> for Unit<Pseudoscalar<T>> {
type Output = Line<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(rhs.as_inner().nx() * self.as_inner().ps()),
-(rhs.as_inner().ny() * self.as_inner().ps()),
-(rhs.as_inner().d() * self.as_inner().ps()),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Pseudoscalar`] and [`PointPair`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<PointPair<T>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.m() * self.ps(),
rhs.e1ep() * self.ps(),
rhs.e2ep() * self.ps(),
rhs.e1em() * self.ps(),
rhs.e2em() * self.ps(),
rhs.epem() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<PointPair<T>> for Unit<Pseudoscalar<T>> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.m() * self.as_inner().ps(),
rhs.e1ep() * self.as_inner().ps(),
rhs.e2ep() * self.as_inner().ps(),
rhs.e1em() * self.as_inner().ps(),
rhs.e2em() * self.as_inner().ps(),
rhs.epem() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<PointPair<T>>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().m() * self.ps(),
rhs.as_inner().e1ep() * self.ps(),
rhs.as_inner().e2ep() * self.ps(),
rhs.as_inner().e1em() * self.ps(),
rhs.as_inner().e2em() * self.ps(),
rhs.as_inner().epem() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<PointPair<T>>> for Unit<Pseudoscalar<T>> {
type Output = PointPair<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().m() * self.as_inner().ps(),
rhs.as_inner().e1ep() * self.as_inner().ps(),
rhs.as_inner().e2ep() * self.as_inner().ps(),
rhs.as_inner().e1em() * self.as_inner().ps(),
rhs.as_inner().e2em() * self.as_inner().ps(),
rhs.as_inner().epem() * self.as_inner().ps(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Pseudoscalar`] and [`Pseudoscalar`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Pseudoscalar<T>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.ps() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Pseudoscalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.ps() * self.as_inner().ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Pseudoscalar<T>>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.as_inner().ps() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Pseudoscalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.as_inner().ps() * self.as_inner().ps())
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Pseudoscalar`] and [`RoundPoint`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<RoundPoint<T>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.x() * self.ps()),
-(rhs.y() * self.ps()),
-(rhs.ep() * self.ps()),
-(rhs.em() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<RoundPoint<T>> for Unit<Pseudoscalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.x() * self.as_inner().ps()),
-(rhs.y() * self.as_inner().ps()),
-(rhs.ep() * self.as_inner().ps()),
-(rhs.em() * self.as_inner().ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<RoundPoint<T>>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().x() * self.ps()),
-(rhs.as_inner().y() * self.ps()),
-(rhs.as_inner().ep() * self.ps()),
-(rhs.as_inner().em() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<RoundPoint<T>>> for Unit<Pseudoscalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().x() * self.as_inner().ps()),
-(rhs.as_inner().y() * self.as_inner().ps()),
-(rhs.as_inner().ep() * self.as_inner().ps()),
-(rhs.as_inner().em() * self.as_inner().ps()),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Pseudoscalar`] and [`Scalar`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Scalar<T>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.s() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Scalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.s() * self.as_inner().ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Scalar<T>>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(rhs.as_inner().s() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Scalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(rhs.as_inner().s() * self.as_inner().ps())
}
}
#[doc = "Antiwedge (regressive/meet) product of [`RoundPoint`] and [`Circle`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Circle<T>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1epem() * self.y())
+ -(rhs.w() * self.em())
+ rhs.e12em() * self.ep()
+ rhs.e2epem() * self.x(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Circle<T>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1epem() * self.as_inner().y())
+ -(rhs.w() * self.as_inner().em())
+ rhs.e12em() * self.as_inner().ep()
+ rhs.e2epem() * self.as_inner().x(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Circle<T>>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1epem() * self.y())
+ -(rhs.as_inner().w() * self.em())
+ rhs.as_inner().e12em() * self.ep()
+ rhs.as_inner().e2epem() * self.x(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Circle<T>>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1epem() * self.as_inner().y())
+ -(rhs.as_inner().w() * self.as_inner().em())
+ rhs.as_inner().e12em() * self.as_inner().ep()
+ rhs.as_inner().e2epem() * self.as_inner().x(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`RoundPoint`] and [`Line`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Line<T>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.ny() * self.y()) + rhs.d() * self.x() + rhs.nx() * self.ep())
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Line<T>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.ny() * self.as_inner().y())
+ rhs.d() * self.as_inner().x()
+ rhs.nx() * self.as_inner().ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Line<T>>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().ny() * self.y())
+ rhs.as_inner().d() * self.x()
+ rhs.as_inner().nx() * self.ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Line<T>>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().ny() * self.as_inner().y())
+ rhs.as_inner().d() * self.as_inner().x()
+ rhs.as_inner().nx() * self.as_inner().ep(),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`RoundPoint`] and [`Pseudoscalar`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Pseudoscalar<T>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Pseudoscalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.ps() * self.x()),
-(rhs.ps() * self.y()),
-(rhs.ps() * self.ep()),
-(rhs.ps() * self.em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Pseudoscalar<T>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Pseudoscalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.ps() * self.as_inner().x()),
-(rhs.ps() * self.as_inner().y()),
-(rhs.ps() * self.as_inner().ep()),
-(rhs.ps() * self.as_inner().em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Pseudoscalar<T>>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Pseudoscalar<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().ps() * self.x()),
-(rhs.as_inner().ps() * self.y()),
-(rhs.as_inner().ps() * self.ep()),
-(rhs.as_inner().ps() * self.em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Pseudoscalar<T>>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Pseudoscalar<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().ps() * self.as_inner().x()),
-(rhs.as_inner().ps() * self.as_inner().y()),
-(rhs.as_inner().ps() * self.as_inner().ep()),
-(rhs.as_inner().ps() * self.as_inner().em()),
)
}
}
#[doc = "Antiwedge (regressive/meet) product of [`Scalar`] and [`Pseudoscalar`].\n\nThe antiwedge product `a v b` computes the meet of two subspaces,\nreturning the largest subspace contained in both. In projective geometry,\nthis finds intersections (e.g., where two planes meet to form a line)."]
impl<T: Float> Antiwedge<Pseudoscalar<T>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Pseudoscalar<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.ps() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Pseudoscalar<T>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Pseudoscalar<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.ps() * self.as_inner().s())
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Pseudoscalar<T>>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Pseudoscalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(rhs.as_inner().ps() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> Antiwedge<Unit<Pseudoscalar<T>>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn antiwedge(&self, rhs: &Unit<Pseudoscalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(rhs.as_inner().ps() * self.as_inner().s())
}
}
#[doc = "Left contraction of [`Circle`] into [`Circle`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<Circle<T>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.w() * self.w())
+ rhs.e12em() * self.e12em()
+ rhs.e1epem() * self.e1epem()
+ rhs.e2epem() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Circle<T>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.w() * self.as_inner().w())
+ rhs.e12em() * self.as_inner().e12em()
+ rhs.e1epem() * self.as_inner().e1epem()
+ rhs.e2epem() * self.as_inner().e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Circle<T>>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().w() * self.w())
+ rhs.as_inner().e12em() * self.e12em()
+ rhs.as_inner().e1epem() * self.e1epem()
+ rhs.as_inner().e2epem() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Circle<T>>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().w() * self.as_inner().w())
+ rhs.as_inner().e12em() * self.as_inner().e12em()
+ rhs.as_inner().e1epem() * self.as_inner().e1epem()
+ rhs.as_inner().e2epem() * self.as_inner().e2epem(),
)
}
}
#[doc = "Left contraction of [`Circle`] into [`Line`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<Line<T>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.d() * self.e2epem() + rhs.nx() * self.e12em() + rhs.ny() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Line<T>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.d() * self.as_inner().e2epem()
+ rhs.nx() * self.as_inner().e12em()
+ rhs.ny() * self.as_inner().e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Line<T>>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().d() * self.e2epem()
+ rhs.as_inner().nx() * self.e12em()
+ rhs.as_inner().ny() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Line<T>>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().d() * self.as_inner().e2epem()
+ rhs.as_inner().nx() * self.as_inner().e12em()
+ rhs.as_inner().ny() * self.as_inner().e1epem(),
)
}
}
#[doc = "Left contraction of [`Circle`] into [`Pseudoscalar`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<Pseudoscalar<T>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Pseudoscalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.ps() * self.e2epem()),
rhs.ps() * self.e1epem(),
-(rhs.ps() * self.e12em()),
-(rhs.ps() * self.w()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Pseudoscalar<T>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Pseudoscalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.ps() * self.as_inner().e2epem()),
rhs.ps() * self.as_inner().e1epem(),
-(rhs.ps() * self.as_inner().e12em()),
-(rhs.ps() * self.as_inner().w()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Pseudoscalar<T>>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Pseudoscalar<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().ps() * self.e2epem()),
rhs.as_inner().ps() * self.e1epem(),
-(rhs.as_inner().ps() * self.e12em()),
-(rhs.as_inner().ps() * self.w()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Pseudoscalar<T>>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Pseudoscalar<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().ps() * self.as_inner().e2epem()),
rhs.as_inner().ps() * self.as_inner().e1epem(),
-(rhs.as_inner().ps() * self.as_inner().e12em()),
-(rhs.as_inner().ps() * self.as_inner().w()),
)
}
}
#[doc = "Left contraction of [`FlatPoint`] into [`FlatPoint`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<FlatPoint<T>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.e1em() + rhs.e2em() * self.e2em() + rhs.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<FlatPoint<T>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<FlatPoint<T>>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<FlatPoint<T>>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Left contraction of [`FlatPoint`] into [`PointPair`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<PointPair<T>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.e1em() + rhs.e2em() * self.e2em() + rhs.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<PointPair<T>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<PointPair<T>>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<PointPair<T>>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Left contraction of [`Line`] into [`Circle`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<Circle<T>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e12em() * self.nx() + rhs.e1epem() * self.ny() + rhs.e2epem() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Circle<T>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e12em() * self.as_inner().nx()
+ rhs.e1epem() * self.as_inner().ny()
+ rhs.e2epem() * self.as_inner().d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Circle<T>>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e12em() * self.nx()
+ rhs.as_inner().e1epem() * self.ny()
+ rhs.as_inner().e2epem() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Circle<T>>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e12em() * self.as_inner().nx()
+ rhs.as_inner().e1epem() * self.as_inner().ny()
+ rhs.as_inner().e2epem() * self.as_inner().d(),
)
}
}
#[doc = "Left contraction of [`Line`] into [`Line`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<Line<T>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.d() * self.d() + rhs.nx() * self.nx() + rhs.ny() * self.ny())
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Line<T>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.d() * self.as_inner().d()
+ rhs.nx() * self.as_inner().nx()
+ rhs.ny() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Line<T>>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().d() * self.d()
+ rhs.as_inner().nx() * self.nx()
+ rhs.as_inner().ny() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Line<T>>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().d() * self.as_inner().d()
+ rhs.as_inner().nx() * self.as_inner().nx()
+ rhs.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[doc = "Left contraction of [`PointPair`] into [`Circle`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<Circle<T>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Circle<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.w() * self.e2ep()) + rhs.e12em() * self.e2em() + rhs.e1epem() * self.epem(),
-(rhs.e12em() * self.e1em()) + rhs.e2epem() * self.epem() + rhs.w() * self.e1ep(),
-(rhs.e1epem() * self.e1em()) + -(rhs.e2epem() * self.e2em()) + -(rhs.w() * self.m()),
-(rhs.e12em() * self.m())
+ -(rhs.e1epem() * self.e1ep())
+ -(rhs.e2epem() * self.e2ep()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Circle<T>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Circle<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.w() * self.as_inner().e2ep())
+ rhs.e12em() * self.as_inner().e2em()
+ rhs.e1epem() * self.as_inner().epem(),
-(rhs.e12em() * self.as_inner().e1em())
+ rhs.e2epem() * self.as_inner().epem()
+ rhs.w() * self.as_inner().e1ep(),
-(rhs.e1epem() * self.as_inner().e1em())
+ -(rhs.e2epem() * self.as_inner().e2em())
+ -(rhs.w() * self.as_inner().m()),
-(rhs.e12em() * self.as_inner().m())
+ -(rhs.e1epem() * self.as_inner().e1ep())
+ -(rhs.e2epem() * self.as_inner().e2ep()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Circle<T>>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Circle<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().w() * self.e2ep())
+ rhs.as_inner().e12em() * self.e2em()
+ rhs.as_inner().e1epem() * self.epem(),
-(rhs.as_inner().e12em() * self.e1em())
+ rhs.as_inner().e2epem() * self.epem()
+ rhs.as_inner().w() * self.e1ep(),
-(rhs.as_inner().e1epem() * self.e1em())
+ -(rhs.as_inner().e2epem() * self.e2em())
+ -(rhs.as_inner().w() * self.m()),
-(rhs.as_inner().e12em() * self.m())
+ -(rhs.as_inner().e1epem() * self.e1ep())
+ -(rhs.as_inner().e2epem() * self.e2ep()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Circle<T>>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Circle<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().w() * self.as_inner().e2ep())
+ rhs.as_inner().e12em() * self.as_inner().e2em()
+ rhs.as_inner().e1epem() * self.as_inner().epem(),
-(rhs.as_inner().e12em() * self.as_inner().e1em())
+ rhs.as_inner().e2epem() * self.as_inner().epem()
+ rhs.as_inner().w() * self.as_inner().e1ep(),
-(rhs.as_inner().e1epem() * self.as_inner().e1em())
+ -(rhs.as_inner().e2epem() * self.as_inner().e2em())
+ -(rhs.as_inner().w() * self.as_inner().m()),
-(rhs.as_inner().e12em() * self.as_inner().m())
+ -(rhs.as_inner().e1epem() * self.as_inner().e1ep())
+ -(rhs.as_inner().e2epem() * self.as_inner().e2ep()),
)
}
}
#[doc = "Left contraction of [`PointPair`] into [`FlatPoint`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<FlatPoint<T>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.e1em() + rhs.e2em() * self.e2em() + rhs.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<FlatPoint<T>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<FlatPoint<T>>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<FlatPoint<T>>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Left contraction of [`PointPair`] into [`Line`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<Line<T>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Line<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.nx() * self.e2em() + rhs.ny() * self.epem(),
-(rhs.nx() * self.e1em()) + rhs.d() * self.epem(),
-(rhs.d() * self.e2em()) + -(rhs.ny() * self.e1em()),
-(rhs.d() * self.e2ep()) + -(rhs.nx() * self.m()) + -(rhs.ny() * self.e1ep()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Line<T>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Line<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.nx() * self.as_inner().e2em() + rhs.ny() * self.as_inner().epem(),
-(rhs.nx() * self.as_inner().e1em()) + rhs.d() * self.as_inner().epem(),
-(rhs.d() * self.as_inner().e2em()) + -(rhs.ny() * self.as_inner().e1em()),
-(rhs.d() * self.as_inner().e2ep())
+ -(rhs.nx() * self.as_inner().m())
+ -(rhs.ny() * self.as_inner().e1ep()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Line<T>>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Line<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().nx() * self.e2em() + rhs.as_inner().ny() * self.epem(),
-(rhs.as_inner().nx() * self.e1em()) + rhs.as_inner().d() * self.epem(),
-(rhs.as_inner().d() * self.e2em()) + -(rhs.as_inner().ny() * self.e1em()),
-(rhs.as_inner().d() * self.e2ep())
+ -(rhs.as_inner().nx() * self.m())
+ -(rhs.as_inner().ny() * self.e1ep()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Line<T>>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Line<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().nx() * self.as_inner().e2em()
+ rhs.as_inner().ny() * self.as_inner().epem(),
-(rhs.as_inner().nx() * self.as_inner().e1em())
+ rhs.as_inner().d() * self.as_inner().epem(),
-(rhs.as_inner().d() * self.as_inner().e2em())
+ -(rhs.as_inner().ny() * self.as_inner().e1em()),
-(rhs.as_inner().d() * self.as_inner().e2ep())
+ -(rhs.as_inner().nx() * self.as_inner().m())
+ -(rhs.as_inner().ny() * self.as_inner().e1ep()),
)
}
}
#[doc = "Left contraction of [`PointPair`] into [`PointPair`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<PointPair<T>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1ep() * self.e1ep())
+ -(rhs.e2ep() * self.e2ep())
+ -(rhs.m() * self.m())
+ rhs.e1em() * self.e1em()
+ rhs.e2em() * self.e2em()
+ rhs.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<PointPair<T>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1ep() * self.as_inner().e1ep())
+ -(rhs.e2ep() * self.as_inner().e2ep())
+ -(rhs.m() * self.as_inner().m())
+ rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<PointPair<T>>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1ep() * self.e1ep())
+ -(rhs.as_inner().e2ep() * self.e2ep())
+ -(rhs.as_inner().m() * self.m())
+ rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<PointPair<T>>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1ep() * self.as_inner().e1ep())
+ -(rhs.as_inner().e2ep() * self.as_inner().e2ep())
+ -(rhs.as_inner().m() * self.as_inner().m())
+ rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Left contraction of [`PointPair`] into [`Pseudoscalar`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<Pseudoscalar<T>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn left_contract(&self, rhs: &Pseudoscalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.ps() * self.epem(),
-(rhs.ps() * self.e2em()),
rhs.ps() * self.e1em(),
-(rhs.ps() * self.e2ep()),
rhs.ps() * self.e1ep(),
-(rhs.ps() * self.m()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Pseudoscalar<T>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn left_contract(&self, rhs: &Pseudoscalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.ps() * self.as_inner().epem(),
-(rhs.ps() * self.as_inner().e2em()),
rhs.ps() * self.as_inner().e1em(),
-(rhs.ps() * self.as_inner().e2ep()),
rhs.ps() * self.as_inner().e1ep(),
-(rhs.ps() * self.as_inner().m()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Pseudoscalar<T>>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Pseudoscalar<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().ps() * self.epem(),
-(rhs.as_inner().ps() * self.e2em()),
rhs.as_inner().ps() * self.e1em(),
-(rhs.as_inner().ps() * self.e2ep()),
rhs.as_inner().ps() * self.e1ep(),
-(rhs.as_inner().ps() * self.m()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Pseudoscalar<T>>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Pseudoscalar<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().ps() * self.as_inner().epem(),
-(rhs.as_inner().ps() * self.as_inner().e2em()),
rhs.as_inner().ps() * self.as_inner().e1em(),
-(rhs.as_inner().ps() * self.as_inner().e2ep()),
rhs.as_inner().ps() * self.as_inner().e1ep(),
-(rhs.as_inner().ps() * self.as_inner().m()),
)
}
}
#[doc = "Left contraction of [`Pseudoscalar`] into [`Pseudoscalar`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<Pseudoscalar<T>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Pseudoscalar<T>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.ps() * self.ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Pseudoscalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Pseudoscalar<T>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.ps() * self.as_inner().ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Pseudoscalar<T>>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Pseudoscalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.as_inner().ps() * self.ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Pseudoscalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Pseudoscalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.as_inner().ps() * self.as_inner().ps()))
}
}
#[doc = "Left contraction of [`RoundPoint`] into [`Circle`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<Circle<T>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn left_contract(&self, rhs: &Circle<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.e12em() * self.em()) + rhs.w() * self.ep(),
-(rhs.e1epem() * self.em()) + -(rhs.w() * self.y()),
-(rhs.e2epem() * self.em()) + rhs.w() * self.x(),
-(rhs.e12em() * self.y()) + -(rhs.e1epem() * self.ep()),
-(rhs.e2epem() * self.ep()) + rhs.e12em() * self.x(),
rhs.e1epem() * self.x() + rhs.e2epem() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Circle<T>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn left_contract(&self, rhs: &Circle<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.e12em() * self.as_inner().em()) + rhs.w() * self.as_inner().ep(),
-(rhs.e1epem() * self.as_inner().em()) + -(rhs.w() * self.as_inner().y()),
-(rhs.e2epem() * self.as_inner().em()) + rhs.w() * self.as_inner().x(),
-(rhs.e12em() * self.as_inner().y()) + -(rhs.e1epem() * self.as_inner().ep()),
-(rhs.e2epem() * self.as_inner().ep()) + rhs.e12em() * self.as_inner().x(),
rhs.e1epem() * self.as_inner().x() + rhs.e2epem() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Circle<T>>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Circle<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().e12em() * self.em()) + rhs.as_inner().w() * self.ep(),
-(rhs.as_inner().e1epem() * self.em()) + -(rhs.as_inner().w() * self.y()),
-(rhs.as_inner().e2epem() * self.em()) + rhs.as_inner().w() * self.x(),
-(rhs.as_inner().e12em() * self.y()) + -(rhs.as_inner().e1epem() * self.ep()),
-(rhs.as_inner().e2epem() * self.ep()) + rhs.as_inner().e12em() * self.x(),
rhs.as_inner().e1epem() * self.x() + rhs.as_inner().e2epem() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Circle<T>>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Circle<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().e12em() * self.as_inner().em())
+ rhs.as_inner().w() * self.as_inner().ep(),
-(rhs.as_inner().e1epem() * self.as_inner().em())
+ -(rhs.as_inner().w() * self.as_inner().y()),
-(rhs.as_inner().e2epem() * self.as_inner().em())
+ rhs.as_inner().w() * self.as_inner().x(),
-(rhs.as_inner().e12em() * self.as_inner().y())
+ -(rhs.as_inner().e1epem() * self.as_inner().ep()),
-(rhs.as_inner().e2epem() * self.as_inner().ep())
+ rhs.as_inner().e12em() * self.as_inner().x(),
rhs.as_inner().e1epem() * self.as_inner().x()
+ rhs.as_inner().e2epem() * self.as_inner().y(),
)
}
}
#[doc = "Left contraction of [`RoundPoint`] into [`FlatPoint`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<FlatPoint<T>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &FlatPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.e1em() * self.em(),
rhs.e2em() * self.em(),
rhs.epem() * self.em(),
rhs.e1em() * self.x() + rhs.e2em() * self.y() + rhs.epem() * self.ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<FlatPoint<T>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &FlatPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.e1em() * self.as_inner().em(),
rhs.e2em() * self.as_inner().em(),
rhs.epem() * self.as_inner().em(),
rhs.e1em() * self.as_inner().x()
+ rhs.e2em() * self.as_inner().y()
+ rhs.epem() * self.as_inner().ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<FlatPoint<T>>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<FlatPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().e1em() * self.em(),
rhs.as_inner().e2em() * self.em(),
rhs.as_inner().epem() * self.em(),
rhs.as_inner().e1em() * self.x()
+ rhs.as_inner().e2em() * self.y()
+ rhs.as_inner().epem() * self.ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<FlatPoint<T>>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<FlatPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().em(),
rhs.as_inner().e2em() * self.as_inner().em(),
rhs.as_inner().epem() * self.as_inner().em(),
rhs.as_inner().e1em() * self.as_inner().x()
+ rhs.as_inner().e2em() * self.as_inner().y()
+ rhs.as_inner().epem() * self.as_inner().ep(),
)
}
}
#[doc = "Left contraction of [`RoundPoint`] into [`Line`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<Line<T>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn left_contract(&self, rhs: &Line<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.nx() * self.em()),
-(rhs.ny() * self.em()),
-(rhs.d() * self.em()),
-(rhs.nx() * self.y()) + -(rhs.ny() * self.ep()),
-(rhs.d() * self.ep()) + rhs.nx() * self.x(),
rhs.d() * self.y() + rhs.ny() * self.x(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Line<T>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn left_contract(&self, rhs: &Line<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.nx() * self.as_inner().em()),
-(rhs.ny() * self.as_inner().em()),
-(rhs.d() * self.as_inner().em()),
-(rhs.nx() * self.as_inner().y()) + -(rhs.ny() * self.as_inner().ep()),
-(rhs.d() * self.as_inner().ep()) + rhs.nx() * self.as_inner().x(),
rhs.d() * self.as_inner().y() + rhs.ny() * self.as_inner().x(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Line<T>>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Line<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().nx() * self.em()),
-(rhs.as_inner().ny() * self.em()),
-(rhs.as_inner().d() * self.em()),
-(rhs.as_inner().nx() * self.y()) + -(rhs.as_inner().ny() * self.ep()),
-(rhs.as_inner().d() * self.ep()) + rhs.as_inner().nx() * self.x(),
rhs.as_inner().d() * self.y() + rhs.as_inner().ny() * self.x(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Line<T>>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Line<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().nx() * self.as_inner().em()),
-(rhs.as_inner().ny() * self.as_inner().em()),
-(rhs.as_inner().d() * self.as_inner().em()),
-(rhs.as_inner().nx() * self.as_inner().y())
+ -(rhs.as_inner().ny() * self.as_inner().ep()),
-(rhs.as_inner().d() * self.as_inner().ep())
+ rhs.as_inner().nx() * self.as_inner().x(),
rhs.as_inner().d() * self.as_inner().y() + rhs.as_inner().ny() * self.as_inner().x(),
)
}
}
#[doc = "Left contraction of [`RoundPoint`] into [`PointPair`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<PointPair<T>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e1ep() * self.ep()) + -(rhs.m() * self.y()) + rhs.e1em() * self.em(),
-(rhs.e2ep() * self.ep()) + rhs.e2em() * self.em() + rhs.m() * self.x(),
rhs.e1ep() * self.x() + rhs.e2ep() * self.y() + rhs.epem() * self.em(),
rhs.e1em() * self.x() + rhs.e2em() * self.y() + rhs.epem() * self.ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<PointPair<T>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e1ep() * self.as_inner().ep())
+ -(rhs.m() * self.as_inner().y())
+ rhs.e1em() * self.as_inner().em(),
-(rhs.e2ep() * self.as_inner().ep())
+ rhs.e2em() * self.as_inner().em()
+ rhs.m() * self.as_inner().x(),
rhs.e1ep() * self.as_inner().x()
+ rhs.e2ep() * self.as_inner().y()
+ rhs.epem() * self.as_inner().em(),
rhs.e1em() * self.as_inner().x()
+ rhs.e2em() * self.as_inner().y()
+ rhs.epem() * self.as_inner().ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<PointPair<T>>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e1ep() * self.ep())
+ -(rhs.as_inner().m() * self.y())
+ rhs.as_inner().e1em() * self.em(),
-(rhs.as_inner().e2ep() * self.ep())
+ rhs.as_inner().e2em() * self.em()
+ rhs.as_inner().m() * self.x(),
rhs.as_inner().e1ep() * self.x()
+ rhs.as_inner().e2ep() * self.y()
+ rhs.as_inner().epem() * self.em(),
rhs.as_inner().e1em() * self.x()
+ rhs.as_inner().e2em() * self.y()
+ rhs.as_inner().epem() * self.ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<PointPair<T>>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e1ep() * self.as_inner().ep())
+ -(rhs.as_inner().m() * self.as_inner().y())
+ rhs.as_inner().e1em() * self.as_inner().em(),
-(rhs.as_inner().e2ep() * self.as_inner().ep())
+ rhs.as_inner().e2em() * self.as_inner().em()
+ rhs.as_inner().m() * self.as_inner().x(),
rhs.as_inner().e1ep() * self.as_inner().x()
+ rhs.as_inner().e2ep() * self.as_inner().y()
+ rhs.as_inner().epem() * self.as_inner().em(),
rhs.as_inner().e1em() * self.as_inner().x()
+ rhs.as_inner().e2em() * self.as_inner().y()
+ rhs.as_inner().epem() * self.as_inner().ep(),
)
}
}
#[doc = "Left contraction of [`RoundPoint`] into [`Pseudoscalar`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<Pseudoscalar<T>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn left_contract(&self, rhs: &Pseudoscalar<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.ps() * self.em(),
rhs.ps() * self.ep(),
-(rhs.ps() * self.y()),
rhs.ps() * self.x(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Pseudoscalar<T>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn left_contract(&self, rhs: &Pseudoscalar<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.ps() * self.as_inner().em(),
rhs.ps() * self.as_inner().ep(),
-(rhs.ps() * self.as_inner().y()),
rhs.ps() * self.as_inner().x(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Pseudoscalar<T>>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Pseudoscalar<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().ps() * self.em(),
rhs.as_inner().ps() * self.ep(),
-(rhs.as_inner().ps() * self.y()),
rhs.as_inner().ps() * self.x(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Pseudoscalar<T>>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Pseudoscalar<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().ps() * self.as_inner().em(),
rhs.as_inner().ps() * self.as_inner().ep(),
-(rhs.as_inner().ps() * self.as_inner().y()),
rhs.as_inner().ps() * self.as_inner().x(),
)
}
}
#[doc = "Left contraction of [`RoundPoint`] into [`RoundPoint`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<RoundPoint<T>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &RoundPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.em() * self.em())
+ rhs.ep() * self.ep()
+ rhs.x() * self.x()
+ rhs.y() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<RoundPoint<T>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &RoundPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.em() * self.as_inner().em())
+ rhs.ep() * self.as_inner().ep()
+ rhs.x() * self.as_inner().x()
+ rhs.y() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<RoundPoint<T>>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<RoundPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().em() * self.em())
+ rhs.as_inner().ep() * self.ep()
+ rhs.as_inner().x() * self.x()
+ rhs.as_inner().y() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<RoundPoint<T>>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<RoundPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().em() * self.as_inner().em())
+ rhs.as_inner().ep() * self.as_inner().ep()
+ rhs.as_inner().x() * self.as_inner().x()
+ rhs.as_inner().y() * self.as_inner().y(),
)
}
}
#[doc = "Left contraction of [`Scalar`] into [`Circle`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<Circle<T>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn left_contract(&self, rhs: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.w() * self.s(),
rhs.e12em() * self.s(),
rhs.e1epem() * self.s(),
rhs.e2epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Circle<T>> for Unit<Scalar<T>> {
type Output = Circle<T>;
#[inline]
fn left_contract(&self, rhs: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.w() * self.as_inner().s(),
rhs.e12em() * self.as_inner().s(),
rhs.e1epem() * self.as_inner().s(),
rhs.e2epem() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Circle<T>>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().w() * self.s(),
rhs.as_inner().e12em() * self.s(),
rhs.as_inner().e1epem() * self.s(),
rhs.as_inner().e2epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Circle<T>>> for Unit<Scalar<T>> {
type Output = Circle<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().w() * self.as_inner().s(),
rhs.as_inner().e12em() * self.as_inner().s(),
rhs.as_inner().e1epem() * self.as_inner().s(),
rhs.as_inner().e2epem() * self.as_inner().s(),
)
}
}
#[doc = "Left contraction of [`Scalar`] into [`FlatPoint`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<FlatPoint<T>> for Scalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn left_contract(&self, rhs: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.e1em() * self.s(),
rhs.e2em() * self.s(),
rhs.epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<FlatPoint<T>> for Unit<Scalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn left_contract(&self, rhs: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.e1em() * self.as_inner().s(),
rhs.e2em() * self.as_inner().s(),
rhs.epem() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<FlatPoint<T>>> for Scalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.as_inner().e1em() * self.s(),
rhs.as_inner().e2em() * self.s(),
rhs.as_inner().epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<FlatPoint<T>>> for Unit<Scalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().s(),
rhs.as_inner().e2em() * self.as_inner().s(),
rhs.as_inner().epem() * self.as_inner().s(),
)
}
}
#[doc = "Left contraction of [`Scalar`] into [`Line`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<Line<T>> for Scalar<T> {
type Output = Line<T>;
#[inline]
fn left_contract(&self, rhs: &Line<T>) -> Line<T> {
Line::new_unchecked(rhs.nx() * self.s(), rhs.ny() * self.s(), rhs.d() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Line<T>> for Unit<Scalar<T>> {
type Output = Line<T>;
#[inline]
fn left_contract(&self, rhs: &Line<T>) -> Line<T> {
Line::new_unchecked(
rhs.nx() * self.as_inner().s(),
rhs.ny() * self.as_inner().s(),
rhs.d() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Line<T>>> for Scalar<T> {
type Output = Line<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
rhs.as_inner().nx() * self.s(),
rhs.as_inner().ny() * self.s(),
rhs.as_inner().d() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Line<T>>> for Unit<Scalar<T>> {
type Output = Line<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
rhs.as_inner().nx() * self.as_inner().s(),
rhs.as_inner().ny() * self.as_inner().s(),
rhs.as_inner().d() * self.as_inner().s(),
)
}
}
#[doc = "Left contraction of [`Scalar`] into [`PointPair`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<PointPair<T>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn left_contract(&self, rhs: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.m() * self.s(),
rhs.e1ep() * self.s(),
rhs.e2ep() * self.s(),
rhs.e1em() * self.s(),
rhs.e2em() * self.s(),
rhs.epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<PointPair<T>> for Unit<Scalar<T>> {
type Output = PointPair<T>;
#[inline]
fn left_contract(&self, rhs: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.m() * self.as_inner().s(),
rhs.e1ep() * self.as_inner().s(),
rhs.e2ep() * self.as_inner().s(),
rhs.e1em() * self.as_inner().s(),
rhs.e2em() * self.as_inner().s(),
rhs.epem() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<PointPair<T>>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().m() * self.s(),
rhs.as_inner().e1ep() * self.s(),
rhs.as_inner().e2ep() * self.s(),
rhs.as_inner().e1em() * self.s(),
rhs.as_inner().e2em() * self.s(),
rhs.as_inner().epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<PointPair<T>>> for Unit<Scalar<T>> {
type Output = PointPair<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().m() * self.as_inner().s(),
rhs.as_inner().e1ep() * self.as_inner().s(),
rhs.as_inner().e2ep() * self.as_inner().s(),
rhs.as_inner().e1em() * self.as_inner().s(),
rhs.as_inner().e2em() * self.as_inner().s(),
rhs.as_inner().epem() * self.as_inner().s(),
)
}
}
#[doc = "Left contraction of [`Scalar`] into [`Pseudoscalar`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<Pseudoscalar<T>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn left_contract(&self, rhs: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.ps() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Pseudoscalar<T>> for Unit<Scalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn left_contract(&self, rhs: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.ps() * self.as_inner().s())
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Pseudoscalar<T>>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.as_inner().ps() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Pseudoscalar<T>>> for Unit<Scalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.as_inner().ps() * self.as_inner().s())
}
}
#[doc = "Left contraction of [`Scalar`] into [`RoundPoint`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<RoundPoint<T>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.x() * self.s(),
rhs.y() * self.s(),
rhs.ep() * self.s(),
rhs.em() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<RoundPoint<T>> for Unit<Scalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.x() * self.as_inner().s(),
rhs.y() * self.as_inner().s(),
rhs.ep() * self.as_inner().s(),
rhs.em() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<RoundPoint<T>>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().x() * self.s(),
rhs.as_inner().y() * self.s(),
rhs.as_inner().ep() * self.s(),
rhs.as_inner().em() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<RoundPoint<T>>> for Unit<Scalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().x() * self.as_inner().s(),
rhs.as_inner().y() * self.as_inner().s(),
rhs.as_inner().ep() * self.as_inner().s(),
rhs.as_inner().em() * self.as_inner().s(),
)
}
}
#[doc = "Left contraction of [`Scalar`] into [`Scalar`].\n\nThe left contraction `a _| b` projects `a` onto `b`, returning the\ncomponent of `b` orthogonal to `a`. The result grade is grade(b) - grade(a)\n(or zero if grade(a) > grade(b))."]
impl<T: Float> LeftContract<Scalar<T>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.s() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Scalar<T>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.s() * self.as_inner().s())
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Scalar<T>>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(rhs.as_inner().s() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> LeftContract<Unit<Scalar<T>>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn left_contract(&self, rhs: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(rhs.as_inner().s() * self.as_inner().s())
}
}
#[doc = "Right contraction of [`Circle`] by [`Circle`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<Circle<T>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.w() * self.w())
+ rhs.e12em() * self.e12em()
+ rhs.e1epem() * self.e1epem()
+ rhs.e2epem() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Circle<T>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.w() * self.as_inner().w())
+ rhs.e12em() * self.as_inner().e12em()
+ rhs.e1epem() * self.as_inner().e1epem()
+ rhs.e2epem() * self.as_inner().e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Circle<T>>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().w() * self.w())
+ rhs.as_inner().e12em() * self.e12em()
+ rhs.as_inner().e1epem() * self.e1epem()
+ rhs.as_inner().e2epem() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Circle<T>>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().w() * self.as_inner().w())
+ rhs.as_inner().e12em() * self.as_inner().e12em()
+ rhs.as_inner().e1epem() * self.as_inner().e1epem()
+ rhs.as_inner().e2epem() * self.as_inner().e2epem(),
)
}
}
#[doc = "Right contraction of [`Circle`] by [`Line`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<Line<T>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.d() * self.e2epem() + rhs.nx() * self.e12em() + rhs.ny() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Line<T>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.d() * self.as_inner().e2epem()
+ rhs.nx() * self.as_inner().e12em()
+ rhs.ny() * self.as_inner().e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Line<T>>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().d() * self.e2epem()
+ rhs.as_inner().nx() * self.e12em()
+ rhs.as_inner().ny() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Line<T>>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().d() * self.as_inner().e2epem()
+ rhs.as_inner().nx() * self.as_inner().e12em()
+ rhs.as_inner().ny() * self.as_inner().e1epem(),
)
}
}
#[doc = "Right contraction of [`Circle`] by [`PointPair`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<PointPair<T>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e2ep() * self.w()) + rhs.e2em() * self.e12em() + rhs.epem() * self.e1epem(),
-(rhs.e1em() * self.e12em()) + rhs.e1ep() * self.w() + rhs.epem() * self.e2epem(),
-(rhs.e1em() * self.e1epem()) + -(rhs.e2em() * self.e2epem()) + -(rhs.m() * self.w()),
-(rhs.e1ep() * self.e1epem())
+ -(rhs.e2ep() * self.e2epem())
+ -(rhs.m() * self.e12em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<PointPair<T>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e2ep() * self.as_inner().w())
+ rhs.e2em() * self.as_inner().e12em()
+ rhs.epem() * self.as_inner().e1epem(),
-(rhs.e1em() * self.as_inner().e12em())
+ rhs.e1ep() * self.as_inner().w()
+ rhs.epem() * self.as_inner().e2epem(),
-(rhs.e1em() * self.as_inner().e1epem())
+ -(rhs.e2em() * self.as_inner().e2epem())
+ -(rhs.m() * self.as_inner().w()),
-(rhs.e1ep() * self.as_inner().e1epem())
+ -(rhs.e2ep() * self.as_inner().e2epem())
+ -(rhs.m() * self.as_inner().e12em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<PointPair<T>>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e2ep() * self.w())
+ rhs.as_inner().e2em() * self.e12em()
+ rhs.as_inner().epem() * self.e1epem(),
-(rhs.as_inner().e1em() * self.e12em())
+ rhs.as_inner().e1ep() * self.w()
+ rhs.as_inner().epem() * self.e2epem(),
-(rhs.as_inner().e1em() * self.e1epem())
+ -(rhs.as_inner().e2em() * self.e2epem())
+ -(rhs.as_inner().m() * self.w()),
-(rhs.as_inner().e1ep() * self.e1epem())
+ -(rhs.as_inner().e2ep() * self.e2epem())
+ -(rhs.as_inner().m() * self.e12em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<PointPair<T>>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e2ep() * self.as_inner().w())
+ rhs.as_inner().e2em() * self.as_inner().e12em()
+ rhs.as_inner().epem() * self.as_inner().e1epem(),
-(rhs.as_inner().e1em() * self.as_inner().e12em())
+ rhs.as_inner().e1ep() * self.as_inner().w()
+ rhs.as_inner().epem() * self.as_inner().e2epem(),
-(rhs.as_inner().e1em() * self.as_inner().e1epem())
+ -(rhs.as_inner().e2em() * self.as_inner().e2epem())
+ -(rhs.as_inner().m() * self.as_inner().w()),
-(rhs.as_inner().e1ep() * self.as_inner().e1epem())
+ -(rhs.as_inner().e2ep() * self.as_inner().e2epem())
+ -(rhs.as_inner().m() * self.as_inner().e12em()),
)
}
}
#[doc = "Right contraction of [`Circle`] by [`RoundPoint`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<RoundPoint<T>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn right_contract(&self, rhs: &RoundPoint<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.em() * self.e12em()) + rhs.ep() * self.w(),
-(rhs.em() * self.e1epem()) + -(rhs.y() * self.w()),
-(rhs.em() * self.e2epem()) + rhs.x() * self.w(),
-(rhs.ep() * self.e1epem()) + -(rhs.y() * self.e12em()),
-(rhs.ep() * self.e2epem()) + rhs.x() * self.e12em(),
rhs.x() * self.e1epem() + rhs.y() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<RoundPoint<T>> for Unit<Circle<T>> {
type Output = PointPair<T>;
#[inline]
fn right_contract(&self, rhs: &RoundPoint<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.em() * self.as_inner().e12em()) + rhs.ep() * self.as_inner().w(),
-(rhs.em() * self.as_inner().e1epem()) + -(rhs.y() * self.as_inner().w()),
-(rhs.em() * self.as_inner().e2epem()) + rhs.x() * self.as_inner().w(),
-(rhs.ep() * self.as_inner().e1epem()) + -(rhs.y() * self.as_inner().e12em()),
-(rhs.ep() * self.as_inner().e2epem()) + rhs.x() * self.as_inner().e12em(),
rhs.x() * self.as_inner().e1epem() + rhs.y() * self.as_inner().e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<RoundPoint<T>>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<RoundPoint<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().em() * self.e12em()) + rhs.as_inner().ep() * self.w(),
-(rhs.as_inner().em() * self.e1epem()) + -(rhs.as_inner().y() * self.w()),
-(rhs.as_inner().em() * self.e2epem()) + rhs.as_inner().x() * self.w(),
-(rhs.as_inner().ep() * self.e1epem()) + -(rhs.as_inner().y() * self.e12em()),
-(rhs.as_inner().ep() * self.e2epem()) + rhs.as_inner().x() * self.e12em(),
rhs.as_inner().x() * self.e1epem() + rhs.as_inner().y() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<RoundPoint<T>>> for Unit<Circle<T>> {
type Output = PointPair<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<RoundPoint<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().em() * self.as_inner().e12em())
+ rhs.as_inner().ep() * self.as_inner().w(),
-(rhs.as_inner().em() * self.as_inner().e1epem())
+ -(rhs.as_inner().y() * self.as_inner().w()),
-(rhs.as_inner().em() * self.as_inner().e2epem())
+ rhs.as_inner().x() * self.as_inner().w(),
-(rhs.as_inner().ep() * self.as_inner().e1epem())
+ -(rhs.as_inner().y() * self.as_inner().e12em()),
-(rhs.as_inner().ep() * self.as_inner().e2epem())
+ rhs.as_inner().x() * self.as_inner().e12em(),
rhs.as_inner().x() * self.as_inner().e1epem()
+ rhs.as_inner().y() * self.as_inner().e2epem(),
)
}
}
#[doc = "Right contraction of [`Circle`] by [`Scalar`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<Scalar<T>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn right_contract(&self, rhs: &Scalar<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.s() * self.w(),
rhs.s() * self.e12em(),
rhs.s() * self.e1epem(),
rhs.s() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Scalar<T>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn right_contract(&self, rhs: &Scalar<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.s() * self.as_inner().w(),
rhs.s() * self.as_inner().e12em(),
rhs.s() * self.as_inner().e1epem(),
rhs.s() * self.as_inner().e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Scalar<T>>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Scalar<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().s() * self.w(),
rhs.as_inner().s() * self.e12em(),
rhs.as_inner().s() * self.e1epem(),
rhs.as_inner().s() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Scalar<T>>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Scalar<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().s() * self.as_inner().w(),
rhs.as_inner().s() * self.as_inner().e12em(),
rhs.as_inner().s() * self.as_inner().e1epem(),
rhs.as_inner().s() * self.as_inner().e2epem(),
)
}
}
#[doc = "Right contraction of [`FlatPoint`] by [`FlatPoint`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<FlatPoint<T>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.e1em() + rhs.e2em() * self.e2em() + rhs.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<FlatPoint<T>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<FlatPoint<T>>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<FlatPoint<T>>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Right contraction of [`FlatPoint`] by [`PointPair`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<PointPair<T>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.e1em() + rhs.e2em() * self.e2em() + rhs.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<PointPair<T>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<PointPair<T>>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<PointPair<T>>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Right contraction of [`FlatPoint`] by [`RoundPoint`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<RoundPoint<T>> for FlatPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.em() * self.e1em()),
-(rhs.em() * self.e2em()),
-(rhs.em() * self.epem()),
-(rhs.ep() * self.epem()) + -(rhs.x() * self.e1em()) + -(rhs.y() * self.e2em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<RoundPoint<T>> for Unit<FlatPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.em() * self.as_inner().e1em()),
-(rhs.em() * self.as_inner().e2em()),
-(rhs.em() * self.as_inner().epem()),
-(rhs.ep() * self.as_inner().epem())
+ -(rhs.x() * self.as_inner().e1em())
+ -(rhs.y() * self.as_inner().e2em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<RoundPoint<T>>> for FlatPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().em() * self.e1em()),
-(rhs.as_inner().em() * self.e2em()),
-(rhs.as_inner().em() * self.epem()),
-(rhs.as_inner().ep() * self.epem())
+ -(rhs.as_inner().x() * self.e1em())
+ -(rhs.as_inner().y() * self.e2em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<RoundPoint<T>>> for Unit<FlatPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().em() * self.as_inner().e1em()),
-(rhs.as_inner().em() * self.as_inner().e2em()),
-(rhs.as_inner().em() * self.as_inner().epem()),
-(rhs.as_inner().ep() * self.as_inner().epem())
+ -(rhs.as_inner().x() * self.as_inner().e1em())
+ -(rhs.as_inner().y() * self.as_inner().e2em()),
)
}
}
#[doc = "Right contraction of [`FlatPoint`] by [`Scalar`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<Scalar<T>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Scalar<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.s() * self.e1em(),
rhs.s() * self.e2em(),
rhs.s() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Scalar<T>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Scalar<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.s() * self.as_inner().e1em(),
rhs.s() * self.as_inner().e2em(),
rhs.s() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Scalar<T>>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Scalar<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.as_inner().s() * self.e1em(),
rhs.as_inner().s() * self.e2em(),
rhs.as_inner().s() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Scalar<T>>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Scalar<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.as_inner().s() * self.as_inner().e1em(),
rhs.as_inner().s() * self.as_inner().e2em(),
rhs.as_inner().s() * self.as_inner().epem(),
)
}
}
#[doc = "Right contraction of [`Line`] by [`Circle`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<Circle<T>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e12em() * self.nx() + rhs.e1epem() * self.ny() + rhs.e2epem() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Circle<T>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e12em() * self.as_inner().nx()
+ rhs.e1epem() * self.as_inner().ny()
+ rhs.e2epem() * self.as_inner().d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Circle<T>>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e12em() * self.nx()
+ rhs.as_inner().e1epem() * self.ny()
+ rhs.as_inner().e2epem() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Circle<T>>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e12em() * self.as_inner().nx()
+ rhs.as_inner().e1epem() * self.as_inner().ny()
+ rhs.as_inner().e2epem() * self.as_inner().d(),
)
}
}
#[doc = "Right contraction of [`Line`] by [`Line`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<Line<T>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.d() * self.d() + rhs.nx() * self.nx() + rhs.ny() * self.ny())
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Line<T>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.d() * self.as_inner().d()
+ rhs.nx() * self.as_inner().nx()
+ rhs.ny() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Line<T>>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().d() * self.d()
+ rhs.as_inner().nx() * self.nx()
+ rhs.as_inner().ny() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Line<T>>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().d() * self.as_inner().d()
+ rhs.as_inner().nx() * self.as_inner().nx()
+ rhs.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[doc = "Right contraction of [`Line`] by [`PointPair`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<PointPair<T>> for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.e2em() * self.nx() + rhs.epem() * self.ny(),
-(rhs.e1em() * self.nx()) + rhs.epem() * self.d(),
-(rhs.e1em() * self.ny()) + -(rhs.e2em() * self.d()),
-(rhs.e1ep() * self.ny()) + -(rhs.e2ep() * self.d()) + -(rhs.m() * self.nx()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<PointPair<T>> for Unit<Line<T>> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.e2em() * self.as_inner().nx() + rhs.epem() * self.as_inner().ny(),
-(rhs.e1em() * self.as_inner().nx()) + rhs.epem() * self.as_inner().d(),
-(rhs.e1em() * self.as_inner().ny()) + -(rhs.e2em() * self.as_inner().d()),
-(rhs.e1ep() * self.as_inner().ny())
+ -(rhs.e2ep() * self.as_inner().d())
+ -(rhs.m() * self.as_inner().nx()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<PointPair<T>>> for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().e2em() * self.nx() + rhs.as_inner().epem() * self.ny(),
-(rhs.as_inner().e1em() * self.nx()) + rhs.as_inner().epem() * self.d(),
-(rhs.as_inner().e1em() * self.ny()) + -(rhs.as_inner().e2em() * self.d()),
-(rhs.as_inner().e1ep() * self.ny())
+ -(rhs.as_inner().e2ep() * self.d())
+ -(rhs.as_inner().m() * self.nx()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<PointPair<T>>> for Unit<Line<T>> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().e2em() * self.as_inner().nx()
+ rhs.as_inner().epem() * self.as_inner().ny(),
-(rhs.as_inner().e1em() * self.as_inner().nx())
+ rhs.as_inner().epem() * self.as_inner().d(),
-(rhs.as_inner().e1em() * self.as_inner().ny())
+ -(rhs.as_inner().e2em() * self.as_inner().d()),
-(rhs.as_inner().e1ep() * self.as_inner().ny())
+ -(rhs.as_inner().e2ep() * self.as_inner().d())
+ -(rhs.as_inner().m() * self.as_inner().nx()),
)
}
}
#[doc = "Right contraction of [`Line`] by [`RoundPoint`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<RoundPoint<T>> for Line<T> {
type Output = PointPair<T>;
#[inline]
fn right_contract(&self, rhs: &RoundPoint<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.em() * self.nx()),
-(rhs.em() * self.ny()),
-(rhs.em() * self.d()),
-(rhs.ep() * self.ny()) + -(rhs.y() * self.nx()),
-(rhs.ep() * self.d()) + rhs.x() * self.nx(),
rhs.x() * self.ny() + rhs.y() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<RoundPoint<T>> for Unit<Line<T>> {
type Output = PointPair<T>;
#[inline]
fn right_contract(&self, rhs: &RoundPoint<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.em() * self.as_inner().nx()),
-(rhs.em() * self.as_inner().ny()),
-(rhs.em() * self.as_inner().d()),
-(rhs.ep() * self.as_inner().ny()) + -(rhs.y() * self.as_inner().nx()),
-(rhs.ep() * self.as_inner().d()) + rhs.x() * self.as_inner().nx(),
rhs.x() * self.as_inner().ny() + rhs.y() * self.as_inner().d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<RoundPoint<T>>> for Line<T> {
type Output = PointPair<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<RoundPoint<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().em() * self.nx()),
-(rhs.as_inner().em() * self.ny()),
-(rhs.as_inner().em() * self.d()),
-(rhs.as_inner().ep() * self.ny()) + -(rhs.as_inner().y() * self.nx()),
-(rhs.as_inner().ep() * self.d()) + rhs.as_inner().x() * self.nx(),
rhs.as_inner().x() * self.ny() + rhs.as_inner().y() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<RoundPoint<T>>> for Unit<Line<T>> {
type Output = PointPair<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<RoundPoint<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().em() * self.as_inner().nx()),
-(rhs.as_inner().em() * self.as_inner().ny()),
-(rhs.as_inner().em() * self.as_inner().d()),
-(rhs.as_inner().ep() * self.as_inner().ny())
+ -(rhs.as_inner().y() * self.as_inner().nx()),
-(rhs.as_inner().ep() * self.as_inner().d())
+ rhs.as_inner().x() * self.as_inner().nx(),
rhs.as_inner().x() * self.as_inner().ny() + rhs.as_inner().y() * self.as_inner().d(),
)
}
}
#[doc = "Right contraction of [`Line`] by [`Scalar`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<Scalar<T>> for Line<T> {
type Output = Line<T>;
#[inline]
fn right_contract(&self, rhs: &Scalar<T>) -> Line<T> {
Line::new_unchecked(rhs.s() * self.nx(), rhs.s() * self.ny(), rhs.s() * self.d())
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Scalar<T>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn right_contract(&self, rhs: &Scalar<T>) -> Line<T> {
Line::new_unchecked(
rhs.s() * self.as_inner().nx(),
rhs.s() * self.as_inner().ny(),
rhs.s() * self.as_inner().d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Scalar<T>>> for Line<T> {
type Output = Line<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Scalar<T>>) -> Line<T> {
Line::new_unchecked(
rhs.as_inner().s() * self.nx(),
rhs.as_inner().s() * self.ny(),
rhs.as_inner().s() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Scalar<T>>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Scalar<T>>) -> Line<T> {
Line::new_unchecked(
rhs.as_inner().s() * self.as_inner().nx(),
rhs.as_inner().s() * self.as_inner().ny(),
rhs.as_inner().s() * self.as_inner().d(),
)
}
}
#[doc = "Right contraction of [`PointPair`] by [`FlatPoint`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<FlatPoint<T>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.e1em() + rhs.e2em() * self.e2em() + rhs.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<FlatPoint<T>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<FlatPoint<T>>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<FlatPoint<T>>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Right contraction of [`PointPair`] by [`PointPair`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<PointPair<T>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1ep() * self.e1ep())
+ -(rhs.e2ep() * self.e2ep())
+ -(rhs.m() * self.m())
+ rhs.e1em() * self.e1em()
+ rhs.e2em() * self.e2em()
+ rhs.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<PointPair<T>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1ep() * self.as_inner().e1ep())
+ -(rhs.e2ep() * self.as_inner().e2ep())
+ -(rhs.m() * self.as_inner().m())
+ rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<PointPair<T>>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1ep() * self.e1ep())
+ -(rhs.as_inner().e2ep() * self.e2ep())
+ -(rhs.as_inner().m() * self.m())
+ rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<PointPair<T>>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1ep() * self.as_inner().e1ep())
+ -(rhs.as_inner().e2ep() * self.as_inner().e2ep())
+ -(rhs.as_inner().m() * self.as_inner().m())
+ rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Right contraction of [`PointPair`] by [`RoundPoint`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<RoundPoint<T>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.em() * self.e1em()) + rhs.ep() * self.e1ep() + rhs.y() * self.m(),
-(rhs.em() * self.e2em()) + -(rhs.x() * self.m()) + rhs.ep() * self.e2ep(),
-(rhs.em() * self.epem()) + -(rhs.x() * self.e1ep()) + -(rhs.y() * self.e2ep()),
-(rhs.ep() * self.epem()) + -(rhs.x() * self.e1em()) + -(rhs.y() * self.e2em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<RoundPoint<T>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.em() * self.as_inner().e1em())
+ rhs.ep() * self.as_inner().e1ep()
+ rhs.y() * self.as_inner().m(),
-(rhs.em() * self.as_inner().e2em())
+ -(rhs.x() * self.as_inner().m())
+ rhs.ep() * self.as_inner().e2ep(),
-(rhs.em() * self.as_inner().epem())
+ -(rhs.x() * self.as_inner().e1ep())
+ -(rhs.y() * self.as_inner().e2ep()),
-(rhs.ep() * self.as_inner().epem())
+ -(rhs.x() * self.as_inner().e1em())
+ -(rhs.y() * self.as_inner().e2em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<RoundPoint<T>>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().em() * self.e1em())
+ rhs.as_inner().ep() * self.e1ep()
+ rhs.as_inner().y() * self.m(),
-(rhs.as_inner().em() * self.e2em())
+ -(rhs.as_inner().x() * self.m())
+ rhs.as_inner().ep() * self.e2ep(),
-(rhs.as_inner().em() * self.epem())
+ -(rhs.as_inner().x() * self.e1ep())
+ -(rhs.as_inner().y() * self.e2ep()),
-(rhs.as_inner().ep() * self.epem())
+ -(rhs.as_inner().x() * self.e1em())
+ -(rhs.as_inner().y() * self.e2em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<RoundPoint<T>>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().em() * self.as_inner().e1em())
+ rhs.as_inner().ep() * self.as_inner().e1ep()
+ rhs.as_inner().y() * self.as_inner().m(),
-(rhs.as_inner().em() * self.as_inner().e2em())
+ -(rhs.as_inner().x() * self.as_inner().m())
+ rhs.as_inner().ep() * self.as_inner().e2ep(),
-(rhs.as_inner().em() * self.as_inner().epem())
+ -(rhs.as_inner().x() * self.as_inner().e1ep())
+ -(rhs.as_inner().y() * self.as_inner().e2ep()),
-(rhs.as_inner().ep() * self.as_inner().epem())
+ -(rhs.as_inner().x() * self.as_inner().e1em())
+ -(rhs.as_inner().y() * self.as_inner().e2em()),
)
}
}
#[doc = "Right contraction of [`PointPair`] by [`Scalar`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<Scalar<T>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn right_contract(&self, rhs: &Scalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.s() * self.m(),
rhs.s() * self.e1ep(),
rhs.s() * self.e2ep(),
rhs.s() * self.e1em(),
rhs.s() * self.e2em(),
rhs.s() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Scalar<T>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn right_contract(&self, rhs: &Scalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.s() * self.as_inner().m(),
rhs.s() * self.as_inner().e1ep(),
rhs.s() * self.as_inner().e2ep(),
rhs.s() * self.as_inner().e1em(),
rhs.s() * self.as_inner().e2em(),
rhs.s() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Scalar<T>>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Scalar<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().s() * self.m(),
rhs.as_inner().s() * self.e1ep(),
rhs.as_inner().s() * self.e2ep(),
rhs.as_inner().s() * self.e1em(),
rhs.as_inner().s() * self.e2em(),
rhs.as_inner().s() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Scalar<T>>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Scalar<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().s() * self.as_inner().m(),
rhs.as_inner().s() * self.as_inner().e1ep(),
rhs.as_inner().s() * self.as_inner().e2ep(),
rhs.as_inner().s() * self.as_inner().e1em(),
rhs.as_inner().s() * self.as_inner().e2em(),
rhs.as_inner().s() * self.as_inner().epem(),
)
}
}
#[doc = "Right contraction of [`Pseudoscalar`] by [`Circle`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<Circle<T>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Circle<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.e2epem() * self.ps(),
-(rhs.e1epem() * self.ps()),
rhs.e12em() * self.ps(),
rhs.w() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Circle<T>> for Unit<Pseudoscalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Circle<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.e2epem() * self.as_inner().ps(),
-(rhs.e1epem() * self.as_inner().ps()),
rhs.e12em() * self.as_inner().ps(),
rhs.w() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Circle<T>>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Circle<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().e2epem() * self.ps(),
-(rhs.as_inner().e1epem() * self.ps()),
rhs.as_inner().e12em() * self.ps(),
rhs.as_inner().w() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Circle<T>>> for Unit<Pseudoscalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Circle<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().e2epem() * self.as_inner().ps(),
-(rhs.as_inner().e1epem() * self.as_inner().ps()),
rhs.as_inner().e12em() * self.as_inner().ps(),
rhs.as_inner().w() * self.as_inner().ps(),
)
}
}
#[doc = "Right contraction of [`Pseudoscalar`] by [`PointPair`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<PointPair<T>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn right_contract(&self, rhs: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.epem() * self.ps(),
-(rhs.e2em() * self.ps()),
rhs.e1em() * self.ps(),
-(rhs.e2ep() * self.ps()),
rhs.e1ep() * self.ps(),
-(rhs.m() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<PointPair<T>> for Unit<Pseudoscalar<T>> {
type Output = PointPair<T>;
#[inline]
fn right_contract(&self, rhs: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.epem() * self.as_inner().ps(),
-(rhs.e2em() * self.as_inner().ps()),
rhs.e1em() * self.as_inner().ps(),
-(rhs.e2ep() * self.as_inner().ps()),
rhs.e1ep() * self.as_inner().ps(),
-(rhs.m() * self.as_inner().ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<PointPair<T>>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().epem() * self.ps(),
-(rhs.as_inner().e2em() * self.ps()),
rhs.as_inner().e1em() * self.ps(),
-(rhs.as_inner().e2ep() * self.ps()),
rhs.as_inner().e1ep() * self.ps(),
-(rhs.as_inner().m() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<PointPair<T>>> for Unit<Pseudoscalar<T>> {
type Output = PointPair<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().epem() * self.as_inner().ps(),
-(rhs.as_inner().e2em() * self.as_inner().ps()),
rhs.as_inner().e1em() * self.as_inner().ps(),
-(rhs.as_inner().e2ep() * self.as_inner().ps()),
rhs.as_inner().e1ep() * self.as_inner().ps(),
-(rhs.as_inner().m() * self.as_inner().ps()),
)
}
}
#[doc = "Right contraction of [`Pseudoscalar`] by [`Pseudoscalar`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<Pseudoscalar<T>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Pseudoscalar<T>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.ps() * self.ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Pseudoscalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Pseudoscalar<T>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.ps() * self.as_inner().ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Pseudoscalar<T>>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Pseudoscalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.as_inner().ps() * self.ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Pseudoscalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Pseudoscalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.as_inner().ps() * self.as_inner().ps()))
}
}
#[doc = "Right contraction of [`Pseudoscalar`] by [`RoundPoint`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<RoundPoint<T>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn right_contract(&self, rhs: &RoundPoint<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.em() * self.ps()),
-(rhs.ep() * self.ps()),
rhs.y() * self.ps(),
-(rhs.x() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<RoundPoint<T>> for Unit<Pseudoscalar<T>> {
type Output = Circle<T>;
#[inline]
fn right_contract(&self, rhs: &RoundPoint<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.em() * self.as_inner().ps()),
-(rhs.ep() * self.as_inner().ps()),
rhs.y() * self.as_inner().ps(),
-(rhs.x() * self.as_inner().ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<RoundPoint<T>>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<RoundPoint<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().em() * self.ps()),
-(rhs.as_inner().ep() * self.ps()),
rhs.as_inner().y() * self.ps(),
-(rhs.as_inner().x() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<RoundPoint<T>>> for Unit<Pseudoscalar<T>> {
type Output = Circle<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<RoundPoint<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().em() * self.as_inner().ps()),
-(rhs.as_inner().ep() * self.as_inner().ps()),
rhs.as_inner().y() * self.as_inner().ps(),
-(rhs.as_inner().x() * self.as_inner().ps()),
)
}
}
#[doc = "Right contraction of [`Pseudoscalar`] by [`Scalar`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<Scalar<T>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn right_contract(&self, rhs: &Scalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.s() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Scalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn right_contract(&self, rhs: &Scalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.s() * self.as_inner().ps())
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Scalar<T>>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Scalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.as_inner().s() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Scalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Scalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.as_inner().s() * self.as_inner().ps())
}
}
#[doc = "Right contraction of [`RoundPoint`] by [`RoundPoint`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<RoundPoint<T>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &RoundPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.em() * self.em())
+ rhs.ep() * self.ep()
+ rhs.x() * self.x()
+ rhs.y() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<RoundPoint<T>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &RoundPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.em() * self.as_inner().em())
+ rhs.ep() * self.as_inner().ep()
+ rhs.x() * self.as_inner().x()
+ rhs.y() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<RoundPoint<T>>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<RoundPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().em() * self.em())
+ rhs.as_inner().ep() * self.ep()
+ rhs.as_inner().x() * self.x()
+ rhs.as_inner().y() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<RoundPoint<T>>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<RoundPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().em() * self.as_inner().em())
+ rhs.as_inner().ep() * self.as_inner().ep()
+ rhs.as_inner().x() * self.as_inner().x()
+ rhs.as_inner().y() * self.as_inner().y(),
)
}
}
#[doc = "Right contraction of [`RoundPoint`] by [`Scalar`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<Scalar<T>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Scalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.s() * self.x(),
rhs.s() * self.y(),
rhs.s() * self.ep(),
rhs.s() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Scalar<T>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Scalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.s() * self.as_inner().x(),
rhs.s() * self.as_inner().y(),
rhs.s() * self.as_inner().ep(),
rhs.s() * self.as_inner().em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Scalar<T>>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Scalar<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().s() * self.x(),
rhs.as_inner().s() * self.y(),
rhs.as_inner().s() * self.ep(),
rhs.as_inner().s() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Scalar<T>>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Scalar<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().s() * self.as_inner().x(),
rhs.as_inner().s() * self.as_inner().y(),
rhs.as_inner().s() * self.as_inner().ep(),
rhs.as_inner().s() * self.as_inner().em(),
)
}
}
#[doc = "Right contraction of [`Scalar`] by [`Scalar`].\n\nThe right contraction `a |_ b` projects `b` onto `a`, returning the\ncomponent of `a` orthogonal to `b`. The result grade is grade(a) - grade(b)\n(or zero if grade(b) > grade(a))."]
impl<T: Float> RightContract<Scalar<T>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.s() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Scalar<T>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.s() * self.as_inner().s())
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Scalar<T>>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(rhs.as_inner().s() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> RightContract<Unit<Scalar<T>>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn right_contract(&self, rhs: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(rhs.as_inner().s() * self.as_inner().s())
}
}
#[doc = "Sandwich product: [`Circle`] x [`Circle`] x rev([`Circle`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Circle<T>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-(self.e12em() * operand.e12em() * self.w())
+ self.e12em() * operand.w() * self.e12em()
- self.e1epem() * operand.e1epem() * self.w()
+ self.e1epem() * operand.w() * self.e1epem()
- self.e2epem() * operand.e2epem() * self.w()
+ self.e2epem() * operand.w() * self.e2epem()
- self.w() * operand.e12em() * self.e12em()
- self.w() * operand.e1epem() * self.e1epem()
- self.w() * operand.e2epem() * self.e2epem()
+ self.w() * operand.w() * self.w(),
-(self.e12em() * operand.e12em() * self.e12em())
- self.e12em() * operand.e1epem() * self.e1epem()
- self.e12em() * operand.e2epem() * self.e2epem()
+ self.e12em() * operand.w() * self.w()
+ self.e1epem() * operand.e12em() * self.e1epem()
- self.e1epem() * operand.e1epem() * self.e12em()
+ self.e2epem() * operand.e12em() * self.e2epem()
- self.e2epem() * operand.e2epem() * self.e12em()
- self.w() * operand.e12em() * self.w()
+ self.w() * operand.w() * self.e12em(),
-(self.e12em() * operand.e12em() * self.e1epem())
+ self.e12em() * operand.e1epem() * self.e12em()
- self.e1epem() * operand.e12em() * self.e12em()
- self.e1epem() * operand.e1epem() * self.e1epem()
- self.e1epem() * operand.e2epem() * self.e2epem()
+ self.e1epem() * operand.w() * self.w()
+ self.e2epem() * operand.e1epem() * self.e2epem()
- self.e2epem() * operand.e2epem() * self.e1epem()
- self.w() * operand.e1epem() * self.w()
+ self.w() * operand.w() * self.e1epem(),
-(self.e12em() * operand.e12em() * self.e2epem())
+ self.e12em() * operand.e2epem() * self.e12em()
- self.e1epem() * operand.e1epem() * self.e2epem()
+ self.e1epem() * operand.e2epem() * self.e1epem()
- self.e2epem() * operand.e12em() * self.e12em()
- self.e2epem() * operand.e1epem() * self.e1epem()
- self.e2epem() * operand.e2epem() * self.e2epem()
+ self.e2epem() * operand.w() * self.w()
- self.w() * operand.e2epem() * self.w()
+ self.w() * operand.w() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Circle<T>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.e12em() * self.as_inner().e12em() * self.as_inner().w()
+ -T::TWO * operand.e1epem() * self.as_inner().e1epem() * self.as_inner().w()
+ -T::TWO * operand.e2epem() * self.as_inner().e2epem() * self.as_inner().w()
+ operand.w() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.w() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.w() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.w() * self.as_inner().w() * self.as_inner().w(),
-(operand.e12em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.e12em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.e1epem() * self.as_inner().e12em() * self.as_inner().e1epem()
+ -T::TWO * operand.e2epem() * self.as_inner().e12em() * self.as_inner().e2epem()
+ T::TWO * operand.w() * self.as_inner().e12em() * self.as_inner().w()
+ operand.e12em() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.e12em() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.e1epem() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.e1epem() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.e12em() * self.as_inner().e12em() * self.as_inner().e1epem()
+ -T::TWO * operand.e2epem() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.w() * self.as_inner().e1epem() * self.as_inner().w()
+ operand.e1epem() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.e1epem() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.e2epem() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.e2epem() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.e12em() * self.as_inner().e12em() * self.as_inner().e2epem()
+ -T::TWO * operand.e1epem() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.w() * self.as_inner().e2epem() * self.as_inner().w()
+ operand.e2epem() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.e2epem() * self.as_inner().e1epem() * self.as_inner().e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Circle<T>>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.as_inner().e12em() * self.e12em() * self.w()
+ -T::TWO * operand.as_inner().e1epem() * self.e1epem() * self.w()
+ -T::TWO * operand.as_inner().e2epem() * self.e2epem() * self.w()
+ operand.as_inner().w() * self.e12em() * self.e12em()
+ operand.as_inner().w() * self.e1epem() * self.e1epem()
+ operand.as_inner().w() * self.e2epem() * self.e2epem()
+ operand.as_inner().w() * self.w() * self.w(),
-(operand.as_inner().e12em() * self.e12em() * self.e12em())
+ -(operand.as_inner().e12em() * self.w() * self.w())
+ -T::TWO * operand.as_inner().e1epem() * self.e12em() * self.e1epem()
+ -T::TWO * operand.as_inner().e2epem() * self.e12em() * self.e2epem()
+ T::TWO * operand.as_inner().w() * self.e12em() * self.w()
+ operand.as_inner().e12em() * self.e1epem() * self.e1epem()
+ operand.as_inner().e12em() * self.e2epem() * self.e2epem(),
-(operand.as_inner().e1epem() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().e1epem() * self.w() * self.w())
+ -T::TWO * operand.as_inner().e12em() * self.e12em() * self.e1epem()
+ -T::TWO * operand.as_inner().e2epem() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().w() * self.e1epem() * self.w()
+ operand.as_inner().e1epem() * self.e12em() * self.e12em()
+ operand.as_inner().e1epem() * self.e2epem() * self.e2epem(),
-(operand.as_inner().e2epem() * self.e2epem() * self.e2epem())
+ -(operand.as_inner().e2epem() * self.w() * self.w())
+ -T::TWO * operand.as_inner().e12em() * self.e12em() * self.e2epem()
+ -T::TWO * operand.as_inner().e1epem() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().w() * self.e2epem() * self.w()
+ operand.as_inner().e2epem() * self.e12em() * self.e12em()
+ operand.as_inner().e2epem() * self.e1epem() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Circle<T>>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.as_inner().e12em() * self.as_inner().e12em() * self.as_inner().w()
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1epem()
* self.as_inner().w()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e2epem()
* self.as_inner().w()
+ operand.as_inner().w() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().w() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().w() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.as_inner().w() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().e12em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().e12em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ T::TWO * operand.as_inner().w() * self.as_inner().e12em() * self.as_inner().w()
+ operand.as_inner().e12em() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().e12em() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.as_inner().e1epem() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.as_inner().e1epem() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO * operand.as_inner().w() * self.as_inner().e1epem() * self.as_inner().w()
+ operand.as_inner().e1epem() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().e1epem() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.as_inner().e2epem() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.as_inner().e2epem() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO * operand.as_inner().w() * self.as_inner().e2epem() * self.as_inner().w()
+ operand.as_inner().e2epem() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().e2epem() * self.as_inner().e1epem() * self.as_inner().e1epem(),
)
}
}
#[doc = "Sandwich product: [`Circle`] x [`FlatPoint`] x rev([`Circle`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<FlatPoint<T>> for Circle<T> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(self.e12em() * operand.e1em() * self.e12em())
+ self.e12em() * operand.epem() * self.e2epem()
- self.e1epem() * operand.e1em() * self.e1epem()
- self.e1epem() * operand.e2em() * self.e2epem()
+ self.e2epem() * operand.e1em() * self.e2epem()
- self.e2epem() * operand.e2em() * self.e1epem()
+ self.e2epem() * operand.epem() * self.e12em()
- self.w() * operand.e1em() * self.w(),
-(self.e12em() * operand.e2em() * self.e12em())
- self.e12em() * operand.epem() * self.e1epem()
- self.e1epem() * operand.e1em() * self.e2epem()
+ self.e1epem() * operand.e2em() * self.e1epem()
- self.e1epem() * operand.epem() * self.e12em()
- self.e2epem() * operand.e1em() * self.e1epem()
- self.e2epem() * operand.e2em() * self.e2epem()
- self.w() * operand.e2em() * self.w(),
self.e12em() * operand.e1em() * self.e2epem()
- self.e12em() * operand.e2em() * self.e1epem()
+ self.e12em() * operand.epem() * self.e12em()
- self.e1epem() * operand.e2em() * self.e12em()
- self.e1epem() * operand.epem() * self.e1epem()
+ self.e2epem() * operand.e1em() * self.e12em()
- self.e2epem() * operand.epem() * self.e2epem()
- self.w() * operand.epem() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<FlatPoint<T>> for Unit<Circle<T>> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.e1em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.e1em() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.e1em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.e2em() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.epem() * self.as_inner().e12em() * self.as_inner().e2epem()
+ operand.e1em() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.e2em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.e2em() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.e2em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.e1em() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ -T::TWO * operand.epem() * self.as_inner().e12em() * self.as_inner().e1epem()
+ operand.e2em() * self.as_inner().e1epem() * self.as_inner().e1epem(),
-(operand.epem() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.epem() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.epem() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.e2em() * self.as_inner().e12em() * self.as_inner().e1epem()
+ T::TWO * operand.e1em() * self.as_inner().e12em() * self.as_inner().e2epem()
+ operand.epem() * self.as_inner().e12em() * self.as_inner().e12em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<FlatPoint<T>>> for Circle<T> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.e12em() * self.e12em())
+ -(operand.as_inner().e1em() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().e1em() * self.w() * self.w())
+ -T::TWO * operand.as_inner().e2em() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().epem() * self.e12em() * self.e2epem()
+ operand.as_inner().e1em() * self.e2epem() * self.e2epem(),
-(operand.as_inner().e2em() * self.e12em() * self.e12em())
+ -(operand.as_inner().e2em() * self.e2epem() * self.e2epem())
+ -(operand.as_inner().e2em() * self.w() * self.w())
+ -T::TWO * operand.as_inner().e1em() * self.e1epem() * self.e2epem()
+ -T::TWO * operand.as_inner().epem() * self.e12em() * self.e1epem()
+ operand.as_inner().e2em() * self.e1epem() * self.e1epem(),
-(operand.as_inner().epem() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().epem() * self.e2epem() * self.e2epem())
+ -(operand.as_inner().epem() * self.w() * self.w())
+ -T::TWO * operand.as_inner().e2em() * self.e12em() * self.e1epem()
+ T::TWO * operand.as_inner().e1em() * self.e12em() * self.e2epem()
+ operand.as_inner().epem() * self.e12em() * self.e12em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<FlatPoint<T>>> for Unit<Circle<T>> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().e1em()
* self.as_inner().e1epem()
* self.as_inner().e1epem())
+ -(operand.as_inner().e1em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ operand.as_inner().e1em() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.as_inner().e2em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().e2em()
* self.as_inner().e2epem()
* self.as_inner().e2epem())
+ -(operand.as_inner().e2em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ operand.as_inner().e2em() * self.as_inner().e1epem() * self.as_inner().e1epem(),
-(operand.as_inner().epem() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.as_inner().epem()
* self.as_inner().e2epem()
* self.as_inner().e2epem())
+ -(operand.as_inner().epem() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ operand.as_inner().epem() * self.as_inner().e12em() * self.as_inner().e12em(),
)
}
}
#[doc = "Sandwich product: [`Circle`] x [`Line`] x rev([`Circle`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Line<T>> for Circle<T> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(self.e12em() * operand.d() * self.e2epem())
- self.e12em() * operand.nx() * self.e12em()
- self.e12em() * operand.ny() * self.e1epem()
+ self.e1epem() * operand.nx() * self.e1epem()
- self.e1epem() * operand.ny() * self.e12em()
- self.e2epem() * operand.d() * self.e12em()
+ self.e2epem() * operand.nx() * self.e2epem()
- self.w() * operand.nx() * self.w(),
-(self.e12em() * operand.nx() * self.e1epem())
+ self.e12em() * operand.ny() * self.e12em()
- self.e1epem() * operand.d() * self.e2epem()
- self.e1epem() * operand.nx() * self.e12em()
- self.e1epem() * operand.ny() * self.e1epem()
- self.e2epem() * operand.d() * self.e1epem()
+ self.e2epem() * operand.ny() * self.e2epem()
- self.w() * operand.ny() * self.w(),
self.e12em() * operand.d() * self.e12em() - self.e12em() * operand.nx() * self.e2epem()
+ self.e1epem() * operand.d() * self.e1epem()
- self.e1epem() * operand.ny() * self.e2epem()
- self.e2epem() * operand.d() * self.e2epem()
- self.e2epem() * operand.nx() * self.e12em()
- self.e2epem() * operand.ny() * self.e1epem()
- self.w() * operand.d() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Line<T>> for Unit<Circle<T>> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(operand.nx() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.nx() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.d() * self.as_inner().e12em() * self.as_inner().e2epem()
+ -T::TWO * operand.ny() * self.as_inner().e12em() * self.as_inner().e1epem()
+ operand.nx() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.nx() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.ny() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.ny() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.d() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ -T::TWO * operand.nx() * self.as_inner().e12em() * self.as_inner().e1epem()
+ operand.ny() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.ny() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.d() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.d() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.nx() * self.as_inner().e12em() * self.as_inner().e2epem()
+ -T::TWO * operand.ny() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ operand.d() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.d() * self.as_inner().e1epem() * self.as_inner().e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Line<T>>> for Circle<T> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.e12em() * self.e12em())
+ -(operand.as_inner().nx() * self.w() * self.w())
+ -T::TWO * operand.as_inner().d() * self.e12em() * self.e2epem()
+ -T::TWO * operand.as_inner().ny() * self.e12em() * self.e1epem()
+ operand.as_inner().nx() * self.e1epem() * self.e1epem()
+ operand.as_inner().nx() * self.e2epem() * self.e2epem(),
-(operand.as_inner().ny() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().ny() * self.w() * self.w())
+ -T::TWO * operand.as_inner().d() * self.e1epem() * self.e2epem()
+ -T::TWO * operand.as_inner().nx() * self.e12em() * self.e1epem()
+ operand.as_inner().ny() * self.e12em() * self.e12em()
+ operand.as_inner().ny() * self.e2epem() * self.e2epem(),
-(operand.as_inner().d() * self.e2epem() * self.e2epem())
+ -(operand.as_inner().d() * self.w() * self.w())
+ -T::TWO * operand.as_inner().nx() * self.e12em() * self.e2epem()
+ -T::TWO * operand.as_inner().ny() * self.e1epem() * self.e2epem()
+ operand.as_inner().d() * self.e12em() * self.e12em()
+ operand.as_inner().d() * self.e1epem() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Line<T>>> for Unit<Circle<T>> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().nx() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().d()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ -T::TWO
* operand.as_inner().ny()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ operand.as_inner().nx() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().nx() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.as_inner().ny() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.as_inner().ny() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().d()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ -T::TWO
* operand.as_inner().nx()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ operand.as_inner().ny() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().ny() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.as_inner().d() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.as_inner().d() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().nx()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ -T::TWO
* operand.as_inner().ny()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ operand.as_inner().d() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().d() * self.as_inner().e1epem() * self.as_inner().e1epem(),
)
}
}
#[doc = "Sandwich product: [`Circle`] x [`Motor`] x rev([`Circle`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Motor<T>> for Circle<T> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
self.e12em() * operand.e1ep() * self.e2epem()
- self.e12em() * operand.e2ep() * self.e1epem()
+ self.e12em() * operand.epem() * self.w()
- self.e12em() * operand.s() * self.e12em()
- self.e1epem() * operand.e2em() * self.w()
+ self.e1epem() * operand.e2ep() * self.e12em()
- self.e1epem() * operand.m() * self.e2epem()
- self.e1epem() * operand.s() * self.e1epem()
+ self.e2epem() * operand.e1em() * self.w()
- self.e2epem() * operand.e1ep() * self.e12em()
+ self.e2epem() * operand.m() * self.e1epem()
- self.e2epem() * operand.s() * self.e2epem()
- self.w() * operand.e1em() * self.e2epem()
+ self.w() * operand.e2em() * self.e1epem()
- self.w() * operand.epem() * self.e12em()
+ self.w() * operand.s() * self.w(),
-(self.e12em() * operand.e1ep() * self.e1epem())
- self.e12em() * operand.e2ep() * self.e2epem()
- self.e12em() * operand.m() * self.e12em()
+ self.e12em() * operand.ps() * self.w()
+ self.e1epem() * operand.e1em() * self.w()
- self.e1epem() * operand.e1ep() * self.e12em()
+ self.e1epem() * operand.m() * self.e1epem()
- self.e1epem() * operand.s() * self.e2epem()
+ self.e2epem() * operand.e2em() * self.w()
- self.e2epem() * operand.e2ep() * self.e12em()
+ self.e2epem() * operand.m() * self.e2epem()
+ self.e2epem() * operand.s() * self.e1epem()
+ self.w() * operand.e1em() * self.e1epem()
+ self.w() * operand.e2em() * self.e2epem()
+ self.w() * operand.m() * self.w()
- self.w() * operand.ps() * self.e12em(),
-(self.e12em() * operand.e1em() * self.w())
+ self.e12em() * operand.e1ep() * self.e12em()
- self.e12em() * operand.m() * self.e1epem()
+ self.e12em() * operand.s() * self.e2epem()
- self.e1epem() * operand.e1ep() * self.e1epem()
- self.e1epem() * operand.e2ep() * self.e2epem()
- self.e1epem() * operand.m() * self.e12em()
+ self.e1epem() * operand.ps() * self.w()
+ self.e2epem() * operand.e1ep() * self.e2epem()
- self.e2epem() * operand.e2ep() * self.e1epem()
+ self.e2epem() * operand.epem() * self.w()
- self.e2epem() * operand.s() * self.e12em()
- self.w() * operand.e1em() * self.e12em()
+ self.w() * operand.e1ep() * self.w()
+ self.w() * operand.epem() * self.e2epem()
- self.w() * operand.ps() * self.e1epem(),
-(self.e12em() * operand.e2em() * self.w())
+ self.e12em() * operand.e2ep() * self.e12em()
- self.e12em() * operand.m() * self.e2epem()
- self.e12em() * operand.s() * self.e1epem()
- self.e1epem() * operand.e1ep() * self.e2epem()
+ self.e1epem() * operand.e2ep() * self.e1epem()
- self.e1epem() * operand.epem() * self.w()
+ self.e1epem() * operand.s() * self.e12em()
- self.e2epem() * operand.e1ep() * self.e1epem()
- self.e2epem() * operand.e2ep() * self.e2epem()
- self.e2epem() * operand.m() * self.e12em()
+ self.e2epem() * operand.ps() * self.w()
- self.w() * operand.e2em() * self.e12em()
+ self.w() * operand.e2ep() * self.w()
- self.w() * operand.epem() * self.e1epem()
- self.w() * operand.ps() * self.e2epem(),
-(self.e12em() * operand.e1em() * self.e12em())
+ self.e12em() * operand.e1ep() * self.w()
+ self.e12em() * operand.epem() * self.e2epem()
- self.e12em() * operand.ps() * self.e1epem()
- self.e1epem() * operand.e1em() * self.e1epem()
- self.e1epem() * operand.e2em() * self.e2epem()
- self.e1epem() * operand.m() * self.w()
+ self.e1epem() * operand.ps() * self.e12em()
+ self.e2epem() * operand.e1em() * self.e2epem()
- self.e2epem() * operand.e2em() * self.e1epem()
+ self.e2epem() * operand.epem() * self.e12em()
- self.e2epem() * operand.s() * self.w()
- self.w() * operand.e1em() * self.w()
+ self.w() * operand.e1ep() * self.e12em()
- self.w() * operand.m() * self.e1epem()
+ self.w() * operand.s() * self.e2epem(),
-(self.e12em() * operand.e2em() * self.e12em())
+ self.e12em() * operand.e2ep() * self.w()
- self.e12em() * operand.epem() * self.e1epem()
- self.e12em() * operand.ps() * self.e2epem()
- self.e1epem() * operand.e1em() * self.e2epem()
+ self.e1epem() * operand.e2em() * self.e1epem()
- self.e1epem() * operand.epem() * self.e12em()
+ self.e1epem() * operand.s() * self.w()
- self.e2epem() * operand.e1em() * self.e1epem()
- self.e2epem() * operand.e2em() * self.e2epem()
- self.e2epem() * operand.m() * self.w()
+ self.e2epem() * operand.ps() * self.e12em()
- self.w() * operand.e2em() * self.w()
+ self.w() * operand.e2ep() * self.e12em()
- self.w() * operand.m() * self.e2epem()
- self.w() * operand.s() * self.e1epem(),
self.e12em() * operand.e1em() * self.e2epem()
- self.e12em() * operand.e2em() * self.e1epem()
+ self.e12em() * operand.epem() * self.e12em()
- self.e12em() * operand.s() * self.w()
- self.e1epem() * operand.e2em() * self.e12em()
+ self.e1epem() * operand.e2ep() * self.w()
- self.e1epem() * operand.epem() * self.e1epem()
- self.e1epem() * operand.ps() * self.e2epem()
+ self.e2epem() * operand.e1em() * self.e12em()
- self.e2epem() * operand.e1ep() * self.w()
- self.e2epem() * operand.epem() * self.e2epem()
+ self.e2epem() * operand.ps() * self.e1epem()
- self.w() * operand.e1ep() * self.e2epem()
+ self.w() * operand.e2ep() * self.e1epem()
- self.w() * operand.epem() * self.w()
+ self.w() * operand.s() * self.e12em(),
-(self.e12em() * operand.e1em() * self.e1epem())
- self.e12em() * operand.e2em() * self.e2epem()
- self.e12em() * operand.m() * self.w()
+ self.e12em() * operand.ps() * self.e12em()
+ self.e1epem() * operand.e1em() * self.e12em()
- self.e1epem() * operand.e1ep() * self.w()
- self.e1epem() * operand.epem() * self.e2epem()
+ self.e1epem() * operand.ps() * self.e1epem()
+ self.e2epem() * operand.e2em() * self.e12em()
- self.e2epem() * operand.e2ep() * self.w()
+ self.e2epem() * operand.epem() * self.e1epem()
+ self.e2epem() * operand.ps() * self.e2epem()
+ self.w() * operand.e1ep() * self.e1epem()
+ self.w() * operand.e2ep() * self.e2epem()
+ self.w() * operand.m() * self.e12em()
- self.w() * operand.ps() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Motor<T>> for Unit<Circle<T>> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(operand.s() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.s() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.s() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ operand.s() * self.as_inner().w() * self.as_inner().w(),
-(operand.m() * self.as_inner().e12em() * self.as_inner().e12em())
+ -T::TWO * operand.e1ep() * self.as_inner().e12em() * self.as_inner().e1epem()
+ -T::TWO * operand.e2ep() * self.as_inner().e12em() * self.as_inner().e2epem()
+ T::TWO * operand.e1em() * self.as_inner().e1epem() * self.as_inner().w()
+ T::TWO * operand.e2em() * self.as_inner().e2epem() * self.as_inner().w()
+ operand.m() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.m() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.m() * self.as_inner().w() * self.as_inner().w(),
-(operand.e1ep() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -T::TWO * operand.e1em() * self.as_inner().e12em() * self.as_inner().w()
+ -T::TWO * operand.e2ep() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ -T::TWO * operand.m() * self.as_inner().e12em() * self.as_inner().e1epem()
+ T::TWO * operand.epem() * self.as_inner().e2epem() * self.as_inner().w()
+ operand.e1ep() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.e1ep() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.e1ep() * self.as_inner().w() * self.as_inner().w(),
-(operand.e2ep() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO * operand.e1ep() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ -T::TWO * operand.e2em() * self.as_inner().e12em() * self.as_inner().w()
+ -T::TWO * operand.epem() * self.as_inner().e1epem() * self.as_inner().w()
+ -T::TWO * operand.m() * self.as_inner().e12em() * self.as_inner().e2epem()
+ operand.e2ep() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.e2ep() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.e2ep() * self.as_inner().w() * self.as_inner().w(),
-(operand.e1em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.e1em() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.e1em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.e2em() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ -T::TWO * operand.m() * self.as_inner().e1epem() * self.as_inner().w()
+ T::TWO * operand.e1ep() * self.as_inner().e12em() * self.as_inner().w()
+ T::TWO * operand.epem() * self.as_inner().e12em() * self.as_inner().e2epem()
+ operand.e1em() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.e2em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.e2em() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.e2em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.e1em() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ -T::TWO * operand.epem() * self.as_inner().e12em() * self.as_inner().e1epem()
+ -T::TWO * operand.m() * self.as_inner().e2epem() * self.as_inner().w()
+ T::TWO * operand.e2ep() * self.as_inner().e12em() * self.as_inner().w()
+ operand.e2em() * self.as_inner().e1epem() * self.as_inner().e1epem(),
-(operand.epem() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.epem() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.epem() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.e1ep() * self.as_inner().e2epem() * self.as_inner().w()
+ -T::TWO * operand.e2em() * self.as_inner().e12em() * self.as_inner().e1epem()
+ T::TWO * operand.e1em() * self.as_inner().e12em() * self.as_inner().e2epem()
+ T::TWO * operand.e2ep() * self.as_inner().e1epem() * self.as_inner().w()
+ operand.epem() * self.as_inner().e12em() * self.as_inner().e12em(),
-(operand.ps() * self.as_inner().w() * self.as_inner().w())
+ operand.ps() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.ps() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.ps() * self.as_inner().e2epem() * self.as_inner().e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Motor<T>>> for Circle<T> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.e12em() * self.e12em())
+ -(operand.as_inner().s() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().s() * self.e2epem() * self.e2epem())
+ operand.as_inner().s() * self.w() * self.w(),
-(operand.as_inner().m() * self.e12em() * self.e12em())
+ -T::TWO * operand.as_inner().e1ep() * self.e12em() * self.e1epem()
+ -T::TWO * operand.as_inner().e2ep() * self.e12em() * self.e2epem()
+ T::TWO * operand.as_inner().e1em() * self.e1epem() * self.w()
+ T::TWO * operand.as_inner().e2em() * self.e2epem() * self.w()
+ operand.as_inner().m() * self.e1epem() * self.e1epem()
+ operand.as_inner().m() * self.e2epem() * self.e2epem()
+ operand.as_inner().m() * self.w() * self.w(),
-(operand.as_inner().e1ep() * self.e1epem() * self.e1epem())
+ -T::TWO * operand.as_inner().e1em() * self.e12em() * self.w()
+ -T::TWO * operand.as_inner().e2ep() * self.e1epem() * self.e2epem()
+ -T::TWO * operand.as_inner().m() * self.e12em() * self.e1epem()
+ T::TWO * operand.as_inner().epem() * self.e2epem() * self.w()
+ operand.as_inner().e1ep() * self.e12em() * self.e12em()
+ operand.as_inner().e1ep() * self.e2epem() * self.e2epem()
+ operand.as_inner().e1ep() * self.w() * self.w(),
-(operand.as_inner().e2ep() * self.e2epem() * self.e2epem())
+ -T::TWO * operand.as_inner().e1ep() * self.e1epem() * self.e2epem()
+ -T::TWO * operand.as_inner().e2em() * self.e12em() * self.w()
+ -T::TWO * operand.as_inner().epem() * self.e1epem() * self.w()
+ -T::TWO * operand.as_inner().m() * self.e12em() * self.e2epem()
+ operand.as_inner().e2ep() * self.e12em() * self.e12em()
+ operand.as_inner().e2ep() * self.e1epem() * self.e1epem()
+ operand.as_inner().e2ep() * self.w() * self.w(),
-(operand.as_inner().e1em() * self.e12em() * self.e12em())
+ -(operand.as_inner().e1em() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().e1em() * self.w() * self.w())
+ -T::TWO * operand.as_inner().e2em() * self.e1epem() * self.e2epem()
+ -T::TWO * operand.as_inner().m() * self.e1epem() * self.w()
+ T::TWO * operand.as_inner().e1ep() * self.e12em() * self.w()
+ T::TWO * operand.as_inner().epem() * self.e12em() * self.e2epem()
+ operand.as_inner().e1em() * self.e2epem() * self.e2epem(),
-(operand.as_inner().e2em() * self.e12em() * self.e12em())
+ -(operand.as_inner().e2em() * self.e2epem() * self.e2epem())
+ -(operand.as_inner().e2em() * self.w() * self.w())
+ -T::TWO * operand.as_inner().e1em() * self.e1epem() * self.e2epem()
+ -T::TWO * operand.as_inner().epem() * self.e12em() * self.e1epem()
+ -T::TWO * operand.as_inner().m() * self.e2epem() * self.w()
+ T::TWO * operand.as_inner().e2ep() * self.e12em() * self.w()
+ operand.as_inner().e2em() * self.e1epem() * self.e1epem(),
-(operand.as_inner().epem() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().epem() * self.e2epem() * self.e2epem())
+ -(operand.as_inner().epem() * self.w() * self.w())
+ -T::TWO * operand.as_inner().e1ep() * self.e2epem() * self.w()
+ -T::TWO * operand.as_inner().e2em() * self.e12em() * self.e1epem()
+ T::TWO * operand.as_inner().e1em() * self.e12em() * self.e2epem()
+ T::TWO * operand.as_inner().e2ep() * self.e1epem() * self.w()
+ operand.as_inner().epem() * self.e12em() * self.e12em(),
-(operand.as_inner().ps() * self.w() * self.w())
+ operand.as_inner().ps() * self.e12em() * self.e12em()
+ operand.as_inner().ps() * self.e1epem() * self.e1epem()
+ operand.as_inner().ps() * self.e2epem() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Motor<T>>> for Unit<Circle<T>> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().s() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.as_inner().s() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ operand.as_inner().s() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().m() * self.as_inner().e12em() * self.as_inner().e12em())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1epem()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2epem()
* self.as_inner().w()
+ operand.as_inner().m() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().m() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.as_inner().m() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().e1ep() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e12em()
* self.as_inner().w()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e2epem()
* self.as_inner().w()
+ operand.as_inner().e1ep() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().e1ep() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.as_inner().e1ep() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().e2ep() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e12em()
* self.as_inner().w()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1epem()
* self.as_inner().w()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ operand.as_inner().e2ep() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().e2ep() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().e2ep() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().e1em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().e1em()
* self.as_inner().e1epem()
* self.as_inner().e1epem())
+ -(operand.as_inner().e1em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1epem() * self.as_inner().w()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e12em()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ operand.as_inner().e1em() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.as_inner().e2em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().e2em()
* self.as_inner().e2epem()
* self.as_inner().e2epem())
+ -(operand.as_inner().e2em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2epem() * self.as_inner().w()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e12em()
* self.as_inner().w()
+ operand.as_inner().e2em() * self.as_inner().e1epem() * self.as_inner().e1epem(),
-(operand.as_inner().epem() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.as_inner().epem()
* self.as_inner().e2epem()
* self.as_inner().e2epem())
+ -(operand.as_inner().epem() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2epem()
* self.as_inner().w()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1epem()
* self.as_inner().w()
+ operand.as_inner().epem() * self.as_inner().e12em() * self.as_inner().e12em(),
-(operand.as_inner().ps() * self.as_inner().w() * self.as_inner().w())
+ operand.as_inner().ps() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().ps() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().ps() * self.as_inner().e2epem() * self.as_inner().e2epem(),
)
}
}
#[doc = "Sandwich product: [`Circle`] x [`PointPair`] x rev([`Circle`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<PointPair<T>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(self.e12em() * operand.e1ep() * self.e1epem())
- self.e12em() * operand.e2ep() * self.e2epem()
- self.e12em() * operand.m() * self.e12em()
+ self.e1epem() * operand.e1em() * self.w()
- self.e1epem() * operand.e1ep() * self.e12em()
+ self.e1epem() * operand.m() * self.e1epem()
+ self.e2epem() * operand.e2em() * self.w()
- self.e2epem() * operand.e2ep() * self.e12em()
+ self.e2epem() * operand.m() * self.e2epem()
+ self.w() * operand.e1em() * self.e1epem()
+ self.w() * operand.e2em() * self.e2epem()
+ self.w() * operand.m() * self.w(),
-(self.e12em() * operand.e1em() * self.w())
+ self.e12em() * operand.e1ep() * self.e12em()
- self.e12em() * operand.m() * self.e1epem()
- self.e1epem() * operand.e1ep() * self.e1epem()
- self.e1epem() * operand.e2ep() * self.e2epem()
- self.e1epem() * operand.m() * self.e12em()
+ self.e2epem() * operand.e1ep() * self.e2epem()
- self.e2epem() * operand.e2ep() * self.e1epem()
+ self.e2epem() * operand.epem() * self.w()
- self.w() * operand.e1em() * self.e12em()
+ self.w() * operand.e1ep() * self.w()
+ self.w() * operand.epem() * self.e2epem(),
-(self.e12em() * operand.e2em() * self.w())
+ self.e12em() * operand.e2ep() * self.e12em()
- self.e12em() * operand.m() * self.e2epem()
- self.e1epem() * operand.e1ep() * self.e2epem()
+ self.e1epem() * operand.e2ep() * self.e1epem()
- self.e1epem() * operand.epem() * self.w()
- self.e2epem() * operand.e1ep() * self.e1epem()
- self.e2epem() * operand.e2ep() * self.e2epem()
- self.e2epem() * operand.m() * self.e12em()
- self.w() * operand.e2em() * self.e12em()
+ self.w() * operand.e2ep() * self.w()
- self.w() * operand.epem() * self.e1epem(),
-(self.e12em() * operand.e1em() * self.e12em())
+ self.e12em() * operand.e1ep() * self.w()
+ self.e12em() * operand.epem() * self.e2epem()
- self.e1epem() * operand.e1em() * self.e1epem()
- self.e1epem() * operand.e2em() * self.e2epem()
- self.e1epem() * operand.m() * self.w()
+ self.e2epem() * operand.e1em() * self.e2epem()
- self.e2epem() * operand.e2em() * self.e1epem()
+ self.e2epem() * operand.epem() * self.e12em()
- self.w() * operand.e1em() * self.w()
+ self.w() * operand.e1ep() * self.e12em()
- self.w() * operand.m() * self.e1epem(),
-(self.e12em() * operand.e2em() * self.e12em())
+ self.e12em() * operand.e2ep() * self.w()
- self.e12em() * operand.epem() * self.e1epem()
- self.e1epem() * operand.e1em() * self.e2epem()
+ self.e1epem() * operand.e2em() * self.e1epem()
- self.e1epem() * operand.epem() * self.e12em()
- self.e2epem() * operand.e1em() * self.e1epem()
- self.e2epem() * operand.e2em() * self.e2epem()
- self.e2epem() * operand.m() * self.w()
- self.w() * operand.e2em() * self.w()
+ self.w() * operand.e2ep() * self.e12em()
- self.w() * operand.m() * self.e2epem(),
self.e12em() * operand.e1em() * self.e2epem()
- self.e12em() * operand.e2em() * self.e1epem()
+ self.e12em() * operand.epem() * self.e12em()
- self.e1epem() * operand.e2em() * self.e12em()
+ self.e1epem() * operand.e2ep() * self.w()
- self.e1epem() * operand.epem() * self.e1epem()
+ self.e2epem() * operand.e1em() * self.e12em()
- self.e2epem() * operand.e1ep() * self.w()
- self.e2epem() * operand.epem() * self.e2epem()
- self.w() * operand.e1ep() * self.e2epem()
+ self.w() * operand.e2ep() * self.e1epem()
- self.w() * operand.epem() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<PointPair<T>> for Unit<Circle<T>> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.m() * self.as_inner().e12em() * self.as_inner().e12em())
+ -T::TWO * operand.e1ep() * self.as_inner().e12em() * self.as_inner().e1epem()
+ -T::TWO * operand.e2ep() * self.as_inner().e12em() * self.as_inner().e2epem()
+ T::TWO * operand.e1em() * self.as_inner().e1epem() * self.as_inner().w()
+ T::TWO * operand.e2em() * self.as_inner().e2epem() * self.as_inner().w()
+ operand.m() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.m() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.m() * self.as_inner().w() * self.as_inner().w(),
-(operand.e1ep() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -T::TWO * operand.e1em() * self.as_inner().e12em() * self.as_inner().w()
+ -T::TWO * operand.e2ep() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ -T::TWO * operand.m() * self.as_inner().e12em() * self.as_inner().e1epem()
+ T::TWO * operand.epem() * self.as_inner().e2epem() * self.as_inner().w()
+ operand.e1ep() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.e1ep() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.e1ep() * self.as_inner().w() * self.as_inner().w(),
-(operand.e2ep() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO * operand.e1ep() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ -T::TWO * operand.e2em() * self.as_inner().e12em() * self.as_inner().w()
+ -T::TWO * operand.epem() * self.as_inner().e1epem() * self.as_inner().w()
+ -T::TWO * operand.m() * self.as_inner().e12em() * self.as_inner().e2epem()
+ operand.e2ep() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.e2ep() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.e2ep() * self.as_inner().w() * self.as_inner().w(),
-(operand.e1em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.e1em() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.e1em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.e2em() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ -T::TWO * operand.m() * self.as_inner().e1epem() * self.as_inner().w()
+ T::TWO * operand.e1ep() * self.as_inner().e12em() * self.as_inner().w()
+ T::TWO * operand.epem() * self.as_inner().e12em() * self.as_inner().e2epem()
+ operand.e1em() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.e2em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.e2em() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.e2em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.e1em() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ -T::TWO * operand.epem() * self.as_inner().e12em() * self.as_inner().e1epem()
+ -T::TWO * operand.m() * self.as_inner().e2epem() * self.as_inner().w()
+ T::TWO * operand.e2ep() * self.as_inner().e12em() * self.as_inner().w()
+ operand.e2em() * self.as_inner().e1epem() * self.as_inner().e1epem(),
-(operand.epem() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.epem() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.epem() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.e1ep() * self.as_inner().e2epem() * self.as_inner().w()
+ -T::TWO * operand.e2em() * self.as_inner().e12em() * self.as_inner().e1epem()
+ T::TWO * operand.e1em() * self.as_inner().e12em() * self.as_inner().e2epem()
+ T::TWO * operand.e2ep() * self.as_inner().e1epem() * self.as_inner().w()
+ operand.epem() * self.as_inner().e12em() * self.as_inner().e12em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<PointPair<T>>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.e12em() * self.e12em())
+ -T::TWO * operand.as_inner().e1ep() * self.e12em() * self.e1epem()
+ -T::TWO * operand.as_inner().e2ep() * self.e12em() * self.e2epem()
+ T::TWO * operand.as_inner().e1em() * self.e1epem() * self.w()
+ T::TWO * operand.as_inner().e2em() * self.e2epem() * self.w()
+ operand.as_inner().m() * self.e1epem() * self.e1epem()
+ operand.as_inner().m() * self.e2epem() * self.e2epem()
+ operand.as_inner().m() * self.w() * self.w(),
-(operand.as_inner().e1ep() * self.e1epem() * self.e1epem())
+ -T::TWO * operand.as_inner().e1em() * self.e12em() * self.w()
+ -T::TWO * operand.as_inner().e2ep() * self.e1epem() * self.e2epem()
+ -T::TWO * operand.as_inner().m() * self.e12em() * self.e1epem()
+ T::TWO * operand.as_inner().epem() * self.e2epem() * self.w()
+ operand.as_inner().e1ep() * self.e12em() * self.e12em()
+ operand.as_inner().e1ep() * self.e2epem() * self.e2epem()
+ operand.as_inner().e1ep() * self.w() * self.w(),
-(operand.as_inner().e2ep() * self.e2epem() * self.e2epem())
+ -T::TWO * operand.as_inner().e1ep() * self.e1epem() * self.e2epem()
+ -T::TWO * operand.as_inner().e2em() * self.e12em() * self.w()
+ -T::TWO * operand.as_inner().epem() * self.e1epem() * self.w()
+ -T::TWO * operand.as_inner().m() * self.e12em() * self.e2epem()
+ operand.as_inner().e2ep() * self.e12em() * self.e12em()
+ operand.as_inner().e2ep() * self.e1epem() * self.e1epem()
+ operand.as_inner().e2ep() * self.w() * self.w(),
-(operand.as_inner().e1em() * self.e12em() * self.e12em())
+ -(operand.as_inner().e1em() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().e1em() * self.w() * self.w())
+ -T::TWO * operand.as_inner().e2em() * self.e1epem() * self.e2epem()
+ -T::TWO * operand.as_inner().m() * self.e1epem() * self.w()
+ T::TWO * operand.as_inner().e1ep() * self.e12em() * self.w()
+ T::TWO * operand.as_inner().epem() * self.e12em() * self.e2epem()
+ operand.as_inner().e1em() * self.e2epem() * self.e2epem(),
-(operand.as_inner().e2em() * self.e12em() * self.e12em())
+ -(operand.as_inner().e2em() * self.e2epem() * self.e2epem())
+ -(operand.as_inner().e2em() * self.w() * self.w())
+ -T::TWO * operand.as_inner().e1em() * self.e1epem() * self.e2epem()
+ -T::TWO * operand.as_inner().epem() * self.e12em() * self.e1epem()
+ -T::TWO * operand.as_inner().m() * self.e2epem() * self.w()
+ T::TWO * operand.as_inner().e2ep() * self.e12em() * self.w()
+ operand.as_inner().e2em() * self.e1epem() * self.e1epem(),
-(operand.as_inner().epem() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().epem() * self.e2epem() * self.e2epem())
+ -(operand.as_inner().epem() * self.w() * self.w())
+ -T::TWO * operand.as_inner().e1ep() * self.e2epem() * self.w()
+ -T::TWO * operand.as_inner().e2em() * self.e12em() * self.e1epem()
+ T::TWO * operand.as_inner().e1em() * self.e12em() * self.e2epem()
+ T::TWO * operand.as_inner().e2ep() * self.e1epem() * self.w()
+ operand.as_inner().epem() * self.e12em() * self.e12em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<PointPair<T>>> for Unit<Circle<T>> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.as_inner().e12em() * self.as_inner().e12em())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1epem()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2epem()
* self.as_inner().w()
+ operand.as_inner().m() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().m() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.as_inner().m() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().e1ep() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e12em()
* self.as_inner().w()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e2epem()
* self.as_inner().w()
+ operand.as_inner().e1ep() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().e1ep() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.as_inner().e1ep() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().e2ep() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e12em()
* self.as_inner().w()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1epem()
* self.as_inner().w()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ operand.as_inner().e2ep() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().e2ep() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().e2ep() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().e1em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().e1em()
* self.as_inner().e1epem()
* self.as_inner().e1epem())
+ -(operand.as_inner().e1em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1epem() * self.as_inner().w()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e12em()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ operand.as_inner().e1em() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.as_inner().e2em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().e2em()
* self.as_inner().e2epem()
* self.as_inner().e2epem())
+ -(operand.as_inner().e2em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2epem() * self.as_inner().w()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e12em()
* self.as_inner().w()
+ operand.as_inner().e2em() * self.as_inner().e1epem() * self.as_inner().e1epem(),
-(operand.as_inner().epem() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.as_inner().epem()
* self.as_inner().e2epem()
* self.as_inner().e2epem())
+ -(operand.as_inner().epem() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2epem()
* self.as_inner().w()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1epem()
* self.as_inner().w()
+ operand.as_inner().epem() * self.as_inner().e12em() * self.as_inner().e12em(),
)
}
}
#[doc = "Sandwich product: [`Circle`] x [`Pseudoscalar`] x rev([`Circle`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Pseudoscalar<T>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
self.e12em() * operand.ps() * self.e12em()
+ self.e1epem() * operand.ps() * self.e1epem()
+ self.e2epem() * operand.ps() * self.e2epem()
- self.w() * operand.ps() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Pseudoscalar<T>> for Unit<Circle<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.ps() * self.as_inner().w() * self.as_inner().w())
+ operand.ps() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.ps() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.ps() * self.as_inner().e2epem() * self.as_inner().e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Pseudoscalar<T>>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.w() * self.w())
+ operand.as_inner().ps() * self.e12em() * self.e12em()
+ operand.as_inner().ps() * self.e1epem() * self.e1epem()
+ operand.as_inner().ps() * self.e2epem() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Pseudoscalar<T>>> for Unit<Circle<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.as_inner().w() * self.as_inner().w())
+ operand.as_inner().ps() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().ps() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().ps() * self.as_inner().e2epem() * self.as_inner().e2epem(),
)
}
}
#[doc = "Sandwich product: [`Circle`] x [`RoundPoint`] x rev([`Circle`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<RoundPoint<T>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
self.e12em() * operand.ep() * self.e2epem()
- self.e12em() * operand.x() * self.e12em()
- self.e1epem() * operand.x() * self.e1epem()
- self.e1epem() * operand.y() * self.e2epem()
- self.e2epem() * operand.em() * self.w()
+ self.e2epem() * operand.ep() * self.e12em()
+ self.e2epem() * operand.x() * self.e2epem()
- self.e2epem() * operand.y() * self.e1epem()
- self.w() * operand.em() * self.e2epem()
+ self.w() * operand.x() * self.w(),
-(self.e12em() * operand.ep() * self.e1epem())
- self.e12em() * operand.y() * self.e12em()
+ self.e1epem() * operand.em() * self.w()
- self.e1epem() * operand.ep() * self.e12em()
- self.e1epem() * operand.x() * self.e2epem()
+ self.e1epem() * operand.y() * self.e1epem()
- self.e2epem() * operand.x() * self.e1epem()
- self.e2epem() * operand.y() * self.e2epem()
+ self.w() * operand.em() * self.e1epem()
+ self.w() * operand.y() * self.w(),
-(self.e12em() * operand.em() * self.w())
+ self.e12em() * operand.ep() * self.e12em()
+ self.e12em() * operand.x() * self.e2epem()
- self.e12em() * operand.y() * self.e1epem()
- self.e1epem() * operand.ep() * self.e1epem()
- self.e1epem() * operand.y() * self.e12em()
- self.e2epem() * operand.ep() * self.e2epem()
+ self.e2epem() * operand.x() * self.e12em()
- self.w() * operand.em() * self.e12em()
+ self.w() * operand.ep() * self.w(),
-(self.e12em() * operand.em() * self.e12em()) + self.e12em() * operand.ep() * self.w()
- self.e1epem() * operand.em() * self.e1epem()
- self.e1epem() * operand.y() * self.w()
- self.e2epem() * operand.em() * self.e2epem()
+ self.e2epem() * operand.x() * self.w()
- self.w() * operand.em() * self.w()
+ self.w() * operand.ep() * self.e12em()
+ self.w() * operand.x() * self.e2epem()
- self.w() * operand.y() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<RoundPoint<T>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.x() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.x() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -T::TWO * operand.em() * self.as_inner().e2epem() * self.as_inner().w()
+ -T::TWO * operand.y() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.ep() * self.as_inner().e12em() * self.as_inner().e2epem()
+ operand.x() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.x() * self.as_inner().w() * self.as_inner().w(),
-(operand.y() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.y() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO * operand.ep() * self.as_inner().e12em() * self.as_inner().e1epem()
+ -T::TWO * operand.x() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.em() * self.as_inner().e1epem() * self.as_inner().w()
+ operand.y() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.y() * self.as_inner().w() * self.as_inner().w(),
-(operand.ep() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.ep() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO * operand.em() * self.as_inner().e12em() * self.as_inner().w()
+ -T::TWO * operand.y() * self.as_inner().e12em() * self.as_inner().e1epem()
+ T::TWO * operand.x() * self.as_inner().e12em() * self.as_inner().e2epem()
+ operand.ep() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.ep() * self.as_inner().w() * self.as_inner().w(),
-(operand.em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.em() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.em() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.y() * self.as_inner().e1epem() * self.as_inner().w()
+ T::TWO * operand.ep() * self.as_inner().e12em() * self.as_inner().w()
+ T::TWO * operand.x() * self.as_inner().e2epem() * self.as_inner().w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<RoundPoint<T>>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.e12em() * self.e12em())
+ -(operand.as_inner().x() * self.e1epem() * self.e1epem())
+ -T::TWO * operand.as_inner().em() * self.e2epem() * self.w()
+ -T::TWO * operand.as_inner().y() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().ep() * self.e12em() * self.e2epem()
+ operand.as_inner().x() * self.e2epem() * self.e2epem()
+ operand.as_inner().x() * self.w() * self.w(),
-(operand.as_inner().y() * self.e12em() * self.e12em())
+ -(operand.as_inner().y() * self.e2epem() * self.e2epem())
+ -T::TWO * operand.as_inner().ep() * self.e12em() * self.e1epem()
+ -T::TWO * operand.as_inner().x() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().em() * self.e1epem() * self.w()
+ operand.as_inner().y() * self.e1epem() * self.e1epem()
+ operand.as_inner().y() * self.w() * self.w(),
-(operand.as_inner().ep() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().ep() * self.e2epem() * self.e2epem())
+ -T::TWO * operand.as_inner().em() * self.e12em() * self.w()
+ -T::TWO * operand.as_inner().y() * self.e12em() * self.e1epem()
+ T::TWO * operand.as_inner().x() * self.e12em() * self.e2epem()
+ operand.as_inner().ep() * self.e12em() * self.e12em()
+ operand.as_inner().ep() * self.w() * self.w(),
-(operand.as_inner().em() * self.e12em() * self.e12em())
+ -(operand.as_inner().em() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().em() * self.e2epem() * self.e2epem())
+ -(operand.as_inner().em() * self.w() * self.w())
+ -T::TWO * operand.as_inner().y() * self.e1epem() * self.w()
+ T::TWO * operand.as_inner().ep() * self.e12em() * self.w()
+ T::TWO * operand.as_inner().x() * self.e2epem() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<RoundPoint<T>>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().x() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -T::TWO
* operand.as_inner().em()
* self.as_inner().e2epem()
* self.as_inner().w()
+ -T::TWO
* operand.as_inner().y()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().ep()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ operand.as_inner().x() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.as_inner().x() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().y() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().y() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO
* operand.as_inner().ep()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ -T::TWO
* operand.as_inner().x()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO * operand.as_inner().em() * self.as_inner().e1epem() * self.as_inner().w()
+ operand.as_inner().y() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().y() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().ep() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.as_inner().ep() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO * operand.as_inner().em() * self.as_inner().e12em() * self.as_inner().w()
+ -T::TWO
* operand.as_inner().y()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ T::TWO
* operand.as_inner().x()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ operand.as_inner().ep() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().ep() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().em() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.as_inner().em() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.as_inner().em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.as_inner().y() * self.as_inner().e1epem() * self.as_inner().w()
+ T::TWO * operand.as_inner().ep() * self.as_inner().e12em() * self.as_inner().w()
+ T::TWO * operand.as_inner().x() * self.as_inner().e2epem() * self.as_inner().w(),
)
}
}
#[doc = "Sandwich product: [`Circle`] x [`Scalar`] x rev([`Circle`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Scalar<T>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(self.e12em() * operand.s() * self.e12em())
- self.e1epem() * operand.s() * self.e1epem()
- self.e2epem() * operand.s() * self.e2epem()
+ self.w() * operand.s() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Scalar<T>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.s() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.s() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.s() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ operand.s() * self.as_inner().w() * self.as_inner().w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Scalar<T>>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.e12em() * self.e12em())
+ -(operand.as_inner().s() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().s() * self.e2epem() * self.e2epem())
+ operand.as_inner().s() * self.w() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Scalar<T>>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().s() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.as_inner().s() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ operand.as_inner().s() * self.as_inner().w() * self.as_inner().w(),
)
}
}
#[doc = "Sandwich product: [`FlatPoint`] x [`Circle`] x rev([`FlatPoint`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Circle<T>> for FlatPoint<T> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
self.e1em() * operand.w() * self.e1em()
+ self.e2em() * operand.w() * self.e2em()
+ self.epem() * operand.w() * self.epem(),
-(self.e1em() * operand.e12em() * self.e1em())
+ self.e1em() * operand.e2epem() * self.epem()
- self.e2em() * operand.e12em() * self.e2em()
- self.e2em() * operand.e1epem() * self.epem()
+ self.epem() * operand.e12em() * self.epem()
- self.epem() * operand.e1epem() * self.e2em()
+ self.epem() * operand.e2epem() * self.e1em(),
-(self.e1em() * operand.e1epem() * self.e1em())
- self.e1em() * operand.e2epem() * self.e2em()
- self.e2em() * operand.e12em() * self.epem()
+ self.e2em() * operand.e1epem() * self.e2em()
- self.e2em() * operand.e2epem() * self.e1em()
- self.epem() * operand.e12em() * self.e2em()
- self.epem() * operand.e1epem() * self.epem(),
self.e1em() * operand.e12em() * self.epem()
- self.e1em() * operand.e1epem() * self.e2em()
+ self.e1em() * operand.e2epem() * self.e1em()
- self.e2em() * operand.e1epem() * self.e1em()
- self.e2em() * operand.e2epem() * self.e2em()
+ self.epem() * operand.e12em() * self.e1em()
- self.epem() * operand.e2epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Circle<T>> for Unit<FlatPoint<T>> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
operand.w() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.w() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.w() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e12em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e12em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO * operand.e1epem() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.e2epem() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.e12em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e1epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e12em() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.e2epem() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.e1epem() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.e2epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1epem() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e12em() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.e2epem() * self.as_inner().e1em() * self.as_inner().e1em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Circle<T>>> for FlatPoint<T> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
operand.as_inner().w() * self.e1em() * self.e1em()
+ operand.as_inner().w() * self.e2em() * self.e2em()
+ operand.as_inner().w() * self.epem() * self.epem(),
-(operand.as_inner().e12em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e12em() * self.e2em() * self.e2em())
+ -T::TWO * operand.as_inner().e1epem() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().e2epem() * self.e1em() * self.epem()
+ operand.as_inner().e12em() * self.epem() * self.epem(),
-(operand.as_inner().e1epem() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1epem() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e12em() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().e2epem() * self.e1em() * self.e2em()
+ operand.as_inner().e1epem() * self.e2em() * self.e2em(),
-(operand.as_inner().e2epem() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2epem() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1epem() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e12em() * self.e1em() * self.epem()
+ operand.as_inner().e2epem() * self.e1em() * self.e1em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Circle<T>>> for Unit<FlatPoint<T>> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
operand.as_inner().w() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().w() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().w() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e12em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e12em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ operand.as_inner().e12em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e1epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ operand.as_inner().e1epem() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().e2epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ operand.as_inner().e2epem() * self.as_inner().e1em() * self.as_inner().e1em(),
)
}
}
#[doc = "Sandwich product: [`FlatPoint`] x [`FlatPoint`] x rev([`FlatPoint`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<FlatPoint<T>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(self.e1em() * operand.e1em() * self.e1em())
- self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.epem() * self.epem()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e2em() * self.e1em()
+ self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.epem() * self.e1em(),
-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e2em() * self.e1em()
- self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.epem() * self.epem()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.epem() * self.e2em(),
-(self.e1em() * operand.e1em() * self.epem())
+ self.e1em() * operand.epem() * self.e1em()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.epem() * self.e2em()
- self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<FlatPoint<T>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e1em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e2em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.epem() * self.as_inner().e2em() * self.as_inner().e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<FlatPoint<T>>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.e1em() * self.e1em())
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ operand.as_inner().e1em() * self.e2em() * self.e2em()
+ operand.as_inner().e1em() * self.epem() * self.epem(),
-(operand.as_inner().e2em() * self.e2em() * self.e2em())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ operand.as_inner().e2em() * self.e1em() * self.e1em()
+ operand.as_inner().e2em() * self.epem() * self.epem(),
-(operand.as_inner().epem() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ operand.as_inner().epem() * self.e1em() * self.e1em()
+ operand.as_inner().epem() * self.e2em() * self.e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<FlatPoint<T>>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em(),
)
}
}
#[doc = "Sandwich product: [`FlatPoint`] x [`Line`] x rev([`FlatPoint`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Line<T>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
self.e1em() * operand.d() * self.epem()
- self.e1em() * operand.nx() * self.e1em()
- self.e2em() * operand.nx() * self.e2em()
- self.e2em() * operand.ny() * self.epem()
+ self.epem() * operand.d() * self.e1em()
+ self.epem() * operand.nx() * self.epem()
- self.epem() * operand.ny() * self.e2em(),
-(self.e1em() * operand.d() * self.e2em())
- self.e1em() * operand.ny() * self.e1em()
- self.e2em() * operand.d() * self.e1em()
- self.e2em() * operand.nx() * self.epem()
+ self.e2em() * operand.ny() * self.e2em()
- self.epem() * operand.nx() * self.e2em()
- self.epem() * operand.ny() * self.epem(),
self.e1em() * operand.d() * self.e1em() + self.e1em() * operand.nx() * self.epem()
- self.e1em() * operand.ny() * self.e2em()
- self.e2em() * operand.d() * self.e2em()
- self.e2em() * operand.ny() * self.e1em()
- self.epem() * operand.d() * self.epem()
+ self.epem() * operand.nx() * self.e1em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Line<T>> for Unit<FlatPoint<T>> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(operand.nx() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.nx() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO * operand.ny() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.d() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.nx() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.ny() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ny() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.d() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.nx() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.ny() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.d() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.d() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.ny() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.nx() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.d() * self.as_inner().e1em() * self.as_inner().e1em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Line<T>>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.e1em() * self.e1em())
+ -(operand.as_inner().nx() * self.e2em() * self.e2em())
+ -T::TWO * operand.as_inner().ny() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().d() * self.e1em() * self.epem()
+ operand.as_inner().nx() * self.epem() * self.epem(),
-(operand.as_inner().ny() * self.e1em() * self.e1em())
+ -(operand.as_inner().ny() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().d() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().nx() * self.e2em() * self.epem()
+ operand.as_inner().ny() * self.e2em() * self.e2em(),
-(operand.as_inner().d() * self.e2em() * self.e2em())
+ -(operand.as_inner().d() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().ny() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().nx() * self.e1em() * self.epem()
+ operand.as_inner().d() * self.e1em() * self.e1em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Line<T>>> for Unit<FlatPoint<T>> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().nx() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO
* operand.as_inner().ny()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().d() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.as_inner().nx() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().ny() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ny() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().d()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().nx()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().ny() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().d() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().d() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().ny()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().nx()
* self.as_inner().e1em()
* self.as_inner().epem()
+ operand.as_inner().d() * self.as_inner().e1em() * self.as_inner().e1em(),
)
}
}
#[doc = "Sandwich product: [`FlatPoint`] x [`Motor`] x rev([`FlatPoint`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Motor<T>> for FlatPoint<T> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(self.e1em() * operand.e1ep() * self.epem())
- self.e1em() * operand.m() * self.e2em()
- self.e1em() * operand.s() * self.e1em()
- self.e2em() * operand.e2ep() * self.epem()
+ self.e2em() * operand.m() * self.e1em()
- self.e2em() * operand.s() * self.e2em()
+ self.epem() * operand.e1ep() * self.e1em()
+ self.epem() * operand.e2ep() * self.e2em()
- self.epem() * operand.s() * self.epem(),
-(self.e1em() * operand.e2ep() * self.epem()) + self.e1em() * operand.m() * self.e1em()
- self.e1em() * operand.s() * self.e2em()
+ self.e2em() * operand.e1ep() * self.epem()
+ self.e2em() * operand.m() * self.e2em()
+ self.e2em() * operand.s() * self.e1em()
+ self.epem() * operand.e1ep() * self.e2em()
- self.epem() * operand.e2ep() * self.e1em()
- self.epem() * operand.m() * self.epem(),
self.e1em() * operand.e1ep() * self.e1em() + self.e1em() * operand.e2ep() * self.e2em()
- self.e1em() * operand.s() * self.epem()
- self.e2em() * operand.e1ep() * self.e2em()
+ self.e2em() * operand.e2ep() * self.e1em()
+ self.e2em() * operand.m() * self.epem()
+ self.epem() * operand.e1ep() * self.epem()
+ self.epem() * operand.m() * self.e2em()
+ self.epem() * operand.s() * self.e1em(),
self.e1em() * operand.e1ep() * self.e2em()
- self.e1em() * operand.e2ep() * self.e1em()
- self.e1em() * operand.m() * self.epem()
+ self.e2em() * operand.e1ep() * self.e1em()
+ self.e2em() * operand.e2ep() * self.e2em()
- self.e2em() * operand.s() * self.epem()
+ self.epem() * operand.e2ep() * self.epem()
- self.epem() * operand.m() * self.e1em()
+ self.epem() * operand.s() * self.e2em(),
-(self.e1em() * operand.e1em() * self.e1em())
- self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.epem() * self.epem()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e2em() * self.e1em()
+ self.e2em() * operand.ps() * self.epem()
+ self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.epem() * self.e1em()
- self.epem() * operand.ps() * self.e2em(),
-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e2em() * self.e1em()
- self.e1em() * operand.ps() * self.epem()
- self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.epem() * self.epem()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.epem() * self.e2em()
+ self.epem() * operand.ps() * self.e1em(),
-(self.e1em() * operand.e1em() * self.epem())
+ self.e1em() * operand.epem() * self.e1em()
+ self.e1em() * operand.ps() * self.e2em()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.epem() * self.e2em()
- self.e2em() * operand.ps() * self.e1em()
- self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.epem() * self.epem(),
-(self.e1em() * operand.e2em() * self.epem())
+ self.e1em() * operand.epem() * self.e2em()
- self.e1em() * operand.ps() * self.e1em()
+ self.e2em() * operand.e1em() * self.epem()
- self.e2em() * operand.epem() * self.e1em()
- self.e2em() * operand.ps() * self.e2em()
- self.epem() * operand.e1em() * self.e2em()
+ self.epem() * operand.e2em() * self.e1em()
- self.epem() * operand.ps() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Motor<T>> for Unit<FlatPoint<T>> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(operand.s() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.s() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.s() * self.as_inner().epem() * self.as_inner().epem()),
-(operand.m() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.m() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.m() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e1ep() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e2ep() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e1em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e2em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.epem() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.ps() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ps() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.ps() * self.as_inner().epem() * self.as_inner().epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Motor<T>>> for FlatPoint<T> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.e1em() * self.e1em())
+ -(operand.as_inner().s() * self.e2em() * self.e2em())
+ -(operand.as_inner().s() * self.epem() * self.epem()),
-(operand.as_inner().m() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e2em() * self.epem()
+ operand.as_inner().m() * self.e1em() * self.e1em()
+ operand.as_inner().m() * self.e2em() * self.e2em(),
-(operand.as_inner().e1ep() * self.e2em() * self.e2em())
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().m() * self.e2em() * self.epem()
+ operand.as_inner().e1ep() * self.e1em() * self.e1em()
+ operand.as_inner().e1ep() * self.epem() * self.epem(),
-(operand.as_inner().e2ep() * self.e1em() * self.e1em())
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2em()
+ operand.as_inner().e2ep() * self.e2em() * self.e2em()
+ operand.as_inner().e2ep() * self.epem() * self.epem(),
-(operand.as_inner().e1em() * self.e1em() * self.e1em())
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ operand.as_inner().e1em() * self.e2em() * self.e2em()
+ operand.as_inner().e1em() * self.epem() * self.epem(),
-(operand.as_inner().e2em() * self.e2em() * self.e2em())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ operand.as_inner().e2em() * self.e1em() * self.e1em()
+ operand.as_inner().e2em() * self.epem() * self.epem(),
-(operand.as_inner().epem() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ operand.as_inner().epem() * self.e1em() * self.e1em()
+ operand.as_inner().epem() * self.e2em() * self.e2em(),
-(operand.as_inner().ps() * self.e1em() * self.e1em())
+ -(operand.as_inner().ps() * self.e2em() * self.e2em())
+ -(operand.as_inner().ps() * self.epem() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Motor<T>>> for Unit<FlatPoint<T>> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().s() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().s() * self.as_inner().epem() * self.as_inner().epem()),
-(operand.as_inner().m() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().e1ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.as_inner().e1ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e1ep() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e2ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ operand.as_inner().e2ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e2ep() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().ps() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ps() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().ps() * self.as_inner().epem() * self.as_inner().epem()),
)
}
}
#[doc = "Sandwich product: [`FlatPoint`] x [`PointPair`] x rev([`FlatPoint`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<PointPair<T>> for FlatPoint<T> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(self.e1em() * operand.e2ep() * self.epem())
+ self.e1em() * operand.m() * self.e1em()
+ self.e2em() * operand.e1ep() * self.epem()
+ self.e2em() * operand.m() * self.e2em()
+ self.epem() * operand.e1ep() * self.e2em()
- self.epem() * operand.e2ep() * self.e1em()
- self.epem() * operand.m() * self.epem(),
self.e1em() * operand.e1ep() * self.e1em() + self.e1em() * operand.e2ep() * self.e2em()
- self.e2em() * operand.e1ep() * self.e2em()
+ self.e2em() * operand.e2ep() * self.e1em()
+ self.e2em() * operand.m() * self.epem()
+ self.epem() * operand.e1ep() * self.epem()
+ self.epem() * operand.m() * self.e2em(),
self.e1em() * operand.e1ep() * self.e2em()
- self.e1em() * operand.e2ep() * self.e1em()
- self.e1em() * operand.m() * self.epem()
+ self.e2em() * operand.e1ep() * self.e1em()
+ self.e2em() * operand.e2ep() * self.e2em()
+ self.epem() * operand.e2ep() * self.epem()
- self.epem() * operand.m() * self.e1em(),
-(self.e1em() * operand.e1em() * self.e1em())
- self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.epem() * self.epem()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e2em() * self.e1em()
+ self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.epem() * self.e1em(),
-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e2em() * self.e1em()
- self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.epem() * self.epem()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.epem() * self.e2em(),
-(self.e1em() * operand.e1em() * self.epem())
+ self.e1em() * operand.epem() * self.e1em()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.epem() * self.e2em()
- self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<PointPair<T>> for Unit<FlatPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.m() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.m() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.m() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e1ep() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e2ep() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e1em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e2em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.epem() * self.as_inner().e2em() * self.as_inner().e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<PointPair<T>>> for FlatPoint<T> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e2em() * self.epem()
+ operand.as_inner().m() * self.e1em() * self.e1em()
+ operand.as_inner().m() * self.e2em() * self.e2em(),
-(operand.as_inner().e1ep() * self.e2em() * self.e2em())
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().m() * self.e2em() * self.epem()
+ operand.as_inner().e1ep() * self.e1em() * self.e1em()
+ operand.as_inner().e1ep() * self.epem() * self.epem(),
-(operand.as_inner().e2ep() * self.e1em() * self.e1em())
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2em()
+ operand.as_inner().e2ep() * self.e2em() * self.e2em()
+ operand.as_inner().e2ep() * self.epem() * self.epem(),
-(operand.as_inner().e1em() * self.e1em() * self.e1em())
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ operand.as_inner().e1em() * self.e2em() * self.e2em()
+ operand.as_inner().e1em() * self.epem() * self.epem(),
-(operand.as_inner().e2em() * self.e2em() * self.e2em())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ operand.as_inner().e2em() * self.e1em() * self.e1em()
+ operand.as_inner().e2em() * self.epem() * self.epem(),
-(operand.as_inner().epem() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ operand.as_inner().epem() * self.e1em() * self.e1em()
+ operand.as_inner().epem() * self.e2em() * self.e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<PointPair<T>>> for Unit<FlatPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().e1ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.as_inner().e1ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e1ep() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e2ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ operand.as_inner().e2ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e2ep() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em(),
)
}
}
#[doc = "Sandwich product: [`FlatPoint`] x [`Pseudoscalar`] x rev([`FlatPoint`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Pseudoscalar<T>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(self.e1em() * operand.ps() * self.e1em())
- self.e2em() * operand.ps() * self.e2em()
- self.epem() * operand.ps() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Pseudoscalar<T>> for Unit<FlatPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.ps() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ps() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.ps() * self.as_inner().epem() * self.as_inner().epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Pseudoscalar<T>>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.e1em() * self.e1em())
+ -(operand.as_inner().ps() * self.e2em() * self.e2em())
+ -(operand.as_inner().ps() * self.epem() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Pseudoscalar<T>>> for Unit<FlatPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ps() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().ps() * self.as_inner().epem() * self.as_inner().epem()),
)
}
}
#[doc = "Sandwich product: [`FlatPoint`] x [`RoundPoint`] x rev([`FlatPoint`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<RoundPoint<T>> for FlatPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
self.e1em() * operand.ep() * self.epem()
+ self.e1em() * operand.x() * self.e1em()
+ self.e1em() * operand.y() * self.e2em()
- self.e2em() * operand.x() * self.e2em()
+ self.e2em() * operand.y() * self.e1em()
+ self.epem() * operand.ep() * self.e1em()
- self.epem() * operand.x() * self.epem(),
self.e1em() * operand.x() * self.e2em() - self.e1em() * operand.y() * self.e1em()
+ self.e2em() * operand.ep() * self.epem()
+ self.e2em() * operand.x() * self.e1em()
+ self.e2em() * operand.y() * self.e2em()
+ self.epem() * operand.ep() * self.e2em()
- self.epem() * operand.y() * self.epem(),
-(self.e1em() * operand.ep() * self.e1em()) + self.e1em() * operand.x() * self.epem()
- self.e2em() * operand.ep() * self.e2em()
+ self.e2em() * operand.y() * self.epem()
+ self.epem() * operand.ep() * self.epem()
+ self.epem() * operand.x() * self.e1em()
+ self.epem() * operand.y() * self.e2em(),
self.e1em() * operand.em() * self.e1em()
+ self.e2em() * operand.em() * self.e2em()
+ self.epem() * operand.em() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<RoundPoint<T>> for Unit<FlatPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.x() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.x() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO * operand.ep() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.y() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.x() * self.as_inner().e1em() * self.as_inner().e1em(),
-(operand.y() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.y() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO * operand.ep() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.x() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.y() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ T::TWO * operand.x() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.y() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.ep() * self.as_inner().epem() * self.as_inner().epem(),
operand.em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.em() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<RoundPoint<T>>> for FlatPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.e2em() * self.e2em())
+ -(operand.as_inner().x() * self.epem() * self.epem())
+ T::TWO * operand.as_inner().ep() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().y() * self.e1em() * self.e2em()
+ operand.as_inner().x() * self.e1em() * self.e1em(),
-(operand.as_inner().y() * self.e1em() * self.e1em())
+ -(operand.as_inner().y() * self.epem() * self.epem())
+ T::TWO * operand.as_inner().ep() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().x() * self.e1em() * self.e2em()
+ operand.as_inner().y() * self.e2em() * self.e2em(),
-(operand.as_inner().ep() * self.e1em() * self.e1em())
+ -(operand.as_inner().ep() * self.e2em() * self.e2em())
+ T::TWO * operand.as_inner().x() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().y() * self.e2em() * self.epem()
+ operand.as_inner().ep() * self.epem() * self.epem(),
operand.as_inner().em() * self.e1em() * self.e1em()
+ operand.as_inner().em() * self.e2em() * self.e2em()
+ operand.as_inner().em() * self.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<RoundPoint<T>>> for Unit<FlatPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().x() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO
* operand.as_inner().ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().e1em(),
-(operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().y() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO
* operand.as_inner().ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.as_inner().y() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ T::TWO * operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.as_inner().y() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.as_inner().ep() * self.as_inner().epem() * self.as_inner().epem(),
operand.as_inner().em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().em() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Sandwich product: [`FlatPoint`] x [`Scalar`] x rev([`FlatPoint`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Scalar<T>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(self.e1em() * operand.s() * self.e1em())
- self.e2em() * operand.s() * self.e2em()
- self.epem() * operand.s() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Scalar<T>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.s() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.s() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.s() * self.as_inner().epem() * self.as_inner().epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Scalar<T>>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.e1em() * self.e1em())
+ -(operand.as_inner().s() * self.e2em() * self.e2em())
+ -(operand.as_inner().s() * self.epem() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Scalar<T>>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().s() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().s() * self.as_inner().epem() * self.as_inner().epem()),
)
}
}
#[doc = "Sandwich product: [`Line`] x [`Circle`] x rev([`Line`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Circle<T>> for Line<T> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
self.d() * operand.w() * self.d()
+ self.nx() * operand.w() * self.nx()
+ self.ny() * operand.w() * self.ny(),
self.d() * operand.e12em() * self.d()
- self.d() * operand.e2epem() * self.nx()
- self.nx() * operand.e12em() * self.nx()
- self.nx() * operand.e1epem() * self.ny()
- self.nx() * operand.e2epem() * self.d()
+ self.ny() * operand.e12em() * self.ny()
- self.ny() * operand.e1epem() * self.nx(),
self.d() * operand.e1epem() * self.d()
- self.d() * operand.e2epem() * self.ny()
- self.nx() * operand.e12em() * self.ny()
+ self.nx() * operand.e1epem() * self.nx()
- self.ny() * operand.e12em() * self.nx()
- self.ny() * operand.e1epem() * self.ny()
- self.ny() * operand.e2epem() * self.d(),
-(self.d() * operand.e12em() * self.nx())
- self.d() * operand.e1epem() * self.ny()
- self.d() * operand.e2epem() * self.d()
- self.nx() * operand.e12em() * self.d()
+ self.nx() * operand.e2epem() * self.nx()
- self.ny() * operand.e1epem() * self.d()
+ self.ny() * operand.e2epem() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Circle<T>> for Unit<Line<T>> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
operand.w() * self.as_inner().d() * self.as_inner().d()
+ operand.w() * self.as_inner().nx() * self.as_inner().nx()
+ operand.w() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.e12em() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.e1epem() * self.as_inner().nx() * self.as_inner().ny()
+ -T::TWO * operand.e2epem() * self.as_inner().d() * self.as_inner().nx()
+ operand.e12em() * self.as_inner().d() * self.as_inner().d()
+ operand.e12em() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.e1epem() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.e12em() * self.as_inner().nx() * self.as_inner().ny()
+ -T::TWO * operand.e2epem() * self.as_inner().d() * self.as_inner().ny()
+ operand.e1epem() * self.as_inner().d() * self.as_inner().d()
+ operand.e1epem() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.e2epem() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.e12em() * self.as_inner().d() * self.as_inner().nx()
+ -T::TWO * operand.e1epem() * self.as_inner().d() * self.as_inner().ny()
+ operand.e2epem() * self.as_inner().nx() * self.as_inner().nx()
+ operand.e2epem() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Circle<T>>> for Line<T> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
operand.as_inner().w() * self.d() * self.d()
+ operand.as_inner().w() * self.nx() * self.nx()
+ operand.as_inner().w() * self.ny() * self.ny(),
-(operand.as_inner().e12em() * self.nx() * self.nx())
+ -T::TWO * operand.as_inner().e1epem() * self.nx() * self.ny()
+ -T::TWO * operand.as_inner().e2epem() * self.d() * self.nx()
+ operand.as_inner().e12em() * self.d() * self.d()
+ operand.as_inner().e12em() * self.ny() * self.ny(),
-(operand.as_inner().e1epem() * self.ny() * self.ny())
+ -T::TWO * operand.as_inner().e12em() * self.nx() * self.ny()
+ -T::TWO * operand.as_inner().e2epem() * self.d() * self.ny()
+ operand.as_inner().e1epem() * self.d() * self.d()
+ operand.as_inner().e1epem() * self.nx() * self.nx(),
-(operand.as_inner().e2epem() * self.d() * self.d())
+ -T::TWO * operand.as_inner().e12em() * self.d() * self.nx()
+ -T::TWO * operand.as_inner().e1epem() * self.d() * self.ny()
+ operand.as_inner().e2epem() * self.nx() * self.nx()
+ operand.as_inner().e2epem() * self.ny() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Circle<T>>> for Unit<Line<T>> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
operand.as_inner().w() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().w() * self.as_inner().nx() * self.as_inner().nx()
+ operand.as_inner().w() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().e12em() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().nx()
* self.as_inner().ny()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().d()
* self.as_inner().nx()
+ operand.as_inner().e12em() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().e12em() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().e1epem() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().nx()
* self.as_inner().ny()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().d()
* self.as_inner().ny()
+ operand.as_inner().e1epem() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().e1epem() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.as_inner().e2epem() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.as_inner().e12em() * self.as_inner().d() * self.as_inner().nx()
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().d()
* self.as_inner().ny()
+ operand.as_inner().e2epem() * self.as_inner().nx() * self.as_inner().nx()
+ operand.as_inner().e2epem() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[doc = "Sandwich product: [`Line`] x [`FlatPoint`] x rev([`Line`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<FlatPoint<T>> for Line<T> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
self.d() * operand.e1em() * self.d() - self.d() * operand.e2em() * self.ny()
+ self.d() * operand.epem() * self.nx()
- self.nx() * operand.e1em() * self.nx()
+ self.nx() * operand.epem() * self.d()
- self.ny() * operand.e1em() * self.ny()
- self.ny() * operand.e2em() * self.d(),
-(self.d() * operand.e1em() * self.ny())
- self.d() * operand.e2em() * self.d()
- self.nx() * operand.e2em() * self.nx()
- self.nx() * operand.epem() * self.ny()
- self.ny() * operand.e1em() * self.d()
+ self.ny() * operand.e2em() * self.ny()
- self.ny() * operand.epem() * self.nx(),
self.d() * operand.e1em() * self.nx() - self.d() * operand.epem() * self.d()
+ self.nx() * operand.e1em() * self.d()
- self.nx() * operand.e2em() * self.ny()
+ self.nx() * operand.epem() * self.nx()
- self.ny() * operand.e2em() * self.nx()
- self.ny() * operand.epem() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<FlatPoint<T>> for Unit<Line<T>> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.e1em() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.e1em() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.e2em() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.epem() * self.as_inner().d() * self.as_inner().nx()
+ operand.e1em() * self.as_inner().d() * self.as_inner().d(),
-(operand.e2em() * self.as_inner().d() * self.as_inner().d())
+ -(operand.e2em() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.e1em() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.epem() * self.as_inner().nx() * self.as_inner().ny()
+ operand.e2em() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.epem() * self.as_inner().d() * self.as_inner().d())
+ -(operand.epem() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.e2em() * self.as_inner().nx() * self.as_inner().ny()
+ T::TWO * operand.e1em() * self.as_inner().d() * self.as_inner().nx()
+ operand.epem() * self.as_inner().nx() * self.as_inner().nx(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<FlatPoint<T>>> for Line<T> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.nx() * self.nx())
+ -(operand.as_inner().e1em() * self.ny() * self.ny())
+ -T::TWO * operand.as_inner().e2em() * self.d() * self.ny()
+ T::TWO * operand.as_inner().epem() * self.d() * self.nx()
+ operand.as_inner().e1em() * self.d() * self.d(),
-(operand.as_inner().e2em() * self.d() * self.d())
+ -(operand.as_inner().e2em() * self.nx() * self.nx())
+ -T::TWO * operand.as_inner().e1em() * self.d() * self.ny()
+ -T::TWO * operand.as_inner().epem() * self.nx() * self.ny()
+ operand.as_inner().e2em() * self.ny() * self.ny(),
-(operand.as_inner().epem() * self.d() * self.d())
+ -(operand.as_inner().epem() * self.ny() * self.ny())
+ -T::TWO * operand.as_inner().e2em() * self.nx() * self.ny()
+ T::TWO * operand.as_inner().e1em() * self.d() * self.nx()
+ operand.as_inner().epem() * self.nx() * self.nx(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<FlatPoint<T>>> for Unit<Line<T>> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.as_inner().e1em() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.as_inner().epem() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().d(),
-(operand.as_inner().e2em() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().e2em() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.as_inner().epem() * self.as_inner().nx() * self.as_inner().ny()
+ operand.as_inner().e2em() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().epem() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().epem() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().nx() * self.as_inner().ny()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().epem() * self.as_inner().nx() * self.as_inner().nx(),
)
}
}
#[doc = "Sandwich product: [`Line`] x [`Line`] x rev([`Line`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Line<T>> for Line<T> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(self.d() * operand.d() * self.nx()) + self.d() * operand.nx() * self.d()
- self.nx() * operand.d() * self.d()
- self.nx() * operand.nx() * self.nx()
- self.nx() * operand.ny() * self.ny()
+ self.ny() * operand.nx() * self.ny()
- self.ny() * operand.ny() * self.nx(),
-(self.d() * operand.d() * self.ny()) + self.d() * operand.ny() * self.d()
- self.nx() * operand.nx() * self.ny()
+ self.nx() * operand.ny() * self.nx()
- self.ny() * operand.d() * self.d()
- self.ny() * operand.nx() * self.nx()
- self.ny() * operand.ny() * self.ny(),
-(self.d() * operand.d() * self.d())
- self.d() * operand.nx() * self.nx()
- self.d() * operand.ny() * self.ny()
+ self.nx() * operand.d() * self.nx()
- self.nx() * operand.nx() * self.d()
+ self.ny() * operand.d() * self.ny()
- self.ny() * operand.ny() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Line<T>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(operand.nx() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.d() * self.as_inner().d() * self.as_inner().nx()
+ -T::TWO * operand.ny() * self.as_inner().nx() * self.as_inner().ny()
+ operand.nx() * self.as_inner().d() * self.as_inner().d()
+ operand.nx() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.ny() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.d() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.nx() * self.as_inner().nx() * self.as_inner().ny()
+ operand.ny() * self.as_inner().d() * self.as_inner().d()
+ operand.ny() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.d() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.nx() * self.as_inner().d() * self.as_inner().nx()
+ -T::TWO * operand.ny() * self.as_inner().d() * self.as_inner().ny()
+ operand.d() * self.as_inner().nx() * self.as_inner().nx()
+ operand.d() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Line<T>>> for Line<T> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.nx() * self.nx())
+ -T::TWO * operand.as_inner().d() * self.d() * self.nx()
+ -T::TWO * operand.as_inner().ny() * self.nx() * self.ny()
+ operand.as_inner().nx() * self.d() * self.d()
+ operand.as_inner().nx() * self.ny() * self.ny(),
-(operand.as_inner().ny() * self.ny() * self.ny())
+ -T::TWO * operand.as_inner().d() * self.d() * self.ny()
+ -T::TWO * operand.as_inner().nx() * self.nx() * self.ny()
+ operand.as_inner().ny() * self.d() * self.d()
+ operand.as_inner().ny() * self.nx() * self.nx(),
-(operand.as_inner().d() * self.d() * self.d())
+ -T::TWO * operand.as_inner().nx() * self.d() * self.nx()
+ -T::TWO * operand.as_inner().ny() * self.d() * self.ny()
+ operand.as_inner().d() * self.nx() * self.nx()
+ operand.as_inner().d() * self.ny() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Line<T>>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.as_inner().d() * self.as_inner().d() * self.as_inner().nx()
+ -T::TWO * operand.as_inner().ny() * self.as_inner().nx() * self.as_inner().ny()
+ operand.as_inner().nx() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().nx() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().ny() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.as_inner().d() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.as_inner().nx() * self.as_inner().nx() * self.as_inner().ny()
+ operand.as_inner().ny() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().ny() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.as_inner().d() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.as_inner().nx() * self.as_inner().d() * self.as_inner().nx()
+ -T::TWO * operand.as_inner().ny() * self.as_inner().d() * self.as_inner().ny()
+ operand.as_inner().d() * self.as_inner().nx() * self.as_inner().nx()
+ operand.as_inner().d() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[doc = "Sandwich product: [`Line`] x [`Motor`] x rev([`Line`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Motor<T>> for Line<T> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(self.d() * operand.e1ep() * self.nx()) + self.d() * operand.m() * self.ny()
- self.d() * operand.s() * self.d()
+ self.nx() * operand.e1ep() * self.d()
- self.nx() * operand.e2ep() * self.ny()
- self.nx() * operand.s() * self.nx()
+ self.ny() * operand.e2ep() * self.nx()
- self.ny() * operand.m() * self.d()
- self.ny() * operand.s() * self.ny(),
-(self.d() * operand.e2ep() * self.nx())
+ self.d() * operand.m() * self.d()
+ self.d() * operand.s() * self.ny()
- self.nx() * operand.e1ep() * self.ny()
- self.nx() * operand.e2ep() * self.d()
- self.nx() * operand.m() * self.nx()
- self.ny() * operand.e1ep() * self.nx()
+ self.ny() * operand.m() * self.ny()
- self.ny() * operand.s() * self.d(),
self.d() * operand.e1ep() * self.d()
- self.d() * operand.e2ep() * self.ny()
- self.d() * operand.s() * self.nx()
+ self.nx() * operand.e1ep() * self.nx()
- self.nx() * operand.m() * self.ny()
+ self.nx() * operand.s() * self.d()
- self.ny() * operand.e1ep() * self.ny()
- self.ny() * operand.e2ep() * self.d()
- self.ny() * operand.m() * self.nx(),
-(self.d() * operand.e1ep() * self.ny())
- self.d() * operand.e2ep() * self.d()
- self.d() * operand.m() * self.nx()
+ self.nx() * operand.e2ep() * self.nx()
- self.nx() * operand.m() * self.d()
- self.nx() * operand.s() * self.ny()
- self.ny() * operand.e1ep() * self.d()
+ self.ny() * operand.e2ep() * self.ny()
+ self.ny() * operand.s() * self.nx(),
self.d() * operand.e1em() * self.d() - self.d() * operand.e2em() * self.ny()
+ self.d() * operand.epem() * self.nx()
- self.nx() * operand.e1em() * self.nx()
+ self.nx() * operand.epem() * self.d()
- self.nx() * operand.ps() * self.ny()
- self.ny() * operand.e1em() * self.ny()
- self.ny() * operand.e2em() * self.d()
+ self.ny() * operand.ps() * self.nx(),
-(self.d() * operand.e1em() * self.ny()) - self.d() * operand.e2em() * self.d()
+ self.d() * operand.ps() * self.nx()
- self.nx() * operand.e2em() * self.nx()
- self.nx() * operand.epem() * self.ny()
- self.nx() * operand.ps() * self.d()
- self.ny() * operand.e1em() * self.d()
+ self.ny() * operand.e2em() * self.ny()
- self.ny() * operand.epem() * self.nx(),
self.d() * operand.e1em() * self.nx() - self.d() * operand.epem() * self.d()
+ self.d() * operand.ps() * self.ny()
+ self.nx() * operand.e1em() * self.d()
- self.nx() * operand.e2em() * self.ny()
+ self.nx() * operand.epem() * self.nx()
- self.ny() * operand.e2em() * self.nx()
- self.ny() * operand.epem() * self.ny()
- self.ny() * operand.ps() * self.d(),
self.d() * operand.e2em() * self.nx()
+ self.d() * operand.epem() * self.ny()
+ self.d() * operand.ps() * self.d()
- self.nx() * operand.e1em() * self.ny()
- self.nx() * operand.e2em() * self.d()
+ self.nx() * operand.ps() * self.nx()
+ self.ny() * operand.e1em() * self.nx()
- self.ny() * operand.epem() * self.d()
+ self.ny() * operand.ps() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Motor<T>> for Unit<Line<T>> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(operand.s() * self.as_inner().d() * self.as_inner().d())
+ -(operand.s() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.s() * self.as_inner().ny() * self.as_inner().ny()),
-(operand.m() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.e1ep() * self.as_inner().nx() * self.as_inner().ny()
+ -T::TWO * operand.e2ep() * self.as_inner().d() * self.as_inner().nx()
+ operand.m() * self.as_inner().d() * self.as_inner().d()
+ operand.m() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.e1ep() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.e2ep() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.m() * self.as_inner().nx() * self.as_inner().ny()
+ operand.e1ep() * self.as_inner().d() * self.as_inner().d()
+ operand.e1ep() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.e2ep() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.e1ep() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.m() * self.as_inner().d() * self.as_inner().nx()
+ operand.e2ep() * self.as_inner().nx() * self.as_inner().nx()
+ operand.e2ep() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.e1em() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.e1em() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.e2em() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.epem() * self.as_inner().d() * self.as_inner().nx()
+ operand.e1em() * self.as_inner().d() * self.as_inner().d(),
-(operand.e2em() * self.as_inner().d() * self.as_inner().d())
+ -(operand.e2em() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.e1em() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.epem() * self.as_inner().nx() * self.as_inner().ny()
+ operand.e2em() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.epem() * self.as_inner().d() * self.as_inner().d())
+ -(operand.epem() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.e2em() * self.as_inner().nx() * self.as_inner().ny()
+ T::TWO * operand.e1em() * self.as_inner().d() * self.as_inner().nx()
+ operand.epem() * self.as_inner().nx() * self.as_inner().nx(),
operand.ps() * self.as_inner().d() * self.as_inner().d()
+ operand.ps() * self.as_inner().nx() * self.as_inner().nx()
+ operand.ps() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Motor<T>>> for Line<T> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.d() * self.d())
+ -(operand.as_inner().s() * self.nx() * self.nx())
+ -(operand.as_inner().s() * self.ny() * self.ny()),
-(operand.as_inner().m() * self.nx() * self.nx())
+ -T::TWO * operand.as_inner().e1ep() * self.nx() * self.ny()
+ -T::TWO * operand.as_inner().e2ep() * self.d() * self.nx()
+ operand.as_inner().m() * self.d() * self.d()
+ operand.as_inner().m() * self.ny() * self.ny(),
-(operand.as_inner().e1ep() * self.ny() * self.ny())
+ -T::TWO * operand.as_inner().e2ep() * self.d() * self.ny()
+ -T::TWO * operand.as_inner().m() * self.nx() * self.ny()
+ operand.as_inner().e1ep() * self.d() * self.d()
+ operand.as_inner().e1ep() * self.nx() * self.nx(),
-(operand.as_inner().e2ep() * self.d() * self.d())
+ -T::TWO * operand.as_inner().e1ep() * self.d() * self.ny()
+ -T::TWO * operand.as_inner().m() * self.d() * self.nx()
+ operand.as_inner().e2ep() * self.nx() * self.nx()
+ operand.as_inner().e2ep() * self.ny() * self.ny(),
-(operand.as_inner().e1em() * self.nx() * self.nx())
+ -(operand.as_inner().e1em() * self.ny() * self.ny())
+ -T::TWO * operand.as_inner().e2em() * self.d() * self.ny()
+ T::TWO * operand.as_inner().epem() * self.d() * self.nx()
+ operand.as_inner().e1em() * self.d() * self.d(),
-(operand.as_inner().e2em() * self.d() * self.d())
+ -(operand.as_inner().e2em() * self.nx() * self.nx())
+ -T::TWO * operand.as_inner().e1em() * self.d() * self.ny()
+ -T::TWO * operand.as_inner().epem() * self.nx() * self.ny()
+ operand.as_inner().e2em() * self.ny() * self.ny(),
-(operand.as_inner().epem() * self.d() * self.d())
+ -(operand.as_inner().epem() * self.ny() * self.ny())
+ -T::TWO * operand.as_inner().e2em() * self.nx() * self.ny()
+ T::TWO * operand.as_inner().e1em() * self.d() * self.nx()
+ operand.as_inner().epem() * self.nx() * self.nx(),
operand.as_inner().ps() * self.d() * self.d()
+ operand.as_inner().ps() * self.nx() * self.nx()
+ operand.as_inner().ps() * self.ny() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Motor<T>>> for Unit<Line<T>> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().s() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.as_inner().s() * self.as_inner().ny() * self.as_inner().ny()),
-(operand.as_inner().m() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().nx() * self.as_inner().ny()
+ -T::TWO * operand.as_inner().e2ep() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().m() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().m() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().e1ep() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.as_inner().e2ep() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.as_inner().m() * self.as_inner().nx() * self.as_inner().ny()
+ operand.as_inner().e1ep() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().e1ep() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.as_inner().e2ep() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.as_inner().m() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().e2ep() * self.as_inner().nx() * self.as_inner().nx()
+ operand.as_inner().e2ep() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().e1em() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.as_inner().e1em() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.as_inner().epem() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().d(),
-(operand.as_inner().e2em() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().e2em() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.as_inner().epem() * self.as_inner().nx() * self.as_inner().ny()
+ operand.as_inner().e2em() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().epem() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().epem() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().nx() * self.as_inner().ny()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().epem() * self.as_inner().nx() * self.as_inner().nx(),
operand.as_inner().ps() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().ps() * self.as_inner().nx() * self.as_inner().nx()
+ operand.as_inner().ps() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[doc = "Sandwich product: [`Line`] x [`PointPair`] x rev([`Line`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<PointPair<T>> for Line<T> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(self.d() * operand.e2ep() * self.nx()) + self.d() * operand.m() * self.d()
- self.nx() * operand.e1ep() * self.ny()
- self.nx() * operand.e2ep() * self.d()
- self.nx() * operand.m() * self.nx()
- self.ny() * operand.e1ep() * self.nx()
+ self.ny() * operand.m() * self.ny(),
self.d() * operand.e1ep() * self.d() - self.d() * operand.e2ep() * self.ny()
+ self.nx() * operand.e1ep() * self.nx()
- self.nx() * operand.m() * self.ny()
- self.ny() * operand.e1ep() * self.ny()
- self.ny() * operand.e2ep() * self.d()
- self.ny() * operand.m() * self.nx(),
-(self.d() * operand.e1ep() * self.ny())
- self.d() * operand.e2ep() * self.d()
- self.d() * operand.m() * self.nx()
+ self.nx() * operand.e2ep() * self.nx()
- self.nx() * operand.m() * self.d()
- self.ny() * operand.e1ep() * self.d()
+ self.ny() * operand.e2ep() * self.ny(),
self.d() * operand.e1em() * self.d() - self.d() * operand.e2em() * self.ny()
+ self.d() * operand.epem() * self.nx()
- self.nx() * operand.e1em() * self.nx()
+ self.nx() * operand.epem() * self.d()
- self.ny() * operand.e1em() * self.ny()
- self.ny() * operand.e2em() * self.d(),
-(self.d() * operand.e1em() * self.ny())
- self.d() * operand.e2em() * self.d()
- self.nx() * operand.e2em() * self.nx()
- self.nx() * operand.epem() * self.ny()
- self.ny() * operand.e1em() * self.d()
+ self.ny() * operand.e2em() * self.ny()
- self.ny() * operand.epem() * self.nx(),
self.d() * operand.e1em() * self.nx() - self.d() * operand.epem() * self.d()
+ self.nx() * operand.e1em() * self.d()
- self.nx() * operand.e2em() * self.ny()
+ self.nx() * operand.epem() * self.nx()
- self.ny() * operand.e2em() * self.nx()
- self.ny() * operand.epem() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<PointPair<T>> for Unit<Line<T>> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.m() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.e1ep() * self.as_inner().nx() * self.as_inner().ny()
+ -T::TWO * operand.e2ep() * self.as_inner().d() * self.as_inner().nx()
+ operand.m() * self.as_inner().d() * self.as_inner().d()
+ operand.m() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.e1ep() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.e2ep() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.m() * self.as_inner().nx() * self.as_inner().ny()
+ operand.e1ep() * self.as_inner().d() * self.as_inner().d()
+ operand.e1ep() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.e2ep() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.e1ep() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.m() * self.as_inner().d() * self.as_inner().nx()
+ operand.e2ep() * self.as_inner().nx() * self.as_inner().nx()
+ operand.e2ep() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.e1em() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.e1em() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.e2em() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.epem() * self.as_inner().d() * self.as_inner().nx()
+ operand.e1em() * self.as_inner().d() * self.as_inner().d(),
-(operand.e2em() * self.as_inner().d() * self.as_inner().d())
+ -(operand.e2em() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.e1em() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.epem() * self.as_inner().nx() * self.as_inner().ny()
+ operand.e2em() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.epem() * self.as_inner().d() * self.as_inner().d())
+ -(operand.epem() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.e2em() * self.as_inner().nx() * self.as_inner().ny()
+ T::TWO * operand.e1em() * self.as_inner().d() * self.as_inner().nx()
+ operand.epem() * self.as_inner().nx() * self.as_inner().nx(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<PointPair<T>>> for Line<T> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.nx() * self.nx())
+ -T::TWO * operand.as_inner().e1ep() * self.nx() * self.ny()
+ -T::TWO * operand.as_inner().e2ep() * self.d() * self.nx()
+ operand.as_inner().m() * self.d() * self.d()
+ operand.as_inner().m() * self.ny() * self.ny(),
-(operand.as_inner().e1ep() * self.ny() * self.ny())
+ -T::TWO * operand.as_inner().e2ep() * self.d() * self.ny()
+ -T::TWO * operand.as_inner().m() * self.nx() * self.ny()
+ operand.as_inner().e1ep() * self.d() * self.d()
+ operand.as_inner().e1ep() * self.nx() * self.nx(),
-(operand.as_inner().e2ep() * self.d() * self.d())
+ -T::TWO * operand.as_inner().e1ep() * self.d() * self.ny()
+ -T::TWO * operand.as_inner().m() * self.d() * self.nx()
+ operand.as_inner().e2ep() * self.nx() * self.nx()
+ operand.as_inner().e2ep() * self.ny() * self.ny(),
-(operand.as_inner().e1em() * self.nx() * self.nx())
+ -(operand.as_inner().e1em() * self.ny() * self.ny())
+ -T::TWO * operand.as_inner().e2em() * self.d() * self.ny()
+ T::TWO * operand.as_inner().epem() * self.d() * self.nx()
+ operand.as_inner().e1em() * self.d() * self.d(),
-(operand.as_inner().e2em() * self.d() * self.d())
+ -(operand.as_inner().e2em() * self.nx() * self.nx())
+ -T::TWO * operand.as_inner().e1em() * self.d() * self.ny()
+ -T::TWO * operand.as_inner().epem() * self.nx() * self.ny()
+ operand.as_inner().e2em() * self.ny() * self.ny(),
-(operand.as_inner().epem() * self.d() * self.d())
+ -(operand.as_inner().epem() * self.ny() * self.ny())
+ -T::TWO * operand.as_inner().e2em() * self.nx() * self.ny()
+ T::TWO * operand.as_inner().e1em() * self.d() * self.nx()
+ operand.as_inner().epem() * self.nx() * self.nx(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<PointPair<T>>> for Unit<Line<T>> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().nx() * self.as_inner().ny()
+ -T::TWO * operand.as_inner().e2ep() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().m() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().m() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().e1ep() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.as_inner().e2ep() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.as_inner().m() * self.as_inner().nx() * self.as_inner().ny()
+ operand.as_inner().e1ep() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().e1ep() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.as_inner().e2ep() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.as_inner().m() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().e2ep() * self.as_inner().nx() * self.as_inner().nx()
+ operand.as_inner().e2ep() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().e1em() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.as_inner().e1em() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.as_inner().epem() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().d(),
-(operand.as_inner().e2em() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().e2em() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.as_inner().epem() * self.as_inner().nx() * self.as_inner().ny()
+ operand.as_inner().e2em() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().epem() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().epem() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().nx() * self.as_inner().ny()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().epem() * self.as_inner().nx() * self.as_inner().nx(),
)
}
}
#[doc = "Sandwich product: [`Line`] x [`Pseudoscalar`] x rev([`Line`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Pseudoscalar<T>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
self.d() * operand.ps() * self.d()
+ self.nx() * operand.ps() * self.nx()
+ self.ny() * operand.ps() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Pseudoscalar<T>> for Unit<Line<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
operand.ps() * self.as_inner().d() * self.as_inner().d()
+ operand.ps() * self.as_inner().nx() * self.as_inner().nx()
+ operand.ps() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Pseudoscalar<T>>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
operand.as_inner().ps() * self.d() * self.d()
+ operand.as_inner().ps() * self.nx() * self.nx()
+ operand.as_inner().ps() * self.ny() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Pseudoscalar<T>>> for Unit<Line<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
operand.as_inner().ps() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().ps() * self.as_inner().nx() * self.as_inner().nx()
+ operand.as_inner().ps() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[doc = "Sandwich product: [`Line`] x [`RoundPoint`] x rev([`Line`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<RoundPoint<T>> for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
self.d() * operand.ep() * self.nx() + self.d() * operand.x() * self.d()
- self.d() * operand.y() * self.ny()
+ self.nx() * operand.ep() * self.d()
- self.nx() * operand.x() * self.nx()
- self.ny() * operand.x() * self.ny()
- self.ny() * operand.y() * self.d(),
-(self.d() * operand.x() * self.ny())
- self.d() * operand.y() * self.d()
- self.nx() * operand.ep() * self.ny()
- self.nx() * operand.y() * self.nx()
- self.ny() * operand.ep() * self.nx()
- self.ny() * operand.x() * self.d()
+ self.ny() * operand.y() * self.ny(),
-(self.d() * operand.ep() * self.d())
+ self.d() * operand.x() * self.nx()
+ self.nx() * operand.ep() * self.nx()
+ self.nx() * operand.x() * self.d()
- self.nx() * operand.y() * self.ny()
- self.ny() * operand.ep() * self.ny()
- self.ny() * operand.y() * self.nx(),
-(self.d() * operand.em() * self.d())
- self.nx() * operand.em() * self.nx()
- self.ny() * operand.em() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<RoundPoint<T>> for Unit<Line<T>> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.x() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.x() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.y() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.ep() * self.as_inner().d() * self.as_inner().nx()
+ operand.x() * self.as_inner().d() * self.as_inner().d(),
-(operand.y() * self.as_inner().d() * self.as_inner().d())
+ -(operand.y() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.ep() * self.as_inner().nx() * self.as_inner().ny()
+ -T::TWO * operand.x() * self.as_inner().d() * self.as_inner().ny()
+ operand.y() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.ep() * self.as_inner().d() * self.as_inner().d())
+ -(operand.ep() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.y() * self.as_inner().nx() * self.as_inner().ny()
+ T::TWO * operand.x() * self.as_inner().d() * self.as_inner().nx()
+ operand.ep() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.em() * self.as_inner().d() * self.as_inner().d())
+ -(operand.em() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.em() * self.as_inner().ny() * self.as_inner().ny()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<RoundPoint<T>>> for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.nx() * self.nx())
+ -(operand.as_inner().x() * self.ny() * self.ny())
+ -T::TWO * operand.as_inner().y() * self.d() * self.ny()
+ T::TWO * operand.as_inner().ep() * self.d() * self.nx()
+ operand.as_inner().x() * self.d() * self.d(),
-(operand.as_inner().y() * self.d() * self.d())
+ -(operand.as_inner().y() * self.nx() * self.nx())
+ -T::TWO * operand.as_inner().ep() * self.nx() * self.ny()
+ -T::TWO * operand.as_inner().x() * self.d() * self.ny()
+ operand.as_inner().y() * self.ny() * self.ny(),
-(operand.as_inner().ep() * self.d() * self.d())
+ -(operand.as_inner().ep() * self.ny() * self.ny())
+ -T::TWO * operand.as_inner().y() * self.nx() * self.ny()
+ T::TWO * operand.as_inner().x() * self.d() * self.nx()
+ operand.as_inner().ep() * self.nx() * self.nx(),
-(operand.as_inner().em() * self.d() * self.d())
+ -(operand.as_inner().em() * self.nx() * self.nx())
+ -(operand.as_inner().em() * self.ny() * self.ny()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<RoundPoint<T>>> for Unit<Line<T>> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.as_inner().x() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.as_inner().y() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.as_inner().ep() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().x() * self.as_inner().d() * self.as_inner().d(),
-(operand.as_inner().y() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().y() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.as_inner().ep() * self.as_inner().nx() * self.as_inner().ny()
+ -T::TWO * operand.as_inner().x() * self.as_inner().d() * self.as_inner().ny()
+ operand.as_inner().y() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().ep() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().ep() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.as_inner().y() * self.as_inner().nx() * self.as_inner().ny()
+ T::TWO * operand.as_inner().x() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().ep() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.as_inner().em() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().em() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.as_inner().em() * self.as_inner().ny() * self.as_inner().ny()),
)
}
}
#[doc = "Sandwich product: [`Line`] x [`Scalar`] x rev([`Line`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Scalar<T>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(self.d() * operand.s() * self.d())
- self.nx() * operand.s() * self.nx()
- self.ny() * operand.s() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Scalar<T>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.s() * self.as_inner().d() * self.as_inner().d())
+ -(operand.s() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.s() * self.as_inner().ny() * self.as_inner().ny()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Scalar<T>>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.d() * self.d())
+ -(operand.as_inner().s() * self.nx() * self.nx())
+ -(operand.as_inner().s() * self.ny() * self.ny()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Scalar<T>>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().s() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.as_inner().s() * self.as_inner().ny() * self.as_inner().ny()),
)
}
}
#[doc = "Sandwich product: [`Motor`] x [`Circle`] x rev([`Motor`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Circle<T>> for Motor<T> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-(self.e1em() * operand.e12em() * self.e1ep())
+ self.e1em() * operand.e1epem() * self.m()
- self.e1em() * operand.e2epem() * self.s()
+ self.e1em() * operand.w() * self.e1em()
- self.e1ep() * operand.e12em() * self.e1em()
- self.e1ep() * operand.e1epem() * self.ps()
+ self.e1ep() * operand.e2epem() * self.epem()
+ self.e1ep() * operand.w() * self.e1ep()
- self.e2em() * operand.e12em() * self.e2ep()
+ self.e2em() * operand.e1epem() * self.s()
+ self.e2em() * operand.e2epem() * self.m()
+ self.e2em() * operand.w() * self.e2em()
- self.e2ep() * operand.e12em() * self.e2em()
- self.e2ep() * operand.e1epem() * self.epem()
- self.e2ep() * operand.e2epem() * self.ps()
+ self.e2ep() * operand.w() * self.e2ep()
- self.epem() * operand.e12em() * self.s()
- self.epem() * operand.e1epem() * self.e2ep()
+ self.epem() * operand.e2epem() * self.e1ep()
+ self.epem() * operand.w() * self.epem()
- self.m() * operand.e12em() * self.ps()
+ self.m() * operand.e1epem() * self.e1em()
+ self.m() * operand.e2epem() * self.e2em()
+ self.m() * operand.w() * self.m()
- self.ps() * operand.e12em() * self.m()
- self.ps() * operand.e1epem() * self.e1ep()
- self.ps() * operand.e2epem() * self.e2ep()
+ self.ps() * operand.w() * self.ps()
- self.s() * operand.e12em() * self.epem()
+ self.s() * operand.e1epem() * self.e2em()
- self.s() * operand.e2epem() * self.e1em()
+ self.s() * operand.w() * self.s(),
-(self.e1em() * operand.e12em() * self.e1em())
- self.e1em() * operand.e1epem() * self.ps()
+ self.e1em() * operand.e2epem() * self.epem()
+ self.e1em() * operand.w() * self.e1ep()
- self.e1ep() * operand.e12em() * self.e1ep()
+ self.e1ep() * operand.e1epem() * self.m()
- self.e1ep() * operand.e2epem() * self.s()
+ self.e1ep() * operand.w() * self.e1em()
- self.e2em() * operand.e12em() * self.e2em()
- self.e2em() * operand.e1epem() * self.epem()
- self.e2em() * operand.e2epem() * self.ps()
+ self.e2em() * operand.w() * self.e2ep()
- self.e2ep() * operand.e12em() * self.e2ep()
+ self.e2ep() * operand.e1epem() * self.s()
+ self.e2ep() * operand.e2epem() * self.m()
+ self.e2ep() * operand.w() * self.e2em()
+ self.epem() * operand.e12em() * self.epem()
- self.epem() * operand.e1epem() * self.e2em()
+ self.epem() * operand.e2epem() * self.e1em()
- self.epem() * operand.w() * self.s()
+ self.m() * operand.e12em() * self.m()
+ self.m() * operand.e1epem() * self.e1ep()
+ self.m() * operand.e2epem() * self.e2ep()
- self.m() * operand.w() * self.ps()
+ self.ps() * operand.e12em() * self.ps()
- self.ps() * operand.e1epem() * self.e1em()
- self.ps() * operand.e2epem() * self.e2em()
- self.ps() * operand.w() * self.m()
+ self.s() * operand.e12em() * self.s()
+ self.s() * operand.e1epem() * self.e2ep()
- self.s() * operand.e2epem() * self.e1ep()
- self.s() * operand.w() * self.epem(),
self.e1em() * operand.e12em() * self.ps()
- self.e1em() * operand.e1epem() * self.e1em()
- self.e1em() * operand.e2epem() * self.e2em()
- self.e1em() * operand.w() * self.m()
+ self.e1ep() * operand.e12em() * self.m()
+ self.e1ep() * operand.e1epem() * self.e1ep()
+ self.e1ep() * operand.e2epem() * self.e2ep()
- self.e1ep() * operand.w() * self.ps()
- self.e2em() * operand.e12em() * self.epem()
+ self.e2em() * operand.e1epem() * self.e2em()
- self.e2em() * operand.e2epem() * self.e1em()
+ self.e2em() * operand.w() * self.s()
- self.e2ep() * operand.e12em() * self.s()
- self.e2ep() * operand.e1epem() * self.e2ep()
+ self.e2ep() * operand.e2epem() * self.e1ep()
+ self.e2ep() * operand.w() * self.epem()
- self.epem() * operand.e12em() * self.e2em()
- self.epem() * operand.e1epem() * self.epem()
- self.epem() * operand.e2epem() * self.ps()
+ self.epem() * operand.w() * self.e2ep()
+ self.m() * operand.e12em() * self.e1ep()
- self.m() * operand.e1epem() * self.m()
+ self.m() * operand.e2epem() * self.s()
- self.m() * operand.w() * self.e1em()
+ self.ps() * operand.e12em() * self.e1em()
+ self.ps() * operand.e1epem() * self.ps()
- self.ps() * operand.e2epem() * self.epem()
- self.ps() * operand.w() * self.e1ep()
- self.s() * operand.e12em() * self.e2ep()
+ self.s() * operand.e1epem() * self.s()
+ self.s() * operand.e2epem() * self.m()
+ self.s() * operand.w() * self.e2em(),
self.e1em() * operand.e12em() * self.epem()
- self.e1em() * operand.e1epem() * self.e2em()
+ self.e1em() * operand.e2epem() * self.e1em()
- self.e1em() * operand.w() * self.s()
+ self.e1ep() * operand.e12em() * self.s()
+ self.e1ep() * operand.e1epem() * self.e2ep()
- self.e1ep() * operand.e2epem() * self.e1ep()
- self.e1ep() * operand.w() * self.epem()
+ self.e2em() * operand.e12em() * self.ps()
- self.e2em() * operand.e1epem() * self.e1em()
- self.e2em() * operand.e2epem() * self.e2em()
- self.e2em() * operand.w() * self.m()
+ self.e2ep() * operand.e12em() * self.m()
+ self.e2ep() * operand.e1epem() * self.e1ep()
+ self.e2ep() * operand.e2epem() * self.e2ep()
- self.e2ep() * operand.w() * self.ps()
+ self.epem() * operand.e12em() * self.e1em()
+ self.epem() * operand.e1epem() * self.ps()
- self.epem() * operand.e2epem() * self.epem()
- self.epem() * operand.w() * self.e1ep()
+ self.m() * operand.e12em() * self.e2ep()
- self.m() * operand.e1epem() * self.s()
- self.m() * operand.e2epem() * self.m()
- self.m() * operand.w() * self.e2em()
+ self.ps() * operand.e12em() * self.e2em()
+ self.ps() * operand.e1epem() * self.epem()
+ self.ps() * operand.e2epem() * self.ps()
- self.ps() * operand.w() * self.e2ep()
+ self.s() * operand.e12em() * self.e1ep()
- self.s() * operand.e1epem() * self.m()
+ self.s() * operand.e2epem() * self.s()
- self.s() * operand.w() * self.e1em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Circle<T>> for Unit<Motor<T>> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.e12em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.e12em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.e12em() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.e12em() * self.as_inner().m() * self.as_inner().ps()
+ -T::TWO * operand.e1epem() * self.as_inner().e1ep() * self.as_inner().ps()
+ -T::TWO * operand.e1epem() * self.as_inner().e2ep() * self.as_inner().epem()
+ -T::TWO * operand.e2epem() * self.as_inner().e1em() * self.as_inner().s()
+ -T::TWO * operand.e2epem() * self.as_inner().e2ep() * self.as_inner().ps()
+ T::TWO * operand.e1epem() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.e1epem() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.e2epem() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.e2epem() * self.as_inner().e2em() * self.as_inner().m()
+ operand.w() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.w() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.w() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.w() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.w() * self.as_inner().epem() * self.as_inner().epem()
+ operand.w() * self.as_inner().m() * self.as_inner().m()
+ operand.w() * self.as_inner().ps() * self.as_inner().ps()
+ operand.w() * self.as_inner().s() * self.as_inner().s(),
-(operand.e12em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e12em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e12em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e12em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO * operand.e1epem() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.e1epem() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.e2epem() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.e2epem() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO * operand.w() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.w() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.e1epem() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e1epem() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.e2epem() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e2epem() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.w() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.w() * self.as_inner().e2em() * self.as_inner().e2ep()
+ operand.e12em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.e12em() * self.as_inner().m() * self.as_inner().m()
+ operand.e12em() * self.as_inner().ps() * self.as_inner().ps()
+ operand.e12em() * self.as_inner().s() * self.as_inner().s(),
-(operand.e1epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e1epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e1epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e12em() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.e12em() * self.as_inner().e2ep() * self.as_inner().s()
+ -T::TWO * operand.e2epem() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e2epem() * self.as_inner().epem() * self.as_inner().ps()
+ -T::TWO * operand.w() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.w() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO * operand.e12em() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.e12em() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e2epem() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e2epem() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.w() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.w() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.e1epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e1epem() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e1epem() * self.as_inner().ps() * self.as_inner().ps()
+ operand.e1epem() * self.as_inner().s() * self.as_inner().s(),
-(operand.e2epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e2epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e2epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e1epem() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e1epem() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO * operand.w() * self.as_inner().e1em() * self.as_inner().s()
+ -T::TWO * operand.w() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.w() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.w() * self.as_inner().e2ep() * self.as_inner().ps()
+ T::TWO * operand.e12em() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e12em() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.e12em() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.e12em() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.e1epem() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e1epem() * self.as_inner().epem() * self.as_inner().ps()
+ operand.e2epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e2epem() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e2epem() * self.as_inner().ps() * self.as_inner().ps()
+ operand.e2epem() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Circle<T>>> for Motor<T> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.as_inner().e12em() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().e12em() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().e12em() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().e12em() * self.m() * self.ps()
+ -T::TWO * operand.as_inner().e1epem() * self.e1ep() * self.ps()
+ -T::TWO * operand.as_inner().e1epem() * self.e2ep() * self.epem()
+ -T::TWO * operand.as_inner().e2epem() * self.e1em() * self.s()
+ -T::TWO * operand.as_inner().e2epem() * self.e2ep() * self.ps()
+ T::TWO * operand.as_inner().e1epem() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().e1epem() * self.e2em() * self.s()
+ T::TWO * operand.as_inner().e2epem() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().e2epem() * self.e2em() * self.m()
+ operand.as_inner().w() * self.e1em() * self.e1em()
+ operand.as_inner().w() * self.e1ep() * self.e1ep()
+ operand.as_inner().w() * self.e2em() * self.e2em()
+ operand.as_inner().w() * self.e2ep() * self.e2ep()
+ operand.as_inner().w() * self.epem() * self.epem()
+ operand.as_inner().w() * self.m() * self.m()
+ operand.as_inner().w() * self.ps() * self.ps()
+ operand.as_inner().w() * self.s() * self.s(),
-(operand.as_inner().e12em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e12em() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e12em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e12em() * self.e2ep() * self.e2ep())
+ -T::TWO * operand.as_inner().e1epem() * self.e1em() * self.ps()
+ -T::TWO * operand.as_inner().e1epem() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().e2epem() * self.e1ep() * self.s()
+ -T::TWO * operand.as_inner().e2epem() * self.e2em() * self.ps()
+ -T::TWO * operand.as_inner().w() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().w() * self.m() * self.ps()
+ T::TWO * operand.as_inner().e1epem() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e1epem() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().e2epem() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e2epem() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().w() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().w() * self.e2em() * self.e2ep()
+ operand.as_inner().e12em() * self.epem() * self.epem()
+ operand.as_inner().e12em() * self.m() * self.m()
+ operand.as_inner().e12em() * self.ps() * self.ps()
+ operand.as_inner().e12em() * self.s() * self.s(),
-(operand.as_inner().e1epem() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1epem() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e1epem() * self.epem() * self.epem())
+ -(operand.as_inner().e1epem() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e12em() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().e12em() * self.e2ep() * self.s()
+ -T::TWO * operand.as_inner().e2epem() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e2epem() * self.epem() * self.ps()
+ -T::TWO * operand.as_inner().w() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().w() * self.e1ep() * self.ps()
+ T::TWO * operand.as_inner().e12em() * self.e1em() * self.ps()
+ T::TWO * operand.as_inner().e12em() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e2epem() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e2epem() * self.m() * self.s()
+ T::TWO * operand.as_inner().w() * self.e2em() * self.s()
+ T::TWO * operand.as_inner().w() * self.e2ep() * self.epem()
+ operand.as_inner().e1epem() * self.e1ep() * self.e1ep()
+ operand.as_inner().e1epem() * self.e2em() * self.e2em()
+ operand.as_inner().e1epem() * self.ps() * self.ps()
+ operand.as_inner().e1epem() * self.s() * self.s(),
-(operand.as_inner().e2epem() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e2epem() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2epem() * self.epem() * self.epem())
+ -(operand.as_inner().e2epem() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e1epem() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e1epem() * self.m() * self.s()
+ -T::TWO * operand.as_inner().w() * self.e1em() * self.s()
+ -T::TWO * operand.as_inner().w() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().w() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().w() * self.e2ep() * self.ps()
+ T::TWO * operand.as_inner().e12em() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e12em() * self.e1ep() * self.s()
+ T::TWO * operand.as_inner().e12em() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().e12em() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().e1epem() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e1epem() * self.epem() * self.ps()
+ operand.as_inner().e2epem() * self.e1em() * self.e1em()
+ operand.as_inner().e2epem() * self.e2ep() * self.e2ep()
+ operand.as_inner().e2epem() * self.ps() * self.ps()
+ operand.as_inner().e2epem() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Circle<T>>> for Unit<Motor<T>> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.as_inner().e12em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().epem()
* self.as_inner().s()
+ -T::TWO * operand.as_inner().e12em() * self.as_inner().m() * self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1ep()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1em()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e2ep()
* self.as_inner().ps()
+ T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1em()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e2em()
* self.as_inner().s()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e2em()
* self.as_inner().m()
+ operand.as_inner().w() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().w() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().w() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().w() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().w() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().w() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().w() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().w() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().e12em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e12em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e12em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e12em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1em()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1ep()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e2em()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().w() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.as_inner().w() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1ep()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e2ep()
* self.as_inner().s()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e2ep()
* self.as_inner().m()
+ T::TWO * operand.as_inner().w() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.as_inner().w() * self.as_inner().e2em() * self.as_inner().e2ep()
+ operand.as_inner().e12em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().e12em() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().e12em() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().e12em() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().e1epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e1epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e1epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2ep()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().epem()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().w() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.as_inner().w() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e1em()
* self.as_inner().ps()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e1ep()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().e2epem() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.as_inner().w() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.as_inner().w() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.as_inner().e1epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e1epem() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e1epem() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().e1epem() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().e2epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e2epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e2epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO * operand.as_inner().e1epem() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO * operand.as_inner().w() * self.as_inner().e1em() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().w()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().w() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.as_inner().w() * self.as_inner().e2ep() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e1ep()
* self.as_inner().s()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2em()
* self.as_inner().ps()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2ep()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e1epem()
* self.as_inner().epem()
* self.as_inner().ps()
+ operand.as_inner().e2epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e2epem() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e2epem() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().e2epem() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Sandwich product: [`Motor`] x [`FlatPoint`] x rev([`Motor`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<FlatPoint<T>> for Motor<T> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(self.e1em() * operand.e1em() * self.e1em())
- self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.epem() * self.epem()
- self.e1ep() * operand.e1em() * self.e1ep()
- self.e1ep() * operand.e2em() * self.e2ep()
+ self.e1ep() * operand.epem() * self.s()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e2em() * self.e1em()
- self.e2em() * operand.epem() * self.ps()
+ self.e2ep() * operand.e1em() * self.e2ep()
- self.e2ep() * operand.e2em() * self.e1ep()
+ self.e2ep() * operand.epem() * self.m()
+ self.epem() * operand.e1em() * self.epem()
+ self.epem() * operand.e2em() * self.ps()
- self.epem() * operand.epem() * self.e1em()
- self.m() * operand.e1em() * self.m()
+ self.m() * operand.e2em() * self.s()
+ self.m() * operand.epem() * self.e2ep()
- self.ps() * operand.e1em() * self.ps()
+ self.ps() * operand.e2em() * self.epem()
- self.ps() * operand.epem() * self.e2em()
+ self.s() * operand.e1em() * self.s()
+ self.s() * operand.e2em() * self.m()
+ self.s() * operand.epem() * self.e1ep(),
-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e2em() * self.e1em()
+ self.e1em() * operand.epem() * self.ps()
- self.e1ep() * operand.e1em() * self.e2ep()
+ self.e1ep() * operand.e2em() * self.e1ep()
- self.e1ep() * operand.epem() * self.m()
- self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.epem() * self.epem()
- self.e2ep() * operand.e1em() * self.e1ep()
- self.e2ep() * operand.e2em() * self.e2ep()
+ self.e2ep() * operand.epem() * self.s()
- self.epem() * operand.e1em() * self.ps()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.epem() * self.e2em()
- self.m() * operand.e1em() * self.s()
- self.m() * operand.e2em() * self.m()
- self.m() * operand.epem() * self.e1ep()
- self.ps() * operand.e1em() * self.epem()
- self.ps() * operand.e2em() * self.ps()
+ self.ps() * operand.epem() * self.e1em()
- self.s() * operand.e1em() * self.m()
+ self.s() * operand.e2em() * self.s()
+ self.s() * operand.epem() * self.e2ep(),
-(self.e1em() * operand.e1em() * self.epem())
- self.e1em() * operand.e2em() * self.ps()
+ self.e1em() * operand.epem() * self.e1em()
- self.e1ep() * operand.e1em() * self.s()
- self.e1ep() * operand.e2em() * self.m()
- self.e1ep() * operand.epem() * self.e1ep()
+ self.e2em() * operand.e1em() * self.ps()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.epem() * self.e2em()
+ self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.e2em() * self.s()
- self.e2ep() * operand.epem() * self.e2ep()
- self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.epem() * self.epem()
+ self.m() * operand.e1em() * self.e2ep()
- self.m() * operand.e2em() * self.e1ep()
+ self.m() * operand.epem() * self.m()
+ self.ps() * operand.e1em() * self.e2em()
- self.ps() * operand.e2em() * self.e1em()
- self.ps() * operand.epem() * self.ps()
- self.s() * operand.e1em() * self.e1ep()
- self.s() * operand.e2em() * self.e2ep()
+ self.s() * operand.epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<FlatPoint<T>> for Unit<Motor<T>> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e1em() * self.as_inner().m() * self.as_inner().m())
+ -(operand.e1em() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO * operand.e2em() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().m()
+ operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e1em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e1em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.e1em() * self.as_inner().s() * self.as_inner().s(),
-(operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e2em() * self.as_inner().m() * self.as_inner().m())
+ -(operand.e2em() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().ps()
+ -T::TWO * operand.e1em() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().s()
+ operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e2em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e2em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.e2em() * self.as_inner().s() * self.as_inner().s(),
-(operand.epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.epem() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.e2em() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ operand.epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.epem() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.epem() * self.as_inner().m() * self.as_inner().m()
+ operand.epem() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<FlatPoint<T>>> for Motor<T> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1em() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e1em() * self.m() * self.m())
+ -(operand.as_inner().e1em() * self.ps() * self.ps())
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().e2em() * self.epem() * self.ps()
+ T::TWO * operand.as_inner().e2em() * self.m() * self.s()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.s()
+ T::TWO * operand.as_inner().epem() * self.e2ep() * self.m()
+ operand.as_inner().e1em() * self.e2em() * self.e2em()
+ operand.as_inner().e1em() * self.e2ep() * self.e2ep()
+ operand.as_inner().e1em() * self.epem() * self.epem()
+ operand.as_inner().e1em() * self.s() * self.s(),
-(operand.as_inner().e2em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2em() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e2em() * self.m() * self.m())
+ -(operand.as_inner().e2em() * self.ps() * self.ps())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().e1em() * self.epem() * self.ps()
+ -T::TWO * operand.as_inner().e1em() * self.m() * self.s()
+ -T::TWO * operand.as_inner().epem() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e2ep() * self.s()
+ operand.as_inner().e2em() * self.e1em() * self.e1em()
+ operand.as_inner().e2em() * self.e1ep() * self.e1ep()
+ operand.as_inner().e2em() * self.epem() * self.epem()
+ operand.as_inner().e2em() * self.s() * self.s(),
-(operand.as_inner().epem() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().epem() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().epem() * self.epem() * self.epem())
+ -(operand.as_inner().epem() * self.ps() * self.ps())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.s()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.ps()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().e2em() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().e1em() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().e1em() * self.e2ep() * self.m()
+ operand.as_inner().epem() * self.e1em() * self.e1em()
+ operand.as_inner().epem() * self.e2em() * self.e2em()
+ operand.as_inner().epem() * self.m() * self.m()
+ operand.as_inner().epem() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<FlatPoint<T>>> for Unit<Motor<T>> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().e1em() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().ps()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().epem()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().m()
+ operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().e1em() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().e2em() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().epem()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().s()
+ operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().e2em() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().epem() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2ep()
* self.as_inner().s()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().epem() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().epem() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Sandwich product: [`Motor`] x [`Line`] x rev([`Motor`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Line<T>> for Motor<T> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
self.e1em() * operand.d() * self.epem()
- self.e1em() * operand.nx() * self.e1em()
- self.e1em() * operand.ny() * self.ps()
- self.e1ep() * operand.d() * self.s()
- self.e1ep() * operand.nx() * self.e1ep()
+ self.e1ep() * operand.ny() * self.m()
- self.e2em() * operand.d() * self.ps()
- self.e2em() * operand.nx() * self.e2em()
- self.e2em() * operand.ny() * self.epem()
+ self.e2ep() * operand.d() * self.m()
- self.e2ep() * operand.nx() * self.e2ep()
+ self.e2ep() * operand.ny() * self.s()
+ self.epem() * operand.d() * self.e1em()
+ self.epem() * operand.nx() * self.epem()
- self.epem() * operand.ny() * self.e2em()
+ self.m() * operand.d() * self.e2ep()
+ self.m() * operand.nx() * self.m()
+ self.m() * operand.ny() * self.e1ep()
- self.ps() * operand.d() * self.e2em()
+ self.ps() * operand.nx() * self.ps()
- self.ps() * operand.ny() * self.e1em()
- self.s() * operand.d() * self.e1ep()
+ self.s() * operand.nx() * self.s()
+ self.s() * operand.ny() * self.e2ep(),
-(self.e1em() * operand.d() * self.e2em()) + self.e1em() * operand.nx() * self.ps()
- self.e1em() * operand.ny() * self.e1em()
+ self.e1ep() * operand.d() * self.e2ep()
+ self.e1ep() * operand.nx() * self.m()
+ self.e1ep() * operand.ny() * self.e1ep()
- self.e2em() * operand.d() * self.e1em()
- self.e2em() * operand.nx() * self.epem()
+ self.e2em() * operand.ny() * self.e2em()
+ self.e2ep() * operand.d() * self.e1ep()
- self.e2ep() * operand.nx() * self.s()
- self.e2ep() * operand.ny() * self.e2ep()
- self.epem() * operand.d() * self.ps()
- self.epem() * operand.nx() * self.e2em()
- self.epem() * operand.ny() * self.epem()
+ self.m() * operand.d() * self.s()
+ self.m() * operand.nx() * self.e1ep()
- self.m() * operand.ny() * self.m()
- self.ps() * operand.d() * self.epem()
+ self.ps() * operand.nx() * self.e1em()
+ self.ps() * operand.ny() * self.ps()
+ self.s() * operand.d() * self.m()
- self.s() * operand.nx() * self.e2ep()
+ self.s() * operand.ny() * self.s(),
self.e1em() * operand.d() * self.e1em() + self.e1em() * operand.nx() * self.epem()
- self.e1em() * operand.ny() * self.e2em()
- self.e1ep() * operand.d() * self.e1ep()
+ self.e1ep() * operand.nx() * self.s()
+ self.e1ep() * operand.ny() * self.e2ep()
- self.e2em() * operand.d() * self.e2em()
+ self.e2em() * operand.nx() * self.ps()
- self.e2em() * operand.ny() * self.e1em()
+ self.e2ep() * operand.d() * self.e2ep()
+ self.e2ep() * operand.nx() * self.m()
+ self.e2ep() * operand.ny() * self.e1ep()
- self.epem() * operand.d() * self.epem()
+ self.epem() * operand.nx() * self.e1em()
+ self.epem() * operand.ny() * self.ps()
- self.m() * operand.d() * self.m()
+ self.m() * operand.nx() * self.e2ep()
- self.m() * operand.ny() * self.s()
+ self.ps() * operand.d() * self.ps()
+ self.ps() * operand.nx() * self.e2em()
+ self.ps() * operand.ny() * self.epem()
+ self.s() * operand.d() * self.s()
+ self.s() * operand.nx() * self.e1ep()
- self.s() * operand.ny() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Line<T>> for Unit<Motor<T>> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(operand.nx() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.nx() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.nx() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.nx() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO * operand.d() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.d() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO * operand.ny() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.ny() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.d() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.d() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.ny() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.ny() * self.as_inner().e2ep() * self.as_inner().s()
+ operand.nx() * self.as_inner().epem() * self.as_inner().epem()
+ operand.nx() * self.as_inner().m() * self.as_inner().m()
+ operand.nx() * self.as_inner().ps() * self.as_inner().ps()
+ operand.nx() * self.as_inner().s() * self.as_inner().s(),
-(operand.ny() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ny() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.ny() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.ny() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.d() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.d() * self.as_inner().epem() * self.as_inner().ps()
+ -T::TWO * operand.nx() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.nx() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.d() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.d() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.nx() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.nx() * self.as_inner().e1ep() * self.as_inner().m()
+ operand.ny() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.ny() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.ny() * self.as_inner().ps() * self.as_inner().ps()
+ operand.ny() * self.as_inner().s() * self.as_inner().s(),
-(operand.d() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.d() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.d() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.d() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.ny() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.ny() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.nx() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.nx() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.nx() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.nx() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.ny() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.ny() * self.as_inner().epem() * self.as_inner().ps()
+ operand.d() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.d() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.d() * self.as_inner().ps() * self.as_inner().ps()
+ operand.d() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Line<T>>> for Motor<T> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.e1em() * self.e1em())
+ -(operand.as_inner().nx() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().nx() * self.e2em() * self.e2em())
+ -(operand.as_inner().nx() * self.e2ep() * self.e2ep())
+ -T::TWO * operand.as_inner().d() * self.e1ep() * self.s()
+ -T::TWO * operand.as_inner().d() * self.e2em() * self.ps()
+ -T::TWO * operand.as_inner().ny() * self.e1em() * self.ps()
+ -T::TWO * operand.as_inner().ny() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().d() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().d() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().ny() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().ny() * self.e2ep() * self.s()
+ operand.as_inner().nx() * self.epem() * self.epem()
+ operand.as_inner().nx() * self.m() * self.m()
+ operand.as_inner().nx() * self.ps() * self.ps()
+ operand.as_inner().nx() * self.s() * self.s(),
-(operand.as_inner().ny() * self.e1em() * self.e1em())
+ -(operand.as_inner().ny() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().ny() * self.epem() * self.epem())
+ -(operand.as_inner().ny() * self.m() * self.m())
+ -T::TWO * operand.as_inner().d() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().d() * self.epem() * self.ps()
+ -T::TWO * operand.as_inner().nx() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().nx() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().d() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().d() * self.m() * self.s()
+ T::TWO * operand.as_inner().nx() * self.e1em() * self.ps()
+ T::TWO * operand.as_inner().nx() * self.e1ep() * self.m()
+ operand.as_inner().ny() * self.e1ep() * self.e1ep()
+ operand.as_inner().ny() * self.e2em() * self.e2em()
+ operand.as_inner().ny() * self.ps() * self.ps()
+ operand.as_inner().ny() * self.s() * self.s(),
-(operand.as_inner().d() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().d() * self.e2em() * self.e2em())
+ -(operand.as_inner().d() * self.epem() * self.epem())
+ -(operand.as_inner().d() * self.m() * self.m())
+ -T::TWO * operand.as_inner().ny() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().ny() * self.m() * self.s()
+ T::TWO * operand.as_inner().nx() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().nx() * self.e1ep() * self.s()
+ T::TWO * operand.as_inner().nx() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().nx() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().ny() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().ny() * self.epem() * self.ps()
+ operand.as_inner().d() * self.e1em() * self.e1em()
+ operand.as_inner().d() * self.e2ep() * self.e2ep()
+ operand.as_inner().d() * self.ps() * self.ps()
+ operand.as_inner().d() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Line<T>>> for Unit<Motor<T>> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().nx() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().nx() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().nx() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO * operand.as_inner().d() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.as_inner().d() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO * operand.as_inner().ny() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO
* operand.as_inner().ny()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().d() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.as_inner().d() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().ny() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().ny() * self.as_inner().e2ep() * self.as_inner().s()
+ operand.as_inner().nx() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().nx() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().nx() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().nx() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().ny() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ny() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().ny() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().ny() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().d()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO * operand.as_inner().d() * self.as_inner().epem() * self.as_inner().ps()
+ -T::TWO
* operand.as_inner().nx()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().nx() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().d() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.as_inner().d() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.as_inner().nx() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.as_inner().nx() * self.as_inner().e1ep() * self.as_inner().m()
+ operand.as_inner().ny() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().ny() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().ny() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().ny() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().d() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().d() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().d() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().d() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().ny()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO * operand.as_inner().ny() * self.as_inner().m() * self.as_inner().s()
+ T::TWO
* operand.as_inner().nx()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().nx() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().nx() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.as_inner().nx() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().ny()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().ny() * self.as_inner().epem() * self.as_inner().ps()
+ operand.as_inner().d() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().d() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().d() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().d() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Sandwich product: [`Motor`] x [`Motor`] x rev([`Motor`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Motor<T>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
self.e1em() * operand.e1em() * self.s() - self.e1em() * operand.e1ep() * self.epem()
+ self.e1em() * operand.e2em() * self.m()
- self.e1em() * operand.e2ep() * self.ps()
+ self.e1em() * operand.epem() * self.e1ep()
- self.e1em() * operand.m() * self.e2em()
+ self.e1em() * operand.ps() * self.e2ep()
- self.e1em() * operand.s() * self.e1em()
+ self.e1ep() * operand.e1em() * self.epem()
- self.e1ep() * operand.e1ep() * self.s()
+ self.e1ep() * operand.e2em() * self.ps()
- self.e1ep() * operand.e2ep() * self.m()
- self.e1ep() * operand.epem() * self.e1em()
+ self.e1ep() * operand.m() * self.e2ep()
- self.e1ep() * operand.ps() * self.e2em()
+ self.e1ep() * operand.s() * self.e1ep()
- self.e2em() * operand.e1em() * self.m()
+ self.e2em() * operand.e1ep() * self.ps()
+ self.e2em() * operand.e2em() * self.s()
- self.e2em() * operand.e2ep() * self.epem()
+ self.e2em() * operand.epem() * self.e2ep()
+ self.e2em() * operand.m() * self.e1em()
- self.e2em() * operand.ps() * self.e1ep()
- self.e2em() * operand.s() * self.e2em()
- self.e2ep() * operand.e1em() * self.ps()
+ self.e2ep() * operand.e1ep() * self.m()
+ self.e2ep() * operand.e2em() * self.epem()
- self.e2ep() * operand.e2ep() * self.s()
- self.e2ep() * operand.epem() * self.e2em()
- self.e2ep() * operand.m() * self.e1ep()
+ self.e2ep() * operand.ps() * self.e1em()
+ self.e2ep() * operand.s() * self.e2ep()
- self.epem() * operand.e1em() * self.e1ep()
+ self.epem() * operand.e1ep() * self.e1em()
- self.epem() * operand.e2em() * self.e2ep()
+ self.epem() * operand.e2ep() * self.e2em()
+ self.epem() * operand.epem() * self.s()
- self.epem() * operand.m() * self.ps()
+ self.epem() * operand.ps() * self.m()
- self.epem() * operand.s() * self.epem()
+ self.m() * operand.e1em() * self.e2em()
- self.m() * operand.e1ep() * self.e2ep()
- self.m() * operand.e2em() * self.e1em()
+ self.m() * operand.e2ep() * self.e1ep()
- self.m() * operand.epem() * self.ps()
- self.m() * operand.m() * self.s()
+ self.m() * operand.ps() * self.epem()
+ self.m() * operand.s() * self.m()
+ self.ps() * operand.e1em() * self.e2ep()
- self.ps() * operand.e1ep() * self.e2em()
- self.ps() * operand.e2em() * self.e1ep()
+ self.ps() * operand.e2ep() * self.e1em()
+ self.ps() * operand.epem() * self.m()
+ self.ps() * operand.m() * self.epem()
- self.ps() * operand.ps() * self.s()
- self.ps() * operand.s() * self.ps()
- self.s() * operand.e1em() * self.e1em()
+ self.s() * operand.e1ep() * self.e1ep()
- self.s() * operand.e2em() * self.e2em()
+ self.s() * operand.e2ep() * self.e2ep()
- self.s() * operand.epem() * self.epem()
+ self.s() * operand.m() * self.m()
- self.s() * operand.ps() * self.ps()
+ self.s() * operand.s() * self.s(),
-(self.e1em() * operand.e1em() * self.m())
+ self.e1em() * operand.e1ep() * self.ps()
+ self.e1em() * operand.e2em() * self.s()
- self.e1em() * operand.e2ep() * self.epem()
+ self.e1em() * operand.epem() * self.e2ep()
+ self.e1em() * operand.m() * self.e1em()
- self.e1em() * operand.ps() * self.e1ep()
- self.e1em() * operand.s() * self.e2em()
- self.e1ep() * operand.e1em() * self.ps()
+ self.e1ep() * operand.e1ep() * self.m()
+ self.e1ep() * operand.e2em() * self.epem()
- self.e1ep() * operand.e2ep() * self.s()
- self.e1ep() * operand.epem() * self.e2em()
- self.e1ep() * operand.m() * self.e1ep()
+ self.e1ep() * operand.ps() * self.e1em()
+ self.e1ep() * operand.s() * self.e2ep()
- self.e2em() * operand.e1em() * self.s()
+ self.e2em() * operand.e1ep() * self.epem()
- self.e2em() * operand.e2em() * self.m()
+ self.e2em() * operand.e2ep() * self.ps()
- self.e2em() * operand.epem() * self.e1ep()
+ self.e2em() * operand.m() * self.e2em()
- self.e2em() * operand.ps() * self.e2ep()
+ self.e2em() * operand.s() * self.e1em()
- self.e2ep() * operand.e1em() * self.epem()
+ self.e2ep() * operand.e1ep() * self.s()
- self.e2ep() * operand.e2em() * self.ps()
+ self.e2ep() * operand.e2ep() * self.m()
+ self.e2ep() * operand.epem() * self.e1em()
- self.e2ep() * operand.m() * self.e2ep()
+ self.e2ep() * operand.ps() * self.e2em()
- self.e2ep() * operand.s() * self.e1ep()
- self.epem() * operand.e1em() * self.e2ep()
+ self.epem() * operand.e1ep() * self.e2em()
+ self.epem() * operand.e2em() * self.e1ep()
- self.epem() * operand.e2ep() * self.e1em()
- self.epem() * operand.epem() * self.m()
- self.epem() * operand.m() * self.epem()
+ self.epem() * operand.ps() * self.s()
+ self.epem() * operand.s() * self.ps()
- self.m() * operand.e1em() * self.e1em()
+ self.m() * operand.e1ep() * self.e1ep()
- self.m() * operand.e2em() * self.e2em()
+ self.m() * operand.e2ep() * self.e2ep()
- self.m() * operand.epem() * self.epem()
+ self.m() * operand.m() * self.m()
- self.m() * operand.ps() * self.ps()
+ self.m() * operand.s() * self.s()
- self.ps() * operand.e1em() * self.e1ep()
+ self.ps() * operand.e1ep() * self.e1em()
- self.ps() * operand.e2em() * self.e2ep()
+ self.ps() * operand.e2ep() * self.e2em()
+ self.ps() * operand.epem() * self.s()
- self.ps() * operand.m() * self.ps()
+ self.ps() * operand.ps() * self.m()
- self.ps() * operand.s() * self.epem()
- self.s() * operand.e1em() * self.e2em()
+ self.s() * operand.e1ep() * self.e2ep()
+ self.s() * operand.e2em() * self.e1em()
- self.s() * operand.e2ep() * self.e1ep()
+ self.s() * operand.epem() * self.ps()
+ self.s() * operand.m() * self.s()
- self.s() * operand.ps() * self.epem()
- self.s() * operand.s() * self.m(),
-(self.e1em() * operand.e1em() * self.e1ep())
+ self.e1em() * operand.e1ep() * self.e1em()
- self.e1em() * operand.e2em() * self.e2ep()
+ self.e1em() * operand.e2ep() * self.e2em()
+ self.e1em() * operand.epem() * self.s()
- self.e1em() * operand.m() * self.ps()
+ self.e1em() * operand.ps() * self.m()
- self.e1em() * operand.s() * self.epem()
- self.e1ep() * operand.e1em() * self.e1em()
+ self.e1ep() * operand.e1ep() * self.e1ep()
- self.e1ep() * operand.e2em() * self.e2em()
+ self.e1ep() * operand.e2ep() * self.e2ep()
- self.e1ep() * operand.epem() * self.epem()
+ self.e1ep() * operand.m() * self.m()
- self.e1ep() * operand.ps() * self.ps()
+ self.e1ep() * operand.s() * self.s()
+ self.e2em() * operand.e1em() * self.e2ep()
- self.e2em() * operand.e1ep() * self.e2em()
- self.e2em() * operand.e2em() * self.e1ep()
+ self.e2em() * operand.e2ep() * self.e1em()
+ self.e2em() * operand.epem() * self.m()
+ self.e2em() * operand.m() * self.epem()
- self.e2em() * operand.ps() * self.s()
- self.e2em() * operand.s() * self.ps()
+ self.e2ep() * operand.e1em() * self.e2em()
- self.e2ep() * operand.e1ep() * self.e2ep()
- self.e2ep() * operand.e2em() * self.e1em()
+ self.e2ep() * operand.e2ep() * self.e1ep()
- self.e2ep() * operand.epem() * self.ps()
- self.e2ep() * operand.m() * self.s()
+ self.e2ep() * operand.ps() * self.epem()
+ self.e2ep() * operand.s() * self.m()
- self.epem() * operand.e1em() * self.s()
+ self.epem() * operand.e1ep() * self.epem()
- self.epem() * operand.e2em() * self.m()
+ self.epem() * operand.e2ep() * self.ps()
- self.epem() * operand.epem() * self.e1ep()
+ self.epem() * operand.m() * self.e2em()
- self.epem() * operand.ps() * self.e2ep()
+ self.epem() * operand.s() * self.e1em()
+ self.m() * operand.e1em() * self.ps()
- self.m() * operand.e1ep() * self.m()
- self.m() * operand.e2em() * self.epem()
+ self.m() * operand.e2ep() * self.s()
+ self.m() * operand.epem() * self.e2em()
+ self.m() * operand.m() * self.e1ep()
- self.m() * operand.ps() * self.e1em()
- self.m() * operand.s() * self.e2ep()
+ self.ps() * operand.e1em() * self.m()
- self.ps() * operand.e1ep() * self.ps()
- self.ps() * operand.e2em() * self.s()
+ self.ps() * operand.e2ep() * self.epem()
- self.ps() * operand.epem() * self.e2ep()
- self.ps() * operand.m() * self.e1em()
+ self.ps() * operand.ps() * self.e1ep()
+ self.ps() * operand.s() * self.e2em()
- self.s() * operand.e1em() * self.epem()
+ self.s() * operand.e1ep() * self.s()
- self.s() * operand.e2em() * self.ps()
+ self.s() * operand.e2ep() * self.m()
+ self.s() * operand.epem() * self.e1em()
- self.s() * operand.m() * self.e2ep()
+ self.s() * operand.ps() * self.e2em()
- self.s() * operand.s() * self.e1ep(),
-(self.e1em() * operand.e1em() * self.e2ep())
+ self.e1em() * operand.e1ep() * self.e2em()
+ self.e1em() * operand.e2em() * self.e1ep()
- self.e1em() * operand.e2ep() * self.e1em()
- self.e1em() * operand.epem() * self.m()
- self.e1em() * operand.m() * self.epem()
+ self.e1em() * operand.ps() * self.s()
+ self.e1em() * operand.s() * self.ps()
- self.e1ep() * operand.e1em() * self.e2em()
+ self.e1ep() * operand.e1ep() * self.e2ep()
+ self.e1ep() * operand.e2em() * self.e1em()
- self.e1ep() * operand.e2ep() * self.e1ep()
+ self.e1ep() * operand.epem() * self.ps()
+ self.e1ep() * operand.m() * self.s()
- self.e1ep() * operand.ps() * self.epem()
- self.e1ep() * operand.s() * self.m()
- self.e2em() * operand.e1em() * self.e1ep()
+ self.e2em() * operand.e1ep() * self.e1em()
- self.e2em() * operand.e2em() * self.e2ep()
+ self.e2em() * operand.e2ep() * self.e2em()
+ self.e2em() * operand.epem() * self.s()
- self.e2em() * operand.m() * self.ps()
+ self.e2em() * operand.ps() * self.m()
- self.e2em() * operand.s() * self.epem()
- self.e2ep() * operand.e1em() * self.e1em()
+ self.e2ep() * operand.e1ep() * self.e1ep()
- self.e2ep() * operand.e2em() * self.e2em()
+ self.e2ep() * operand.e2ep() * self.e2ep()
- self.e2ep() * operand.epem() * self.epem()
+ self.e2ep() * operand.m() * self.m()
- self.e2ep() * operand.ps() * self.ps()
+ self.e2ep() * operand.s() * self.s()
+ self.epem() * operand.e1em() * self.m()
- self.epem() * operand.e1ep() * self.ps()
- self.epem() * operand.e2em() * self.s()
+ self.epem() * operand.e2ep() * self.epem()
- self.epem() * operand.epem() * self.e2ep()
- self.epem() * operand.m() * self.e1em()
+ self.epem() * operand.ps() * self.e1ep()
+ self.epem() * operand.s() * self.e2em()
+ self.m() * operand.e1em() * self.epem()
- self.m() * operand.e1ep() * self.s()
+ self.m() * operand.e2em() * self.ps()
- self.m() * operand.e2ep() * self.m()
- self.m() * operand.epem() * self.e1em()
+ self.m() * operand.m() * self.e2ep()
- self.m() * operand.ps() * self.e2em()
+ self.m() * operand.s() * self.e1ep()
+ self.ps() * operand.e1em() * self.s()
- self.ps() * operand.e1ep() * self.epem()
+ self.ps() * operand.e2em() * self.m()
- self.ps() * operand.e2ep() * self.ps()
+ self.ps() * operand.epem() * self.e1ep()
- self.ps() * operand.m() * self.e2em()
+ self.ps() * operand.ps() * self.e2ep()
- self.ps() * operand.s() * self.e1em()
+ self.s() * operand.e1em() * self.ps()
- self.s() * operand.e1ep() * self.m()
- self.s() * operand.e2em() * self.epem()
+ self.s() * operand.e2ep() * self.s()
+ self.s() * operand.epem() * self.e2em()
+ self.s() * operand.m() * self.e1ep()
- self.s() * operand.ps() * self.e1em()
- self.s() * operand.s() * self.e2ep(),
-(self.e1em() * operand.e1em() * self.e1em())
+ self.e1em() * operand.e1ep() * self.e1ep()
- self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.e2ep() * self.e2ep()
- self.e1em() * operand.epem() * self.epem()
+ self.e1em() * operand.m() * self.m()
- self.e1em() * operand.ps() * self.ps()
+ self.e1em() * operand.s() * self.s()
- self.e1ep() * operand.e1em() * self.e1ep()
+ self.e1ep() * operand.e1ep() * self.e1em()
- self.e1ep() * operand.e2em() * self.e2ep()
+ self.e1ep() * operand.e2ep() * self.e2em()
+ self.e1ep() * operand.epem() * self.s()
- self.e1ep() * operand.m() * self.ps()
+ self.e1ep() * operand.ps() * self.m()
- self.e1ep() * operand.s() * self.epem()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e1ep() * self.e2ep()
- self.e2em() * operand.e2em() * self.e1em()
+ self.e2em() * operand.e2ep() * self.e1ep()
- self.e2em() * operand.epem() * self.ps()
- self.e2em() * operand.m() * self.s()
+ self.e2em() * operand.ps() * self.epem()
+ self.e2em() * operand.s() * self.m()
+ self.e2ep() * operand.e1em() * self.e2ep()
- self.e2ep() * operand.e1ep() * self.e2em()
- self.e2ep() * operand.e2em() * self.e1ep()
+ self.e2ep() * operand.e2ep() * self.e1em()
+ self.e2ep() * operand.epem() * self.m()
+ self.e2ep() * operand.m() * self.epem()
- self.e2ep() * operand.ps() * self.s()
- self.e2ep() * operand.s() * self.ps()
+ self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.e1ep() * self.s()
+ self.epem() * operand.e2em() * self.ps()
- self.epem() * operand.e2ep() * self.m()
- self.epem() * operand.epem() * self.e1em()
+ self.epem() * operand.m() * self.e2ep()
- self.epem() * operand.ps() * self.e2em()
+ self.epem() * operand.s() * self.e1ep()
- self.m() * operand.e1em() * self.m()
+ self.m() * operand.e1ep() * self.ps()
+ self.m() * operand.e2em() * self.s()
- self.m() * operand.e2ep() * self.epem()
+ self.m() * operand.epem() * self.e2ep()
+ self.m() * operand.m() * self.e1em()
- self.m() * operand.ps() * self.e1ep()
- self.m() * operand.s() * self.e2em()
- self.ps() * operand.e1em() * self.ps()
+ self.ps() * operand.e1ep() * self.m()
+ self.ps() * operand.e2em() * self.epem()
- self.ps() * operand.e2ep() * self.s()
- self.ps() * operand.epem() * self.e2em()
- self.ps() * operand.m() * self.e1ep()
+ self.ps() * operand.ps() * self.e1em()
+ self.ps() * operand.s() * self.e2ep()
+ self.s() * operand.e1em() * self.s()
- self.s() * operand.e1ep() * self.epem()
+ self.s() * operand.e2em() * self.m()
- self.s() * operand.e2ep() * self.ps()
+ self.s() * operand.epem() * self.e1ep()
- self.s() * operand.m() * self.e2em()
+ self.s() * operand.ps() * self.e2ep()
- self.s() * operand.s() * self.e1em(),
-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e1ep() * self.e2ep()
+ self.e1em() * operand.e2em() * self.e1em()
- self.e1em() * operand.e2ep() * self.e1ep()
+ self.e1em() * operand.epem() * self.ps()
+ self.e1em() * operand.m() * self.s()
- self.e1em() * operand.ps() * self.epem()
- self.e1em() * operand.s() * self.m()
- self.e1ep() * operand.e1em() * self.e2ep()
+ self.e1ep() * operand.e1ep() * self.e2em()
+ self.e1ep() * operand.e2em() * self.e1ep()
- self.e1ep() * operand.e2ep() * self.e1em()
- self.e1ep() * operand.epem() * self.m()
- self.e1ep() * operand.m() * self.epem()
+ self.e1ep() * operand.ps() * self.s()
+ self.e1ep() * operand.s() * self.ps()
- self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e1ep() * self.e1ep()
- self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.e2ep() * self.e2ep()
- self.e2em() * operand.epem() * self.epem()
+ self.e2em() * operand.m() * self.m()
- self.e2em() * operand.ps() * self.ps()
+ self.e2em() * operand.s() * self.s()
- self.e2ep() * operand.e1em() * self.e1ep()
+ self.e2ep() * operand.e1ep() * self.e1em()
- self.e2ep() * operand.e2em() * self.e2ep()
+ self.e2ep() * operand.e2ep() * self.e2em()
+ self.e2ep() * operand.epem() * self.s()
- self.e2ep() * operand.m() * self.ps()
+ self.e2ep() * operand.ps() * self.m()
- self.e2ep() * operand.s() * self.epem()
- self.epem() * operand.e1em() * self.ps()
+ self.epem() * operand.e1ep() * self.m()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.e2ep() * self.s()
- self.epem() * operand.epem() * self.e2em()
- self.epem() * operand.m() * self.e1ep()
+ self.epem() * operand.ps() * self.e1em()
+ self.epem() * operand.s() * self.e2ep()
- self.m() * operand.e1em() * self.s()
+ self.m() * operand.e1ep() * self.epem()
- self.m() * operand.e2em() * self.m()
+ self.m() * operand.e2ep() * self.ps()
- self.m() * operand.epem() * self.e1ep()
+ self.m() * operand.m() * self.e2em()
- self.m() * operand.ps() * self.e2ep()
+ self.m() * operand.s() * self.e1em()
- self.ps() * operand.e1em() * self.epem()
+ self.ps() * operand.e1ep() * self.s()
- self.ps() * operand.e2em() * self.ps()
+ self.ps() * operand.e2ep() * self.m()
+ self.ps() * operand.epem() * self.e1em()
- self.ps() * operand.m() * self.e2ep()
+ self.ps() * operand.ps() * self.e2em()
- self.ps() * operand.s() * self.e1ep()
- self.s() * operand.e1em() * self.m()
+ self.s() * operand.e1ep() * self.ps()
+ self.s() * operand.e2em() * self.s()
- self.s() * operand.e2ep() * self.epem()
+ self.s() * operand.epem() * self.e2ep()
+ self.s() * operand.m() * self.e1em()
- self.s() * operand.ps() * self.e1ep()
- self.s() * operand.s() * self.e2em(),
-(self.e1em() * operand.e1em() * self.epem()) + self.e1em() * operand.e1ep() * self.s()
- self.e1em() * operand.e2em() * self.ps()
+ self.e1em() * operand.e2ep() * self.m()
+ self.e1em() * operand.epem() * self.e1em()
- self.e1em() * operand.m() * self.e2ep()
+ self.e1em() * operand.ps() * self.e2em()
- self.e1em() * operand.s() * self.e1ep()
- self.e1ep() * operand.e1em() * self.s()
+ self.e1ep() * operand.e1ep() * self.epem()
- self.e1ep() * operand.e2em() * self.m()
+ self.e1ep() * operand.e2ep() * self.ps()
- self.e1ep() * operand.epem() * self.e1ep()
+ self.e1ep() * operand.m() * self.e2em()
- self.e1ep() * operand.ps() * self.e2ep()
+ self.e1ep() * operand.s() * self.e1em()
+ self.e2em() * operand.e1em() * self.ps()
- self.e2em() * operand.e1ep() * self.m()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.e2ep() * self.s()
+ self.e2em() * operand.epem() * self.e2em()
+ self.e2em() * operand.m() * self.e1ep()
- self.e2em() * operand.ps() * self.e1em()
- self.e2em() * operand.s() * self.e2ep()
+ self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.e1ep() * self.ps()
- self.e2ep() * operand.e2em() * self.s()
+ self.e2ep() * operand.e2ep() * self.epem()
- self.e2ep() * operand.epem() * self.e2ep()
- self.e2ep() * operand.m() * self.e1em()
+ self.e2ep() * operand.ps() * self.e1ep()
+ self.e2ep() * operand.s() * self.e2em()
- self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e1ep() * self.e1ep()
- self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.e2ep() * self.e2ep()
- self.epem() * operand.epem() * self.epem()
+ self.epem() * operand.m() * self.m()
- self.epem() * operand.ps() * self.ps()
+ self.epem() * operand.s() * self.s()
+ self.m() * operand.e1em() * self.e2ep()
- self.m() * operand.e1ep() * self.e2em()
- self.m() * operand.e2em() * self.e1ep()
+ self.m() * operand.e2ep() * self.e1em()
+ self.m() * operand.epem() * self.m()
+ self.m() * operand.m() * self.epem()
- self.m() * operand.ps() * self.s()
- self.m() * operand.s() * self.ps()
+ self.ps() * operand.e1em() * self.e2em()
- self.ps() * operand.e1ep() * self.e2ep()
- self.ps() * operand.e2em() * self.e1em()
+ self.ps() * operand.e2ep() * self.e1ep()
- self.ps() * operand.epem() * self.ps()
- self.ps() * operand.m() * self.s()
+ self.ps() * operand.ps() * self.epem()
+ self.ps() * operand.s() * self.m()
- self.s() * operand.e1em() * self.e1ep()
+ self.s() * operand.e1ep() * self.e1em()
- self.s() * operand.e2em() * self.e2ep()
+ self.s() * operand.e2ep() * self.e2em()
+ self.s() * operand.epem() * self.s()
- self.s() * operand.m() * self.ps()
+ self.s() * operand.ps() * self.m()
- self.s() * operand.s() * self.epem(),
self.e1em() * operand.e1em() * self.ps()
- self.e1em() * operand.e1ep() * self.m()
- self.e1em() * operand.e2em() * self.epem()
+ self.e1em() * operand.e2ep() * self.s()
+ self.e1em() * operand.epem() * self.e2em()
+ self.e1em() * operand.m() * self.e1ep()
- self.e1em() * operand.ps() * self.e1em()
- self.e1em() * operand.s() * self.e2ep()
+ self.e1ep() * operand.e1em() * self.m()
- self.e1ep() * operand.e1ep() * self.ps()
- self.e1ep() * operand.e2em() * self.s()
+ self.e1ep() * operand.e2ep() * self.epem()
- self.e1ep() * operand.epem() * self.e2ep()
- self.e1ep() * operand.m() * self.e1em()
+ self.e1ep() * operand.ps() * self.e1ep()
+ self.e1ep() * operand.s() * self.e2em()
+ self.e2em() * operand.e1em() * self.epem()
- self.e2em() * operand.e1ep() * self.s()
+ self.e2em() * operand.e2em() * self.ps()
- self.e2em() * operand.e2ep() * self.m()
- self.e2em() * operand.epem() * self.e1em()
+ self.e2em() * operand.m() * self.e2ep()
- self.e2em() * operand.ps() * self.e2em()
+ self.e2em() * operand.s() * self.e1ep()
+ self.e2ep() * operand.e1em() * self.s()
- self.e2ep() * operand.e1ep() * self.epem()
+ self.e2ep() * operand.e2em() * self.m()
- self.e2ep() * operand.e2ep() * self.ps()
+ self.e2ep() * operand.epem() * self.e1ep()
- self.e2ep() * operand.m() * self.e2em()
+ self.e2ep() * operand.ps() * self.e2ep()
- self.e2ep() * operand.s() * self.e1em()
- self.epem() * operand.e1em() * self.e2em()
+ self.epem() * operand.e1ep() * self.e2ep()
+ self.epem() * operand.e2em() * self.e1em()
- self.epem() * operand.e2ep() * self.e1ep()
+ self.epem() * operand.epem() * self.ps()
+ self.epem() * operand.m() * self.s()
- self.epem() * operand.ps() * self.epem()
- self.epem() * operand.s() * self.m()
- self.m() * operand.e1em() * self.e1ep()
+ self.m() * operand.e1ep() * self.e1em()
- self.m() * operand.e2em() * self.e2ep()
+ self.m() * operand.e2ep() * self.e2em()
+ self.m() * operand.epem() * self.s()
- self.m() * operand.m() * self.ps()
+ self.m() * operand.ps() * self.m()
- self.m() * operand.s() * self.epem()
- self.ps() * operand.e1em() * self.e1em()
+ self.ps() * operand.e1ep() * self.e1ep()
- self.ps() * operand.e2em() * self.e2em()
+ self.ps() * operand.e2ep() * self.e2ep()
- self.ps() * operand.epem() * self.epem()
+ self.ps() * operand.m() * self.m()
- self.ps() * operand.ps() * self.ps()
+ self.ps() * operand.s() * self.s()
- self.s() * operand.e1em() * self.e2ep()
+ self.s() * operand.e1ep() * self.e2em()
+ self.s() * operand.e2em() * self.e1ep()
- self.s() * operand.e2ep() * self.e1em()
- self.s() * operand.epem() * self.m()
- self.s() * operand.m() * self.epem()
+ self.s() * operand.ps() * self.s()
+ self.s() * operand.s() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Motor<T>> for Unit<Motor<T>> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(operand.s() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.s() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.s() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.s() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO * operand.ps() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.ps() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO * operand.ps() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.ps() * self.as_inner().epem() * self.as_inner().m()
+ operand.s() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.s() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.s() * self.as_inner().m() * self.as_inner().m()
+ operand.s() * self.as_inner().s() * self.as_inner().s(),
-(operand.m() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.m() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.m() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.m() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().ps()
+ -T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().s()
+ -T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().epem()
+ -T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.e2em() * self.as_inner().e2ep() * self.as_inner().ps()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.epem() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.e2ep() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.e2ep() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.epem() * self.as_inner().ps() * self.as_inner().s()
+ operand.m() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.m() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.m() * self.as_inner().m() * self.as_inner().m()
+ operand.m() * self.as_inner().s() * self.as_inner().s(),
-(operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e1ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e1ep() * self.as_inner().m() * self.as_inner().m())
+ -(operand.e1ep() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().m()
+ -T::TWO * operand.e2em() * self.as_inner().ps() * self.as_inner().s()
+ -T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().ps()
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.e1em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e2ep() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO * operand.e2ep() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e1ep() * self.as_inner().epem() * self.as_inner().epem()
+ operand.e1ep() * self.as_inner().s() * self.as_inner().s(),
-(operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e2ep() * self.as_inner().m() * self.as_inner().m())
+ -(operand.e2ep() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.e1ep() * self.as_inner().epem() * self.as_inner().ps()
+ -T::TWO * operand.e1ep() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e1em() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.e2em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().m()
+ operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e2ep() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e2ep() * self.as_inner().epem() * self.as_inner().epem()
+ operand.e2ep() * self.as_inner().s() * self.as_inner().s(),
-(operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e1em() * self.as_inner().m() * self.as_inner().m())
+ -(operand.e1em() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.e1ep() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.e2ep() * self.as_inner().epem() * self.as_inner().m()
+ -T::TWO * operand.e2ep() * self.as_inner().ps() * self.as_inner().s()
+ -T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().ps()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.e1ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO * operand.e2em() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e1em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e1em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.e1em() * self.as_inner().s() * self.as_inner().s(),
-(operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e2em() * self.as_inner().m() * self.as_inner().m())
+ -(operand.e2em() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().ps()
+ -T::TWO * operand.e1em() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.e2ep() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().ps()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.e1ep() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e1ep() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO * operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.e2ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().m()
+ operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e2em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e2em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.e2em() * self.as_inner().s() * self.as_inner().s(),
-(operand.epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.epem() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.e1ep() * self.as_inner().e2ep() * self.as_inner().ps()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.e2em() * self.as_inner().e2ep() * self.as_inner().s()
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.m() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO * operand.e2ep() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.e2ep() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.m() * self.as_inner().epem() * self.as_inner().m()
+ operand.epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.epem() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.epem() * self.as_inner().m() * self.as_inner().m()
+ operand.epem() * self.as_inner().s() * self.as_inner().s(),
-(operand.ps() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ps() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.ps() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.ps() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO * operand.s() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.s() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.s() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.s() * self.as_inner().ps() * self.as_inner().s()
+ operand.ps() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.ps() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.ps() * self.as_inner().m() * self.as_inner().m()
+ operand.ps() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Motor<T>>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.e1em() * self.e1em())
+ -(operand.as_inner().s() * self.e2em() * self.e2em())
+ -(operand.as_inner().s() * self.epem() * self.epem())
+ -(operand.as_inner().s() * self.ps() * self.ps())
+ -T::TWO * operand.as_inner().ps() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().ps() * self.ps() * self.s()
+ T::TWO * operand.as_inner().ps() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().ps() * self.epem() * self.m()
+ operand.as_inner().s() * self.e1ep() * self.e1ep()
+ operand.as_inner().s() * self.e2ep() * self.e2ep()
+ operand.as_inner().s() * self.m() * self.m()
+ operand.as_inner().s() * self.s() * self.s(),
-(operand.as_inner().m() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().m() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().m() * self.epem() * self.epem())
+ -(operand.as_inner().m() * self.ps() * self.ps())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.ps()
+ -T::TWO * operand.as_inner().e1em() * self.e2em() * self.s()
+ -T::TWO * operand.as_inner().e1em() * self.e2ep() * self.epem()
+ -T::TWO * operand.as_inner().e2em() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().e2em() * self.e2ep() * self.ps()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.s()
+ -T::TWO * operand.as_inner().epem() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().epem() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.ps()
+ T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e1ep() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().e2ep() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().e2ep() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().epem() * self.ps() * self.s()
+ operand.as_inner().m() * self.e1em() * self.e1em()
+ operand.as_inner().m() * self.e2em() * self.e2em()
+ operand.as_inner().m() * self.m() * self.m()
+ operand.as_inner().m() * self.s() * self.s(),
-(operand.as_inner().e1ep() * self.e2em() * self.e2em())
+ -(operand.as_inner().e1ep() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e1ep() * self.m() * self.m())
+ -(operand.as_inner().e1ep() * self.ps() * self.ps())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().e1em() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().e2em() * self.epem() * self.m()
+ -T::TWO * operand.as_inner().e2em() * self.ps() * self.s()
+ -T::TWO * operand.as_inner().epem() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().epem() * self.e2ep() * self.ps()
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.ps()
+ -T::TWO * operand.as_inner().m() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().e1em() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().e1em() * self.m() * self.ps()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.epem() * self.ps()
+ T::TWO * operand.as_inner().e2ep() * self.m() * self.s()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().epem() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().m() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().m() * self.e2em() * self.epem()
+ operand.as_inner().e1ep() * self.e1em() * self.e1em()
+ operand.as_inner().e1ep() * self.e1ep() * self.e1ep()
+ operand.as_inner().e1ep() * self.epem() * self.epem()
+ operand.as_inner().e1ep() * self.s() * self.s(),
-(operand.as_inner().e2ep() * self.e1em() * self.e1em())
+ -(operand.as_inner().e2ep() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e2ep() * self.m() * self.m())
+ -(operand.as_inner().e2ep() * self.ps() * self.ps())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().e1ep() * self.epem() * self.ps()
+ -T::TWO * operand.as_inner().e1ep() * self.m() * self.s()
+ -T::TWO * operand.as_inner().e2em() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().e2em() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().epem() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e2ep() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().e1em() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e1em() * self.ps() * self.s()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().e2em() * self.m() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e2em() * self.s()
+ T::TWO * operand.as_inner().m() * self.e1ep() * self.s()
+ T::TWO * operand.as_inner().m() * self.e2ep() * self.m()
+ operand.as_inner().e2ep() * self.e2em() * self.e2em()
+ operand.as_inner().e2ep() * self.e2ep() * self.e2ep()
+ operand.as_inner().e2ep() * self.epem() * self.epem()
+ operand.as_inner().e2ep() * self.s() * self.s(),
-(operand.as_inner().e1em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1em() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e1em() * self.m() * self.m())
+ -(operand.as_inner().e1em() * self.ps() * self.ps())
+ -T::TWO * operand.as_inner().e1ep() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().e1ep() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().e2ep() * self.epem() * self.m()
+ -T::TWO * operand.as_inner().e2ep() * self.ps() * self.s()
+ -T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.ps()
+ -T::TWO * operand.as_inner().m() * self.e1ep() * self.ps()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.s()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().e1ep() * self.m() * self.ps()
+ T::TWO * operand.as_inner().e2em() * self.epem() * self.ps()
+ T::TWO * operand.as_inner().e2em() * self.m() * self.s()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.s()
+ T::TWO * operand.as_inner().epem() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().m() * self.e2ep() * self.epem()
+ operand.as_inner().e1em() * self.e2em() * self.e2em()
+ operand.as_inner().e1em() * self.e2ep() * self.e2ep()
+ operand.as_inner().e1em() * self.epem() * self.epem()
+ operand.as_inner().e1em() * self.s() * self.s(),
-(operand.as_inner().e2em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2em() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e2em() * self.m() * self.m())
+ -(operand.as_inner().e2em() * self.ps() * self.ps())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().e1em() * self.epem() * self.ps()
+ -T::TWO * operand.as_inner().e1em() * self.m() * self.s()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().e2ep() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().epem() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e2ep() * self.ps()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().e1ep() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e1ep() * self.ps() * self.s()
+ T::TWO * operand.as_inner().e2ep() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.m() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().m() * self.e2em() * self.m()
+ operand.as_inner().e2em() * self.e1em() * self.e1em()
+ operand.as_inner().e2em() * self.e1ep() * self.e1ep()
+ operand.as_inner().e2em() * self.epem() * self.epem()
+ operand.as_inner().e2em() * self.s() * self.s(),
-(operand.as_inner().epem() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().epem() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().epem() * self.epem() * self.epem())
+ -(operand.as_inner().epem() * self.ps() * self.ps())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.s()
+ -T::TWO * operand.as_inner().e1ep() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().e1ep() * self.e2ep() * self.ps()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.ps()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().e2em() * self.e2ep() * self.s()
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().m() * self.ps() * self.s()
+ T::TWO * operand.as_inner().e1em() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().e1em() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.ps()
+ T::TWO * operand.as_inner().e2ep() * self.e2em() * self.s()
+ T::TWO * operand.as_inner().e2ep() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().m() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().m() * self.epem() * self.m()
+ operand.as_inner().epem() * self.e1em() * self.e1em()
+ operand.as_inner().epem() * self.e2em() * self.e2em()
+ operand.as_inner().epem() * self.m() * self.m()
+ operand.as_inner().epem() * self.s() * self.s(),
-(operand.as_inner().ps() * self.e1em() * self.e1em())
+ -(operand.as_inner().ps() * self.e2em() * self.e2em())
+ -(operand.as_inner().ps() * self.epem() * self.epem())
+ -(operand.as_inner().ps() * self.ps() * self.ps())
+ -T::TWO * operand.as_inner().s() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().s() * self.epem() * self.m()
+ T::TWO * operand.as_inner().s() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().s() * self.ps() * self.s()
+ operand.as_inner().ps() * self.e1ep() * self.e1ep()
+ operand.as_inner().ps() * self.e2ep() * self.e2ep()
+ operand.as_inner().ps() * self.m() * self.m()
+ operand.as_inner().ps() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Motor<T>>> for Unit<Motor<T>> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().s() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().s() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().s() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO
* operand.as_inner().ps()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO * operand.as_inner().ps() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO
* operand.as_inner().ps()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().ps() * self.as_inner().epem() * self.as_inner().m()
+ operand.as_inner().s() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().s() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().s() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().s() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().m() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().m() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2ep()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().epem()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().epem() * self.as_inner().ps() * self.as_inner().s()
+ operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().m() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().m() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().e1ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e1ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e1ep() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().e1ep() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().epem()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().epem()
* self.as_inner().m()
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().ps() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().epem()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.as_inner().e1ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e1ep() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e1ep() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().e1ep() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().e2ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e2ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e2ep() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().e2ep() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().epem()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().epem()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().m()
+ operand.as_inner().e2ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e2ep() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e2ep() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().e2ep() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().e1em() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().epem()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().epem()
* self.as_inner().m()
+ -T::TWO * operand.as_inner().e2ep() * self.as_inner().ps() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().ps()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().epem()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().e1em() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().e2em() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().epem()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().epem()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().m()
+ operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().e2em() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().epem() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2ep()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2ep()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().m() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.as_inner().m() * self.as_inner().epem() * self.as_inner().m()
+ operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().epem() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().epem() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().ps() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ps() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().ps() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().ps() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO
* operand.as_inner().s()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().s() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.as_inner().s() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.as_inner().s() * self.as_inner().ps() * self.as_inner().s()
+ operand.as_inner().ps() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().ps() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().ps() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().ps() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Sandwich product: [`Motor`] x [`PointPair`] x rev([`Motor`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<PointPair<T>> for Motor<T> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(self.e1em() * operand.e1em() * self.m())
+ self.e1em() * operand.e1ep() * self.ps()
+ self.e1em() * operand.e2em() * self.s()
- self.e1em() * operand.e2ep() * self.epem()
+ self.e1em() * operand.epem() * self.e2ep()
+ self.e1em() * operand.m() * self.e1em()
- self.e1ep() * operand.e1em() * self.ps()
+ self.e1ep() * operand.e1ep() * self.m()
+ self.e1ep() * operand.e2em() * self.epem()
- self.e1ep() * operand.e2ep() * self.s()
- self.e1ep() * operand.epem() * self.e2em()
- self.e1ep() * operand.m() * self.e1ep()
- self.e2em() * operand.e1em() * self.s()
+ self.e2em() * operand.e1ep() * self.epem()
- self.e2em() * operand.e2em() * self.m()
+ self.e2em() * operand.e2ep() * self.ps()
- self.e2em() * operand.epem() * self.e1ep()
+ self.e2em() * operand.m() * self.e2em()
- self.e2ep() * operand.e1em() * self.epem()
+ self.e2ep() * operand.e1ep() * self.s()
- self.e2ep() * operand.e2em() * self.ps()
+ self.e2ep() * operand.e2ep() * self.m()
+ self.e2ep() * operand.epem() * self.e1em()
- self.e2ep() * operand.m() * self.e2ep()
- self.epem() * operand.e1em() * self.e2ep()
+ self.epem() * operand.e1ep() * self.e2em()
+ self.epem() * operand.e2em() * self.e1ep()
- self.epem() * operand.e2ep() * self.e1em()
- self.epem() * operand.epem() * self.m()
- self.epem() * operand.m() * self.epem()
- self.m() * operand.e1em() * self.e1em()
+ self.m() * operand.e1ep() * self.e1ep()
- self.m() * operand.e2em() * self.e2em()
+ self.m() * operand.e2ep() * self.e2ep()
- self.m() * operand.epem() * self.epem()
+ self.m() * operand.m() * self.m()
- self.ps() * operand.e1em() * self.e1ep()
+ self.ps() * operand.e1ep() * self.e1em()
- self.ps() * operand.e2em() * self.e2ep()
+ self.ps() * operand.e2ep() * self.e2em()
+ self.ps() * operand.epem() * self.s()
- self.ps() * operand.m() * self.ps()
- self.s() * operand.e1em() * self.e2em()
+ self.s() * operand.e1ep() * self.e2ep()
+ self.s() * operand.e2em() * self.e1em()
- self.s() * operand.e2ep() * self.e1ep()
+ self.s() * operand.epem() * self.ps()
+ self.s() * operand.m() * self.s(),
-(self.e1em() * operand.e1em() * self.e1ep())
+ self.e1em() * operand.e1ep() * self.e1em()
- self.e1em() * operand.e2em() * self.e2ep()
+ self.e1em() * operand.e2ep() * self.e2em()
+ self.e1em() * operand.epem() * self.s()
- self.e1em() * operand.m() * self.ps()
- self.e1ep() * operand.e1em() * self.e1em()
+ self.e1ep() * operand.e1ep() * self.e1ep()
- self.e1ep() * operand.e2em() * self.e2em()
+ self.e1ep() * operand.e2ep() * self.e2ep()
- self.e1ep() * operand.epem() * self.epem()
+ self.e1ep() * operand.m() * self.m()
+ self.e2em() * operand.e1em() * self.e2ep()
- self.e2em() * operand.e1ep() * self.e2em()
- self.e2em() * operand.e2em() * self.e1ep()
+ self.e2em() * operand.e2ep() * self.e1em()
+ self.e2em() * operand.epem() * self.m()
+ self.e2em() * operand.m() * self.epem()
+ self.e2ep() * operand.e1em() * self.e2em()
- self.e2ep() * operand.e1ep() * self.e2ep()
- self.e2ep() * operand.e2em() * self.e1em()
+ self.e2ep() * operand.e2ep() * self.e1ep()
- self.e2ep() * operand.epem() * self.ps()
- self.e2ep() * operand.m() * self.s()
- self.epem() * operand.e1em() * self.s()
+ self.epem() * operand.e1ep() * self.epem()
- self.epem() * operand.e2em() * self.m()
+ self.epem() * operand.e2ep() * self.ps()
- self.epem() * operand.epem() * self.e1ep()
+ self.epem() * operand.m() * self.e2em()
+ self.m() * operand.e1em() * self.ps()
- self.m() * operand.e1ep() * self.m()
- self.m() * operand.e2em() * self.epem()
+ self.m() * operand.e2ep() * self.s()
+ self.m() * operand.epem() * self.e2em()
+ self.m() * operand.m() * self.e1ep()
+ self.ps() * operand.e1em() * self.m()
- self.ps() * operand.e1ep() * self.ps()
- self.ps() * operand.e2em() * self.s()
+ self.ps() * operand.e2ep() * self.epem()
- self.ps() * operand.epem() * self.e2ep()
- self.ps() * operand.m() * self.e1em()
- self.s() * operand.e1em() * self.epem()
+ self.s() * operand.e1ep() * self.s()
- self.s() * operand.e2em() * self.ps()
+ self.s() * operand.e2ep() * self.m()
+ self.s() * operand.epem() * self.e1em()
- self.s() * operand.m() * self.e2ep(),
-(self.e1em() * operand.e1em() * self.e2ep())
+ self.e1em() * operand.e1ep() * self.e2em()
+ self.e1em() * operand.e2em() * self.e1ep()
- self.e1em() * operand.e2ep() * self.e1em()
- self.e1em() * operand.epem() * self.m()
- self.e1em() * operand.m() * self.epem()
- self.e1ep() * operand.e1em() * self.e2em()
+ self.e1ep() * operand.e1ep() * self.e2ep()
+ self.e1ep() * operand.e2em() * self.e1em()
- self.e1ep() * operand.e2ep() * self.e1ep()
+ self.e1ep() * operand.epem() * self.ps()
+ self.e1ep() * operand.m() * self.s()
- self.e2em() * operand.e1em() * self.e1ep()
+ self.e2em() * operand.e1ep() * self.e1em()
- self.e2em() * operand.e2em() * self.e2ep()
+ self.e2em() * operand.e2ep() * self.e2em()
+ self.e2em() * operand.epem() * self.s()
- self.e2em() * operand.m() * self.ps()
- self.e2ep() * operand.e1em() * self.e1em()
+ self.e2ep() * operand.e1ep() * self.e1ep()
- self.e2ep() * operand.e2em() * self.e2em()
+ self.e2ep() * operand.e2ep() * self.e2ep()
- self.e2ep() * operand.epem() * self.epem()
+ self.e2ep() * operand.m() * self.m()
+ self.epem() * operand.e1em() * self.m()
- self.epem() * operand.e1ep() * self.ps()
- self.epem() * operand.e2em() * self.s()
+ self.epem() * operand.e2ep() * self.epem()
- self.epem() * operand.epem() * self.e2ep()
- self.epem() * operand.m() * self.e1em()
+ self.m() * operand.e1em() * self.epem()
- self.m() * operand.e1ep() * self.s()
+ self.m() * operand.e2em() * self.ps()
- self.m() * operand.e2ep() * self.m()
- self.m() * operand.epem() * self.e1em()
+ self.m() * operand.m() * self.e2ep()
+ self.ps() * operand.e1em() * self.s()
- self.ps() * operand.e1ep() * self.epem()
+ self.ps() * operand.e2em() * self.m()
- self.ps() * operand.e2ep() * self.ps()
+ self.ps() * operand.epem() * self.e1ep()
- self.ps() * operand.m() * self.e2em()
+ self.s() * operand.e1em() * self.ps()
- self.s() * operand.e1ep() * self.m()
- self.s() * operand.e2em() * self.epem()
+ self.s() * operand.e2ep() * self.s()
+ self.s() * operand.epem() * self.e2em()
+ self.s() * operand.m() * self.e1ep(),
-(self.e1em() * operand.e1em() * self.e1em())
+ self.e1em() * operand.e1ep() * self.e1ep()
- self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.e2ep() * self.e2ep()
- self.e1em() * operand.epem() * self.epem()
+ self.e1em() * operand.m() * self.m()
- self.e1ep() * operand.e1em() * self.e1ep()
+ self.e1ep() * operand.e1ep() * self.e1em()
- self.e1ep() * operand.e2em() * self.e2ep()
+ self.e1ep() * operand.e2ep() * self.e2em()
+ self.e1ep() * operand.epem() * self.s()
- self.e1ep() * operand.m() * self.ps()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e1ep() * self.e2ep()
- self.e2em() * operand.e2em() * self.e1em()
+ self.e2em() * operand.e2ep() * self.e1ep()
- self.e2em() * operand.epem() * self.ps()
- self.e2em() * operand.m() * self.s()
+ self.e2ep() * operand.e1em() * self.e2ep()
- self.e2ep() * operand.e1ep() * self.e2em()
- self.e2ep() * operand.e2em() * self.e1ep()
+ self.e2ep() * operand.e2ep() * self.e1em()
+ self.e2ep() * operand.epem() * self.m()
+ self.e2ep() * operand.m() * self.epem()
+ self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.e1ep() * self.s()
+ self.epem() * operand.e2em() * self.ps()
- self.epem() * operand.e2ep() * self.m()
- self.epem() * operand.epem() * self.e1em()
+ self.epem() * operand.m() * self.e2ep()
- self.m() * operand.e1em() * self.m()
+ self.m() * operand.e1ep() * self.ps()
+ self.m() * operand.e2em() * self.s()
- self.m() * operand.e2ep() * self.epem()
+ self.m() * operand.epem() * self.e2ep()
+ self.m() * operand.m() * self.e1em()
- self.ps() * operand.e1em() * self.ps()
+ self.ps() * operand.e1ep() * self.m()
+ self.ps() * operand.e2em() * self.epem()
- self.ps() * operand.e2ep() * self.s()
- self.ps() * operand.epem() * self.e2em()
- self.ps() * operand.m() * self.e1ep()
+ self.s() * operand.e1em() * self.s()
- self.s() * operand.e1ep() * self.epem()
+ self.s() * operand.e2em() * self.m()
- self.s() * operand.e2ep() * self.ps()
+ self.s() * operand.epem() * self.e1ep()
- self.s() * operand.m() * self.e2em(),
-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e1ep() * self.e2ep()
+ self.e1em() * operand.e2em() * self.e1em()
- self.e1em() * operand.e2ep() * self.e1ep()
+ self.e1em() * operand.epem() * self.ps()
+ self.e1em() * operand.m() * self.s()
- self.e1ep() * operand.e1em() * self.e2ep()
+ self.e1ep() * operand.e1ep() * self.e2em()
+ self.e1ep() * operand.e2em() * self.e1ep()
- self.e1ep() * operand.e2ep() * self.e1em()
- self.e1ep() * operand.epem() * self.m()
- self.e1ep() * operand.m() * self.epem()
- self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e1ep() * self.e1ep()
- self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.e2ep() * self.e2ep()
- self.e2em() * operand.epem() * self.epem()
+ self.e2em() * operand.m() * self.m()
- self.e2ep() * operand.e1em() * self.e1ep()
+ self.e2ep() * operand.e1ep() * self.e1em()
- self.e2ep() * operand.e2em() * self.e2ep()
+ self.e2ep() * operand.e2ep() * self.e2em()
+ self.e2ep() * operand.epem() * self.s()
- self.e2ep() * operand.m() * self.ps()
- self.epem() * operand.e1em() * self.ps()
+ self.epem() * operand.e1ep() * self.m()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.e2ep() * self.s()
- self.epem() * operand.epem() * self.e2em()
- self.epem() * operand.m() * self.e1ep()
- self.m() * operand.e1em() * self.s()
+ self.m() * operand.e1ep() * self.epem()
- self.m() * operand.e2em() * self.m()
+ self.m() * operand.e2ep() * self.ps()
- self.m() * operand.epem() * self.e1ep()
+ self.m() * operand.m() * self.e2em()
- self.ps() * operand.e1em() * self.epem()
+ self.ps() * operand.e1ep() * self.s()
- self.ps() * operand.e2em() * self.ps()
+ self.ps() * operand.e2ep() * self.m()
+ self.ps() * operand.epem() * self.e1em()
- self.ps() * operand.m() * self.e2ep()
- self.s() * operand.e1em() * self.m()
+ self.s() * operand.e1ep() * self.ps()
+ self.s() * operand.e2em() * self.s()
- self.s() * operand.e2ep() * self.epem()
+ self.s() * operand.epem() * self.e2ep()
+ self.s() * operand.m() * self.e1em(),
-(self.e1em() * operand.e1em() * self.epem()) + self.e1em() * operand.e1ep() * self.s()
- self.e1em() * operand.e2em() * self.ps()
+ self.e1em() * operand.e2ep() * self.m()
+ self.e1em() * operand.epem() * self.e1em()
- self.e1em() * operand.m() * self.e2ep()
- self.e1ep() * operand.e1em() * self.s()
+ self.e1ep() * operand.e1ep() * self.epem()
- self.e1ep() * operand.e2em() * self.m()
+ self.e1ep() * operand.e2ep() * self.ps()
- self.e1ep() * operand.epem() * self.e1ep()
+ self.e1ep() * operand.m() * self.e2em()
+ self.e2em() * operand.e1em() * self.ps()
- self.e2em() * operand.e1ep() * self.m()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.e2ep() * self.s()
+ self.e2em() * operand.epem() * self.e2em()
+ self.e2em() * operand.m() * self.e1ep()
+ self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.e1ep() * self.ps()
- self.e2ep() * operand.e2em() * self.s()
+ self.e2ep() * operand.e2ep() * self.epem()
- self.e2ep() * operand.epem() * self.e2ep()
- self.e2ep() * operand.m() * self.e1em()
- self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e1ep() * self.e1ep()
- self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.e2ep() * self.e2ep()
- self.epem() * operand.epem() * self.epem()
+ self.epem() * operand.m() * self.m()
+ self.m() * operand.e1em() * self.e2ep()
- self.m() * operand.e1ep() * self.e2em()
- self.m() * operand.e2em() * self.e1ep()
+ self.m() * operand.e2ep() * self.e1em()
+ self.m() * operand.epem() * self.m()
+ self.m() * operand.m() * self.epem()
+ self.ps() * operand.e1em() * self.e2em()
- self.ps() * operand.e1ep() * self.e2ep()
- self.ps() * operand.e2em() * self.e1em()
+ self.ps() * operand.e2ep() * self.e1ep()
- self.ps() * operand.epem() * self.ps()
- self.ps() * operand.m() * self.s()
- self.s() * operand.e1em() * self.e1ep()
+ self.s() * operand.e1ep() * self.e1em()
- self.s() * operand.e2em() * self.e2ep()
+ self.s() * operand.e2ep() * self.e2em()
+ self.s() * operand.epem() * self.s()
- self.s() * operand.m() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<PointPair<T>> for Unit<Motor<T>> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.m() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.m() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.m() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.m() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().ps()
+ -T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().s()
+ -T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().epem()
+ -T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.e2em() * self.as_inner().e2ep() * self.as_inner().ps()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.epem() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.e2ep() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.e2ep() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.epem() * self.as_inner().ps() * self.as_inner().s()
+ operand.m() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.m() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.m() * self.as_inner().m() * self.as_inner().m()
+ operand.m() * self.as_inner().s() * self.as_inner().s(),
-(operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e1ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e1ep() * self.as_inner().m() * self.as_inner().m())
+ -(operand.e1ep() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().m()
+ -T::TWO * operand.e2em() * self.as_inner().ps() * self.as_inner().s()
+ -T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().ps()
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.e1em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e2ep() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO * operand.e2ep() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e1ep() * self.as_inner().epem() * self.as_inner().epem()
+ operand.e1ep() * self.as_inner().s() * self.as_inner().s(),
-(operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e2ep() * self.as_inner().m() * self.as_inner().m())
+ -(operand.e2ep() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.e1ep() * self.as_inner().epem() * self.as_inner().ps()
+ -T::TWO * operand.e1ep() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e1em() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.e2em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().m()
+ operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e2ep() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e2ep() * self.as_inner().epem() * self.as_inner().epem()
+ operand.e2ep() * self.as_inner().s() * self.as_inner().s(),
-(operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e1em() * self.as_inner().m() * self.as_inner().m())
+ -(operand.e1em() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.e1ep() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.e2ep() * self.as_inner().epem() * self.as_inner().m()
+ -T::TWO * operand.e2ep() * self.as_inner().ps() * self.as_inner().s()
+ -T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().ps()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.e1ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO * operand.e2em() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e1em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e1em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.e1em() * self.as_inner().s() * self.as_inner().s(),
-(operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e2em() * self.as_inner().m() * self.as_inner().m())
+ -(operand.e2em() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().ps()
+ -T::TWO * operand.e1em() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.e2ep() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().ps()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.e1ep() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e1ep() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO * operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.e2ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().m()
+ operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e2em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e2em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.e2em() * self.as_inner().s() * self.as_inner().s(),
-(operand.epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.epem() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.e1ep() * self.as_inner().e2ep() * self.as_inner().ps()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.e2em() * self.as_inner().e2ep() * self.as_inner().s()
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.m() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO * operand.e2ep() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.e2ep() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.m() * self.as_inner().epem() * self.as_inner().m()
+ operand.epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.epem() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.epem() * self.as_inner().m() * self.as_inner().m()
+ operand.epem() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<PointPair<T>>> for Motor<T> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().m() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().m() * self.epem() * self.epem())
+ -(operand.as_inner().m() * self.ps() * self.ps())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.ps()
+ -T::TWO * operand.as_inner().e1em() * self.e2em() * self.s()
+ -T::TWO * operand.as_inner().e1em() * self.e2ep() * self.epem()
+ -T::TWO * operand.as_inner().e2em() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().e2em() * self.e2ep() * self.ps()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.s()
+ -T::TWO * operand.as_inner().epem() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().epem() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.ps()
+ T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e1ep() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().e2ep() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().e2ep() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().epem() * self.ps() * self.s()
+ operand.as_inner().m() * self.e1em() * self.e1em()
+ operand.as_inner().m() * self.e2em() * self.e2em()
+ operand.as_inner().m() * self.m() * self.m()
+ operand.as_inner().m() * self.s() * self.s(),
-(operand.as_inner().e1ep() * self.e2em() * self.e2em())
+ -(operand.as_inner().e1ep() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e1ep() * self.m() * self.m())
+ -(operand.as_inner().e1ep() * self.ps() * self.ps())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().e1em() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().e2em() * self.epem() * self.m()
+ -T::TWO * operand.as_inner().e2em() * self.ps() * self.s()
+ -T::TWO * operand.as_inner().epem() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().epem() * self.e2ep() * self.ps()
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.ps()
+ -T::TWO * operand.as_inner().m() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().e1em() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().e1em() * self.m() * self.ps()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.epem() * self.ps()
+ T::TWO * operand.as_inner().e2ep() * self.m() * self.s()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().epem() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().m() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().m() * self.e2em() * self.epem()
+ operand.as_inner().e1ep() * self.e1em() * self.e1em()
+ operand.as_inner().e1ep() * self.e1ep() * self.e1ep()
+ operand.as_inner().e1ep() * self.epem() * self.epem()
+ operand.as_inner().e1ep() * self.s() * self.s(),
-(operand.as_inner().e2ep() * self.e1em() * self.e1em())
+ -(operand.as_inner().e2ep() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e2ep() * self.m() * self.m())
+ -(operand.as_inner().e2ep() * self.ps() * self.ps())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().e1ep() * self.epem() * self.ps()
+ -T::TWO * operand.as_inner().e1ep() * self.m() * self.s()
+ -T::TWO * operand.as_inner().e2em() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().e2em() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().epem() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e2ep() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().e1em() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e1em() * self.ps() * self.s()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().e2em() * self.m() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e2em() * self.s()
+ T::TWO * operand.as_inner().m() * self.e1ep() * self.s()
+ T::TWO * operand.as_inner().m() * self.e2ep() * self.m()
+ operand.as_inner().e2ep() * self.e2em() * self.e2em()
+ operand.as_inner().e2ep() * self.e2ep() * self.e2ep()
+ operand.as_inner().e2ep() * self.epem() * self.epem()
+ operand.as_inner().e2ep() * self.s() * self.s(),
-(operand.as_inner().e1em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1em() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e1em() * self.m() * self.m())
+ -(operand.as_inner().e1em() * self.ps() * self.ps())
+ -T::TWO * operand.as_inner().e1ep() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().e1ep() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().e2ep() * self.epem() * self.m()
+ -T::TWO * operand.as_inner().e2ep() * self.ps() * self.s()
+ -T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.ps()
+ -T::TWO * operand.as_inner().m() * self.e1ep() * self.ps()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.s()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().e1ep() * self.m() * self.ps()
+ T::TWO * operand.as_inner().e2em() * self.epem() * self.ps()
+ T::TWO * operand.as_inner().e2em() * self.m() * self.s()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.s()
+ T::TWO * operand.as_inner().epem() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().m() * self.e2ep() * self.epem()
+ operand.as_inner().e1em() * self.e2em() * self.e2em()
+ operand.as_inner().e1em() * self.e2ep() * self.e2ep()
+ operand.as_inner().e1em() * self.epem() * self.epem()
+ operand.as_inner().e1em() * self.s() * self.s(),
-(operand.as_inner().e2em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2em() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e2em() * self.m() * self.m())
+ -(operand.as_inner().e2em() * self.ps() * self.ps())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().e1em() * self.epem() * self.ps()
+ -T::TWO * operand.as_inner().e1em() * self.m() * self.s()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().e2ep() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().epem() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e2ep() * self.ps()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().e1ep() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e1ep() * self.ps() * self.s()
+ T::TWO * operand.as_inner().e2ep() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.m() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().m() * self.e2em() * self.m()
+ operand.as_inner().e2em() * self.e1em() * self.e1em()
+ operand.as_inner().e2em() * self.e1ep() * self.e1ep()
+ operand.as_inner().e2em() * self.epem() * self.epem()
+ operand.as_inner().e2em() * self.s() * self.s(),
-(operand.as_inner().epem() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().epem() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().epem() * self.epem() * self.epem())
+ -(operand.as_inner().epem() * self.ps() * self.ps())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.s()
+ -T::TWO * operand.as_inner().e1ep() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().e1ep() * self.e2ep() * self.ps()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.ps()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().e2em() * self.e2ep() * self.s()
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().m() * self.ps() * self.s()
+ T::TWO * operand.as_inner().e1em() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().e1em() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.ps()
+ T::TWO * operand.as_inner().e2ep() * self.e2em() * self.s()
+ T::TWO * operand.as_inner().e2ep() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().m() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().m() * self.epem() * self.m()
+ operand.as_inner().epem() * self.e1em() * self.e1em()
+ operand.as_inner().epem() * self.e2em() * self.e2em()
+ operand.as_inner().epem() * self.m() * self.m()
+ operand.as_inner().epem() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<PointPair<T>>> for Unit<Motor<T>> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().m() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().m() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2ep()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().epem()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().epem() * self.as_inner().ps() * self.as_inner().s()
+ operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().m() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().m() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().e1ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e1ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e1ep() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().e1ep() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().epem()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().epem()
* self.as_inner().m()
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().ps() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().epem()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.as_inner().e1ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e1ep() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e1ep() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().e1ep() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().e2ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e2ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e2ep() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().e2ep() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().epem()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().epem()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().m()
+ operand.as_inner().e2ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e2ep() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e2ep() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().e2ep() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().e1em() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().epem()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().epem()
* self.as_inner().m()
+ -T::TWO * operand.as_inner().e2ep() * self.as_inner().ps() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().ps()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().epem()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().e1em() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().e2em() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().epem()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().epem()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().m()
+ operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().e2em() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().epem() * self.as_inner().ps() * self.as_inner().ps())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2ep()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2ep()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().m() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.as_inner().m() * self.as_inner().epem() * self.as_inner().m()
+ operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().epem() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().epem() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Sandwich product: [`Motor`] x [`Pseudoscalar`] x rev([`Motor`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Pseudoscalar<T>> for Motor<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(self.e1em() * operand.ps() * self.e1em()) + self.e1ep() * operand.ps() * self.e1ep()
- self.e2em() * operand.ps() * self.e2em()
+ self.e2ep() * operand.ps() * self.e2ep()
- self.epem() * operand.ps() * self.epem()
+ self.m() * operand.ps() * self.m()
- self.ps() * operand.ps() * self.ps()
+ self.s() * operand.ps() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Pseudoscalar<T>> for Unit<Motor<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.ps() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ps() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.ps() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.ps() * self.as_inner().ps() * self.as_inner().ps())
+ operand.ps() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.ps() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.ps() * self.as_inner().m() * self.as_inner().m()
+ operand.ps() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Pseudoscalar<T>>> for Motor<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.e1em() * self.e1em())
+ -(operand.as_inner().ps() * self.e2em() * self.e2em())
+ -(operand.as_inner().ps() * self.epem() * self.epem())
+ -(operand.as_inner().ps() * self.ps() * self.ps())
+ operand.as_inner().ps() * self.e1ep() * self.e1ep()
+ operand.as_inner().ps() * self.e2ep() * self.e2ep()
+ operand.as_inner().ps() * self.m() * self.m()
+ operand.as_inner().ps() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Pseudoscalar<T>>> for Unit<Motor<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ps() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().ps() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().ps() * self.as_inner().ps() * self.as_inner().ps())
+ operand.as_inner().ps() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().ps() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().ps() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().ps() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Sandwich product: [`Motor`] x [`RoundPoint`] x rev([`Motor`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<RoundPoint<T>> for Motor<T> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(self.e1em() * operand.em() * self.s())
+ self.e1em() * operand.ep() * self.epem()
+ self.e1em() * operand.x() * self.e1em()
+ self.e1em() * operand.y() * self.e2em()
- self.e1ep() * operand.em() * self.epem()
+ self.e1ep() * operand.ep() * self.s()
- self.e1ep() * operand.x() * self.e1ep()
- self.e1ep() * operand.y() * self.e2ep()
- self.e2em() * operand.em() * self.m()
+ self.e2em() * operand.ep() * self.ps()
- self.e2em() * operand.x() * self.e2em()
+ self.e2em() * operand.y() * self.e1em()
- self.e2ep() * operand.em() * self.ps()
+ self.e2ep() * operand.ep() * self.m()
+ self.e2ep() * operand.x() * self.e2ep()
- self.e2ep() * operand.y() * self.e1ep()
- self.epem() * operand.em() * self.e1ep()
+ self.epem() * operand.ep() * self.e1em()
- self.epem() * operand.x() * self.epem()
- self.epem() * operand.y() * self.ps()
- self.m() * operand.em() * self.e2em()
+ self.m() * operand.ep() * self.e2ep()
- self.m() * operand.x() * self.m()
+ self.m() * operand.y() * self.s()
- self.ps() * operand.em() * self.e2ep()
+ self.ps() * operand.ep() * self.e2em()
+ self.ps() * operand.x() * self.ps()
- self.ps() * operand.y() * self.epem()
- self.s() * operand.em() * self.e1em()
+ self.s() * operand.ep() * self.e1ep()
+ self.s() * operand.x() * self.s()
+ self.s() * operand.y() * self.m(),
self.e1em() * operand.em() * self.m() - self.e1em() * operand.ep() * self.ps()
+ self.e1em() * operand.x() * self.e2em()
- self.e1em() * operand.y() * self.e1em()
+ self.e1ep() * operand.em() * self.ps()
- self.e1ep() * operand.ep() * self.m()
- self.e1ep() * operand.x() * self.e2ep()
+ self.e1ep() * operand.y() * self.e1ep()
- self.e2em() * operand.em() * self.s()
+ self.e2em() * operand.ep() * self.epem()
+ self.e2em() * operand.x() * self.e1em()
+ self.e2em() * operand.y() * self.e2em()
- self.e2ep() * operand.em() * self.epem()
+ self.e2ep() * operand.ep() * self.s()
- self.e2ep() * operand.x() * self.e1ep()
- self.e2ep() * operand.y() * self.e2ep()
- self.epem() * operand.em() * self.e2ep()
+ self.epem() * operand.ep() * self.e2em()
+ self.epem() * operand.x() * self.ps()
- self.epem() * operand.y() * self.epem()
+ self.m() * operand.em() * self.e1em()
- self.m() * operand.ep() * self.e1ep()
- self.m() * operand.x() * self.s()
- self.m() * operand.y() * self.m()
+ self.ps() * operand.em() * self.e1ep()
- self.ps() * operand.ep() * self.e1em()
+ self.ps() * operand.x() * self.epem()
+ self.ps() * operand.y() * self.ps()
- self.s() * operand.em() * self.e2em()
+ self.s() * operand.ep() * self.e2ep()
- self.s() * operand.x() * self.m()
+ self.s() * operand.y() * self.s(),
self.e1em() * operand.em() * self.e1ep() - self.e1em() * operand.ep() * self.e1em()
+ self.e1em() * operand.x() * self.epem()
+ self.e1em() * operand.y() * self.ps()
+ self.e1ep() * operand.em() * self.e1em()
- self.e1ep() * operand.ep() * self.e1ep()
- self.e1ep() * operand.x() * self.s()
- self.e1ep() * operand.y() * self.m()
+ self.e2em() * operand.em() * self.e2ep()
- self.e2em() * operand.ep() * self.e2em()
- self.e2em() * operand.x() * self.ps()
+ self.e2em() * operand.y() * self.epem()
+ self.e2ep() * operand.em() * self.e2em()
- self.e2ep() * operand.ep() * self.e2ep()
+ self.e2ep() * operand.x() * self.m()
- self.e2ep() * operand.y() * self.s()
- self.epem() * operand.em() * self.s()
+ self.epem() * operand.ep() * self.epem()
+ self.epem() * operand.x() * self.e1em()
+ self.epem() * operand.y() * self.e2em()
- self.m() * operand.em() * self.ps()
+ self.m() * operand.ep() * self.m()
+ self.m() * operand.x() * self.e2ep()
- self.m() * operand.y() * self.e1ep()
- self.ps() * operand.em() * self.m()
+ self.ps() * operand.ep() * self.ps()
- self.ps() * operand.x() * self.e2em()
+ self.ps() * operand.y() * self.e1em()
- self.s() * operand.em() * self.epem()
+ self.s() * operand.ep() * self.s()
- self.s() * operand.x() * self.e1ep()
- self.s() * operand.y() * self.e2ep(),
self.e1em() * operand.em() * self.e1em()
- self.e1em() * operand.ep() * self.e1ep()
- self.e1em() * operand.x() * self.s()
- self.e1em() * operand.y() * self.m()
+ self.e1ep() * operand.em() * self.e1ep()
- self.e1ep() * operand.ep() * self.e1em()
+ self.e1ep() * operand.x() * self.epem()
+ self.e1ep() * operand.y() * self.ps()
+ self.e2em() * operand.em() * self.e2em()
- self.e2em() * operand.ep() * self.e2ep()
+ self.e2em() * operand.x() * self.m()
- self.e2em() * operand.y() * self.s()
+ self.e2ep() * operand.em() * self.e2ep()
- self.e2ep() * operand.ep() * self.e2em()
- self.e2ep() * operand.x() * self.ps()
+ self.e2ep() * operand.y() * self.epem()
+ self.epem() * operand.em() * self.epem()
- self.epem() * operand.ep() * self.s()
+ self.epem() * operand.x() * self.e1ep()
+ self.epem() * operand.y() * self.e2ep()
+ self.m() * operand.em() * self.m()
- self.m() * operand.ep() * self.ps()
+ self.m() * operand.x() * self.e2em()
- self.m() * operand.y() * self.e1em()
+ self.ps() * operand.em() * self.ps()
- self.ps() * operand.ep() * self.m()
- self.ps() * operand.x() * self.e2ep()
+ self.ps() * operand.y() * self.e1ep()
+ self.s() * operand.em() * self.s()
- self.s() * operand.ep() * self.epem()
- self.s() * operand.x() * self.e1em()
- self.s() * operand.y() * self.e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<RoundPoint<T>> for Unit<Motor<T>> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.x() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.x() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.x() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.x() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.em() * self.as_inner().e1em() * self.as_inner().s()
+ -T::TWO * operand.em() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.em() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.em() * self.as_inner().e2ep() * self.as_inner().ps()
+ -T::TWO * operand.y() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.y() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO * operand.ep() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.ep() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.ep() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.ep() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.y() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.y() * self.as_inner().m() * self.as_inner().s()
+ operand.x() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.x() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.x() * self.as_inner().ps() * self.as_inner().ps()
+ operand.x() * self.as_inner().s() * self.as_inner().s(),
-(operand.y() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.y() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.y() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.y() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.em() * self.as_inner().e2em() * self.as_inner().s()
+ -T::TWO * operand.em() * self.as_inner().e2ep() * self.as_inner().epem()
+ -T::TWO * operand.ep() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.ep() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.x() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.x() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.em() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.em() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO * operand.ep() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.ep() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.x() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.x() * self.as_inner().epem() * self.as_inner().ps()
+ operand.y() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.y() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.y() * self.as_inner().ps() * self.as_inner().ps()
+ operand.y() * self.as_inner().s() * self.as_inner().s(),
-(operand.ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO * operand.em() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.em() * self.as_inner().m() * self.as_inner().ps()
+ -T::TWO * operand.x() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.x() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO * operand.y() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.y() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.x() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.x() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.y() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.y() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.ep() * self.as_inner().epem() * self.as_inner().epem()
+ operand.ep() * self.as_inner().m() * self.as_inner().m()
+ operand.ep() * self.as_inner().ps() * self.as_inner().ps()
+ operand.ep() * self.as_inner().s() * self.as_inner().s(),
-T::TWO * operand.ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.ep() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.ep() * self.as_inner().m() * self.as_inner().ps()
+ -T::TWO * operand.x() * self.as_inner().e1em() * self.as_inner().s()
+ -T::TWO * operand.x() * self.as_inner().e2ep() * self.as_inner().ps()
+ -T::TWO * operand.y() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.y() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.x() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.x() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.y() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO * operand.y() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.em() * self.as_inner().m() * self.as_inner().m()
+ operand.em() * self.as_inner().ps() * self.as_inner().ps()
+ operand.em() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<RoundPoint<T>>> for Motor<T> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().x() * self.e2em() * self.e2em())
+ -(operand.as_inner().x() * self.epem() * self.epem())
+ -(operand.as_inner().x() * self.m() * self.m())
+ -T::TWO * operand.as_inner().em() * self.e1em() * self.s()
+ -T::TWO * operand.as_inner().em() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().em() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().em() * self.e2ep() * self.ps()
+ -T::TWO * operand.as_inner().y() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().y() * self.epem() * self.ps()
+ T::TWO * operand.as_inner().ep() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().ep() * self.e1ep() * self.s()
+ T::TWO * operand.as_inner().ep() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().ep() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().y() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().y() * self.m() * self.s()
+ operand.as_inner().x() * self.e1em() * self.e1em()
+ operand.as_inner().x() * self.e2ep() * self.e2ep()
+ operand.as_inner().x() * self.ps() * self.ps()
+ operand.as_inner().x() * self.s() * self.s(),
-(operand.as_inner().y() * self.e1em() * self.e1em())
+ -(operand.as_inner().y() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().y() * self.epem() * self.epem())
+ -(operand.as_inner().y() * self.m() * self.m())
+ -T::TWO * operand.as_inner().em() * self.e2em() * self.s()
+ -T::TWO * operand.as_inner().em() * self.e2ep() * self.epem()
+ -T::TWO * operand.as_inner().ep() * self.e1em() * self.ps()
+ -T::TWO * operand.as_inner().ep() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().x() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().x() * self.m() * self.s()
+ T::TWO * operand.as_inner().em() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().em() * self.e1ep() * self.ps()
+ T::TWO * operand.as_inner().ep() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().ep() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().x() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().x() * self.epem() * self.ps()
+ operand.as_inner().y() * self.e1ep() * self.e1ep()
+ operand.as_inner().y() * self.e2em() * self.e2em()
+ operand.as_inner().y() * self.ps() * self.ps()
+ operand.as_inner().y() * self.s() * self.s(),
-(operand.as_inner().ep() * self.e1em() * self.e1em())
+ -(operand.as_inner().ep() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().ep() * self.e2em() * self.e2em())
+ -(operand.as_inner().ep() * self.e2ep() * self.e2ep())
+ -T::TWO * operand.as_inner().em() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().em() * self.m() * self.ps()
+ -T::TWO * operand.as_inner().x() * self.e1ep() * self.s()
+ -T::TWO * operand.as_inner().x() * self.e2em() * self.ps()
+ -T::TWO * operand.as_inner().y() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().y() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().em() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().em() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().x() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().x() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().y() * self.e1em() * self.ps()
+ T::TWO * operand.as_inner().y() * self.e2em() * self.epem()
+ operand.as_inner().ep() * self.epem() * self.epem()
+ operand.as_inner().ep() * self.m() * self.m()
+ operand.as_inner().ep() * self.ps() * self.ps()
+ operand.as_inner().ep() * self.s() * self.s(),
-T::TWO * operand.as_inner().ep() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().ep() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().ep() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().ep() * self.m() * self.ps()
+ -T::TWO * operand.as_inner().x() * self.e1em() * self.s()
+ -T::TWO * operand.as_inner().x() * self.e2ep() * self.ps()
+ -T::TWO * operand.as_inner().y() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().y() * self.e2em() * self.s()
+ T::TWO * operand.as_inner().x() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().x() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().y() * self.e1ep() * self.ps()
+ T::TWO * operand.as_inner().y() * self.e2ep() * self.epem()
+ operand.as_inner().em() * self.e1em() * self.e1em()
+ operand.as_inner().em() * self.e1ep() * self.e1ep()
+ operand.as_inner().em() * self.e2em() * self.e2em()
+ operand.as_inner().em() * self.e2ep() * self.e2ep()
+ operand.as_inner().em() * self.epem() * self.epem()
+ operand.as_inner().em() * self.m() * self.m()
+ operand.as_inner().em() * self.ps() * self.ps()
+ operand.as_inner().em() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<RoundPoint<T>>> for Unit<Motor<T>> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().x() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().x() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().x() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.as_inner().em() * self.as_inner().e1em() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().em()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().em() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.as_inner().em() * self.as_inner().e2ep() * self.as_inner().ps()
+ -T::TWO
* operand.as_inner().y()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().y() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().ep() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().ep() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.as_inner().ep() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.as_inner().y() * self.as_inner().m() * self.as_inner().s()
+ operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().x() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().x() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().x() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().y() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().y() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().y() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.as_inner().em() * self.as_inner().e2em() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().em()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().ep() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.as_inner().ep() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO
* operand.as_inner().x()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().x() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.as_inner().em() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.as_inner().em() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().ep() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.as_inner().x() * self.as_inner().epem() * self.as_inner().ps()
+ operand.as_inner().y() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().y() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().y() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().y() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO * operand.as_inner().em() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.as_inner().em() * self.as_inner().m() * self.as_inner().ps()
+ -T::TWO * operand.as_inner().x() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.as_inner().x() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO * operand.as_inner().y() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.as_inner().y() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO
* operand.as_inner().em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO
* operand.as_inner().em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.as_inner().x() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.as_inner().y() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.as_inner().ep() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().ep() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().ep() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().ep() * self.as_inner().s() * self.as_inner().s(),
-T::TWO * operand.as_inner().ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().ep() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.as_inner().ep() * self.as_inner().m() * self.as_inner().ps()
+ -T::TWO * operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().s()
+ -T::TWO * operand.as_inner().x() * self.as_inner().e2ep() * self.as_inner().ps()
+ -T::TWO * operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.as_inner().y() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.as_inner().x() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.as_inner().x() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.as_inner().y() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO * operand.as_inner().y() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.as_inner().em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().em() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().em() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().em() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Sandwich product: [`Motor`] x [`Scalar`] x rev([`Motor`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Scalar<T>> for Motor<T> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(self.e1em() * operand.s() * self.e1em()) + self.e1ep() * operand.s() * self.e1ep()
- self.e2em() * operand.s() * self.e2em()
+ self.e2ep() * operand.s() * self.e2ep()
- self.epem() * operand.s() * self.epem()
+ self.m() * operand.s() * self.m()
- self.ps() * operand.s() * self.ps()
+ self.s() * operand.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Scalar<T>> for Unit<Motor<T>> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.s() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.s() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.s() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.s() * self.as_inner().ps() * self.as_inner().ps())
+ operand.s() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.s() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.s() * self.as_inner().m() * self.as_inner().m()
+ operand.s() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Scalar<T>>> for Motor<T> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.e1em() * self.e1em())
+ -(operand.as_inner().s() * self.e2em() * self.e2em())
+ -(operand.as_inner().s() * self.epem() * self.epem())
+ -(operand.as_inner().s() * self.ps() * self.ps())
+ operand.as_inner().s() * self.e1ep() * self.e1ep()
+ operand.as_inner().s() * self.e2ep() * self.e2ep()
+ operand.as_inner().s() * self.m() * self.m()
+ operand.as_inner().s() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Scalar<T>>> for Unit<Motor<T>> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().s() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().s() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().s() * self.as_inner().ps() * self.as_inner().ps())
+ operand.as_inner().s() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().s() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().s() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().s() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Sandwich product: [`PointPair`] x [`Circle`] x rev([`PointPair`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Circle<T>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-(self.e1em() * operand.e12em() * self.e1ep())
+ self.e1em() * operand.e1epem() * self.m()
+ self.e1em() * operand.w() * self.e1em()
- self.e1ep() * operand.e12em() * self.e1em()
+ self.e1ep() * operand.e2epem() * self.epem()
+ self.e1ep() * operand.w() * self.e1ep()
- self.e2em() * operand.e12em() * self.e2ep()
+ self.e2em() * operand.e2epem() * self.m()
+ self.e2em() * operand.w() * self.e2em()
- self.e2ep() * operand.e12em() * self.e2em()
- self.e2ep() * operand.e1epem() * self.epem()
+ self.e2ep() * operand.w() * self.e2ep()
- self.epem() * operand.e1epem() * self.e2ep()
+ self.epem() * operand.e2epem() * self.e1ep()
+ self.epem() * operand.w() * self.epem()
+ self.m() * operand.e1epem() * self.e1em()
+ self.m() * operand.e2epem() * self.e2em()
+ self.m() * operand.w() * self.m(),
-(self.e1em() * operand.e12em() * self.e1em())
+ self.e1em() * operand.e2epem() * self.epem()
+ self.e1em() * operand.w() * self.e1ep()
- self.e1ep() * operand.e12em() * self.e1ep()
+ self.e1ep() * operand.e1epem() * self.m()
+ self.e1ep() * operand.w() * self.e1em()
- self.e2em() * operand.e12em() * self.e2em()
- self.e2em() * operand.e1epem() * self.epem()
+ self.e2em() * operand.w() * self.e2ep()
- self.e2ep() * operand.e12em() * self.e2ep()
+ self.e2ep() * operand.e2epem() * self.m()
+ self.e2ep() * operand.w() * self.e2em()
+ self.epem() * operand.e12em() * self.epem()
- self.epem() * operand.e1epem() * self.e2em()
+ self.epem() * operand.e2epem() * self.e1em()
+ self.m() * operand.e12em() * self.m()
+ self.m() * operand.e1epem() * self.e1ep()
+ self.m() * operand.e2epem() * self.e2ep(),
-(self.e1em() * operand.e1epem() * self.e1em())
- self.e1em() * operand.e2epem() * self.e2em()
- self.e1em() * operand.w() * self.m()
+ self.e1ep() * operand.e12em() * self.m()
+ self.e1ep() * operand.e1epem() * self.e1ep()
+ self.e1ep() * operand.e2epem() * self.e2ep()
- self.e2em() * operand.e12em() * self.epem()
+ self.e2em() * operand.e1epem() * self.e2em()
- self.e2em() * operand.e2epem() * self.e1em()
- self.e2ep() * operand.e1epem() * self.e2ep()
+ self.e2ep() * operand.e2epem() * self.e1ep()
+ self.e2ep() * operand.w() * self.epem()
- self.epem() * operand.e12em() * self.e2em()
- self.epem() * operand.e1epem() * self.epem()
+ self.epem() * operand.w() * self.e2ep()
+ self.m() * operand.e12em() * self.e1ep()
- self.m() * operand.e1epem() * self.m()
- self.m() * operand.w() * self.e1em(),
self.e1em() * operand.e12em() * self.epem()
- self.e1em() * operand.e1epem() * self.e2em()
+ self.e1em() * operand.e2epem() * self.e1em()
+ self.e1ep() * operand.e1epem() * self.e2ep()
- self.e1ep() * operand.e2epem() * self.e1ep()
- self.e1ep() * operand.w() * self.epem()
- self.e2em() * operand.e1epem() * self.e1em()
- self.e2em() * operand.e2epem() * self.e2em()
- self.e2em() * operand.w() * self.m()
+ self.e2ep() * operand.e12em() * self.m()
+ self.e2ep() * operand.e1epem() * self.e1ep()
+ self.e2ep() * operand.e2epem() * self.e2ep()
+ self.epem() * operand.e12em() * self.e1em()
- self.epem() * operand.e2epem() * self.epem()
- self.epem() * operand.w() * self.e1ep()
+ self.m() * operand.e12em() * self.e2ep()
- self.m() * operand.e2epem() * self.m()
- self.m() * operand.w() * self.e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Circle<T>> for Unit<PointPair<T>> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.e12em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.e12em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.e1epem() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.e1epem() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.e2epem() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.e2epem() * self.as_inner().e2em() * self.as_inner().m()
+ operand.w() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.w() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.w() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.w() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.w() * self.as_inner().epem() * self.as_inner().epem()
+ operand.w() * self.as_inner().m() * self.as_inner().m(),
-(operand.e12em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e12em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e12em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e12em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO * operand.e1epem() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.e1epem() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e2epem() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e2epem() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.w() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.w() * self.as_inner().e2em() * self.as_inner().e2ep()
+ operand.e12em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.e12em() * self.as_inner().m() * self.as_inner().m(),
-(operand.e1epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e1epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e1epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e12em() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.e2epem() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.w() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.e12em() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e2epem() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.w() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.e1epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e1epem() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.e2epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e2epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e2epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e1epem() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.w() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.w() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.e12em() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e12em() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.e1epem() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ operand.e2epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e2epem() * self.as_inner().e2ep() * self.as_inner().e2ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Circle<T>>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.as_inner().e12em() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().e12em() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().e1epem() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().e1epem() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().e2epem() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().e2epem() * self.e2em() * self.m()
+ operand.as_inner().w() * self.e1em() * self.e1em()
+ operand.as_inner().w() * self.e1ep() * self.e1ep()
+ operand.as_inner().w() * self.e2em() * self.e2em()
+ operand.as_inner().w() * self.e2ep() * self.e2ep()
+ operand.as_inner().w() * self.epem() * self.epem()
+ operand.as_inner().w() * self.m() * self.m(),
-(operand.as_inner().e12em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e12em() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e12em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e12em() * self.e2ep() * self.e2ep())
+ -T::TWO * operand.as_inner().e1epem() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().e1epem() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e2epem() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e2epem() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().w() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().w() * self.e2em() * self.e2ep()
+ operand.as_inner().e12em() * self.epem() * self.epem()
+ operand.as_inner().e12em() * self.m() * self.m(),
-(operand.as_inner().e1epem() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1epem() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e1epem() * self.epem() * self.epem())
+ -(operand.as_inner().e1epem() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e12em() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().e2epem() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().w() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().e12em() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e2epem() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().w() * self.e2ep() * self.epem()
+ operand.as_inner().e1epem() * self.e1ep() * self.e1ep()
+ operand.as_inner().e1epem() * self.e2em() * self.e2em(),
-(operand.as_inner().e2epem() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e2epem() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2epem() * self.epem() * self.epem())
+ -(operand.as_inner().e2epem() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e1epem() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().w() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().w() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().e12em() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e12em() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().e1epem() * self.e1ep() * self.e2ep()
+ operand.as_inner().e2epem() * self.e1em() * self.e1em()
+ operand.as_inner().e2epem() * self.e2ep() * self.e2ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Circle<T>>> for Unit<PointPair<T>> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.as_inner().e12em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1em()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e2em()
* self.as_inner().m()
+ operand.as_inner().w() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().w() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().w() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().w() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().w() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().w() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().e12em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e12em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e12em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e12em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1ep()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e2ep()
* self.as_inner().m()
+ T::TWO * operand.as_inner().w() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.as_inner().w() * self.as_inner().e2em() * self.as_inner().e2ep()
+ operand.as_inner().e12em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().e12em() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().e1epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e1epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e1epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO * operand.as_inner().w() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e1ep()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().w() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.as_inner().e1epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e1epem() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().e2epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e2epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e2epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().w()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().w() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2ep()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ operand.as_inner().e2epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e2epem() * self.as_inner().e2ep() * self.as_inner().e2ep(),
)
}
}
#[doc = "Sandwich product: [`PointPair`] x [`FlatPoint`] x rev([`PointPair`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<FlatPoint<T>> for PointPair<T> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(self.e1em() * operand.e1em() * self.e1em())
- self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.epem() * self.epem()
- self.e1ep() * operand.e1em() * self.e1ep()
- self.e1ep() * operand.e2em() * self.e2ep()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e2em() * self.e1em()
+ self.e2ep() * operand.e1em() * self.e2ep()
- self.e2ep() * operand.e2em() * self.e1ep()
+ self.e2ep() * operand.epem() * self.m()
+ self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.epem() * self.e1em()
- self.m() * operand.e1em() * self.m()
+ self.m() * operand.epem() * self.e2ep(),
-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e2em() * self.e1em()
- self.e1ep() * operand.e1em() * self.e2ep()
+ self.e1ep() * operand.e2em() * self.e1ep()
- self.e1ep() * operand.epem() * self.m()
- self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.epem() * self.epem()
- self.e2ep() * operand.e1em() * self.e1ep()
- self.e2ep() * operand.e2em() * self.e2ep()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.epem() * self.e2em()
- self.m() * operand.e2em() * self.m()
- self.m() * operand.epem() * self.e1ep(),
-(self.e1em() * operand.e1em() * self.epem())
+ self.e1em() * operand.epem() * self.e1em()
- self.e1ep() * operand.e2em() * self.m()
- self.e1ep() * operand.epem() * self.e1ep()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.epem() * self.e2em()
+ self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.epem() * self.e2ep()
- self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.epem() * self.epem()
+ self.m() * operand.e1em() * self.e2ep()
- self.m() * operand.e2em() * self.e1ep()
+ self.m() * operand.epem() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<FlatPoint<T>> for Unit<PointPair<T>> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e1em() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().m()
+ operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e1em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e1em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e2em() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e2em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e2em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ operand.epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.epem() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.epem() * self.as_inner().m() * self.as_inner().m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<FlatPoint<T>>> for PointPair<T> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1em() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e1em() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().epem() * self.e2ep() * self.m()
+ operand.as_inner().e1em() * self.e2em() * self.e2em()
+ operand.as_inner().e1em() * self.e2ep() * self.e2ep()
+ operand.as_inner().e1em() * self.epem() * self.epem(),
-(operand.as_inner().e2em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2em() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e2em() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().epem() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ operand.as_inner().e2em() * self.e1em() * self.e1em()
+ operand.as_inner().e2em() * self.e1ep() * self.e1ep()
+ operand.as_inner().e2em() * self.epem() * self.epem(),
-(operand.as_inner().epem() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().epem() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().epem() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().e1em() * self.e2ep() * self.m()
+ operand.as_inner().epem() * self.e1em() * self.e1em()
+ operand.as_inner().epem() * self.e2em() * self.e2em()
+ operand.as_inner().epem() * self.m() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<FlatPoint<T>>> for Unit<PointPair<T>> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().m()
+ operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().epem() * self.as_inner().m() * self.as_inner().m(),
)
}
}
#[doc = "Sandwich product: [`PointPair`] x [`Line`] x rev([`PointPair`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Line<T>> for PointPair<T> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
self.e1em() * operand.d() * self.epem()
- self.e1em() * operand.nx() * self.e1em()
- self.e1ep() * operand.nx() * self.e1ep()
+ self.e1ep() * operand.ny() * self.m()
- self.e2em() * operand.nx() * self.e2em()
- self.e2em() * operand.ny() * self.epem()
+ self.e2ep() * operand.d() * self.m()
- self.e2ep() * operand.nx() * self.e2ep()
+ self.epem() * operand.d() * self.e1em()
+ self.epem() * operand.nx() * self.epem()
- self.epem() * operand.ny() * self.e2em()
+ self.m() * operand.d() * self.e2ep()
+ self.m() * operand.nx() * self.m()
+ self.m() * operand.ny() * self.e1ep(),
-(self.e1em() * operand.d() * self.e2em()) - self.e1em() * operand.ny() * self.e1em()
+ self.e1ep() * operand.d() * self.e2ep()
+ self.e1ep() * operand.nx() * self.m()
+ self.e1ep() * operand.ny() * self.e1ep()
- self.e2em() * operand.d() * self.e1em()
- self.e2em() * operand.nx() * self.epem()
+ self.e2em() * operand.ny() * self.e2em()
+ self.e2ep() * operand.d() * self.e1ep()
- self.e2ep() * operand.ny() * self.e2ep()
- self.epem() * operand.nx() * self.e2em()
- self.epem() * operand.ny() * self.epem()
+ self.m() * operand.nx() * self.e1ep()
- self.m() * operand.ny() * self.m(),
self.e1em() * operand.d() * self.e1em() + self.e1em() * operand.nx() * self.epem()
- self.e1em() * operand.ny() * self.e2em()
- self.e1ep() * operand.d() * self.e1ep()
+ self.e1ep() * operand.ny() * self.e2ep()
- self.e2em() * operand.d() * self.e2em()
- self.e2em() * operand.ny() * self.e1em()
+ self.e2ep() * operand.d() * self.e2ep()
+ self.e2ep() * operand.nx() * self.m()
+ self.e2ep() * operand.ny() * self.e1ep()
- self.epem() * operand.d() * self.epem()
+ self.epem() * operand.nx() * self.e1em()
- self.m() * operand.d() * self.m()
+ self.m() * operand.nx() * self.e2ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Line<T>> for Unit<PointPair<T>> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(operand.nx() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.nx() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.nx() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.nx() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO * operand.ny() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.d() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.d() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.ny() * self.as_inner().e1ep() * self.as_inner().m()
+ operand.nx() * self.as_inner().epem() * self.as_inner().epem()
+ operand.nx() * self.as_inner().m() * self.as_inner().m(),
-(operand.ny() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ny() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.ny() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.ny() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.d() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.nx() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.d() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.nx() * self.as_inner().e1ep() * self.as_inner().m()
+ operand.ny() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.ny() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.d() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.d() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.d() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.d() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.ny() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.nx() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.nx() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.ny() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ operand.d() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.d() * self.as_inner().e2ep() * self.as_inner().e2ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Line<T>>> for PointPair<T> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.e1em() * self.e1em())
+ -(operand.as_inner().nx() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().nx() * self.e2em() * self.e2em())
+ -(operand.as_inner().nx() * self.e2ep() * self.e2ep())
+ -T::TWO * operand.as_inner().ny() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().d() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().d() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().ny() * self.e1ep() * self.m()
+ operand.as_inner().nx() * self.epem() * self.epem()
+ operand.as_inner().nx() * self.m() * self.m(),
-(operand.as_inner().ny() * self.e1em() * self.e1em())
+ -(operand.as_inner().ny() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().ny() * self.epem() * self.epem())
+ -(operand.as_inner().ny() * self.m() * self.m())
+ -T::TWO * operand.as_inner().d() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().nx() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().d() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().nx() * self.e1ep() * self.m()
+ operand.as_inner().ny() * self.e1ep() * self.e1ep()
+ operand.as_inner().ny() * self.e2em() * self.e2em(),
-(operand.as_inner().d() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().d() * self.e2em() * self.e2em())
+ -(operand.as_inner().d() * self.epem() * self.epem())
+ -(operand.as_inner().d() * self.m() * self.m())
+ -T::TWO * operand.as_inner().ny() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().nx() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().nx() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().ny() * self.e1ep() * self.e2ep()
+ operand.as_inner().d() * self.e1em() * self.e1em()
+ operand.as_inner().d() * self.e2ep() * self.e2ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Line<T>>> for Unit<PointPair<T>> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().nx() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().nx() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().nx() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO
* operand.as_inner().ny()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().d() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.as_inner().d() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().ny() * self.as_inner().e1ep() * self.as_inner().m()
+ operand.as_inner().nx() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().nx() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().ny() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ny() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().ny() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().ny() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().d()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().nx()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().d() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.as_inner().nx() * self.as_inner().e1ep() * self.as_inner().m()
+ operand.as_inner().ny() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().ny() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().d() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().d() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().d() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().d() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().ny()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().nx()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().nx() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().ny()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ operand.as_inner().d() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().d() * self.as_inner().e2ep() * self.as_inner().e2ep(),
)
}
}
#[doc = "Sandwich product: [`PointPair`] x [`Motor`] x rev([`PointPair`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Motor<T>> for PointPair<T> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(self.e1em() * operand.e1ep() * self.epem())
+ self.e1em() * operand.e2em() * self.m()
+ self.e1em() * operand.epem() * self.e1ep()
- self.e1em() * operand.m() * self.e2em()
+ self.e1em() * operand.ps() * self.e2ep()
- self.e1em() * operand.s() * self.e1em()
+ self.e1ep() * operand.e1em() * self.epem()
- self.e1ep() * operand.e2ep() * self.m()
- self.e1ep() * operand.epem() * self.e1em()
+ self.e1ep() * operand.m() * self.e2ep()
- self.e1ep() * operand.ps() * self.e2em()
+ self.e1ep() * operand.s() * self.e1ep()
- self.e2em() * operand.e1em() * self.m()
- self.e2em() * operand.e2ep() * self.epem()
+ self.e2em() * operand.epem() * self.e2ep()
+ self.e2em() * operand.m() * self.e1em()
- self.e2em() * operand.ps() * self.e1ep()
- self.e2em() * operand.s() * self.e2em()
+ self.e2ep() * operand.e1ep() * self.m()
+ self.e2ep() * operand.e2em() * self.epem()
- self.e2ep() * operand.epem() * self.e2em()
- self.e2ep() * operand.m() * self.e1ep()
+ self.e2ep() * operand.ps() * self.e1em()
+ self.e2ep() * operand.s() * self.e2ep()
- self.epem() * operand.e1em() * self.e1ep()
+ self.epem() * operand.e1ep() * self.e1em()
- self.epem() * operand.e2em() * self.e2ep()
+ self.epem() * operand.e2ep() * self.e2em()
+ self.epem() * operand.ps() * self.m()
- self.epem() * operand.s() * self.epem()
+ self.m() * operand.e1em() * self.e2em()
- self.m() * operand.e1ep() * self.e2ep()
- self.m() * operand.e2em() * self.e1em()
+ self.m() * operand.e2ep() * self.e1ep()
+ self.m() * operand.ps() * self.epem()
+ self.m() * operand.s() * self.m(),
-(self.e1em() * operand.e1em() * self.m()) - self.e1em() * operand.e2ep() * self.epem()
+ self.e1em() * operand.epem() * self.e2ep()
+ self.e1em() * operand.m() * self.e1em()
- self.e1em() * operand.ps() * self.e1ep()
- self.e1em() * operand.s() * self.e2em()
+ self.e1ep() * operand.e1ep() * self.m()
+ self.e1ep() * operand.e2em() * self.epem()
- self.e1ep() * operand.epem() * self.e2em()
- self.e1ep() * operand.m() * self.e1ep()
+ self.e1ep() * operand.ps() * self.e1em()
+ self.e1ep() * operand.s() * self.e2ep()
+ self.e2em() * operand.e1ep() * self.epem()
- self.e2em() * operand.e2em() * self.m()
- self.e2em() * operand.epem() * self.e1ep()
+ self.e2em() * operand.m() * self.e2em()
- self.e2em() * operand.ps() * self.e2ep()
+ self.e2em() * operand.s() * self.e1em()
- self.e2ep() * operand.e1em() * self.epem()
+ self.e2ep() * operand.e2ep() * self.m()
+ self.e2ep() * operand.epem() * self.e1em()
- self.e2ep() * operand.m() * self.e2ep()
+ self.e2ep() * operand.ps() * self.e2em()
- self.e2ep() * operand.s() * self.e1ep()
- self.epem() * operand.e1em() * self.e2ep()
+ self.epem() * operand.e1ep() * self.e2em()
+ self.epem() * operand.e2em() * self.e1ep()
- self.epem() * operand.e2ep() * self.e1em()
- self.epem() * operand.epem() * self.m()
- self.epem() * operand.m() * self.epem()
- self.m() * operand.e1em() * self.e1em()
+ self.m() * operand.e1ep() * self.e1ep()
- self.m() * operand.e2em() * self.e2em()
+ self.m() * operand.e2ep() * self.e2ep()
- self.m() * operand.epem() * self.epem()
+ self.m() * operand.m() * self.m(),
-(self.e1em() * operand.e1em() * self.e1ep())
+ self.e1em() * operand.e1ep() * self.e1em()
- self.e1em() * operand.e2em() * self.e2ep()
+ self.e1em() * operand.e2ep() * self.e2em()
+ self.e1em() * operand.ps() * self.m()
- self.e1em() * operand.s() * self.epem()
- self.e1ep() * operand.e1em() * self.e1em()
+ self.e1ep() * operand.e1ep() * self.e1ep()
- self.e1ep() * operand.e2em() * self.e2em()
+ self.e1ep() * operand.e2ep() * self.e2ep()
- self.e1ep() * operand.epem() * self.epem()
+ self.e1ep() * operand.m() * self.m()
+ self.e2em() * operand.e1em() * self.e2ep()
- self.e2em() * operand.e1ep() * self.e2em()
- self.e2em() * operand.e2em() * self.e1ep()
+ self.e2em() * operand.e2ep() * self.e1em()
+ self.e2em() * operand.epem() * self.m()
+ self.e2em() * operand.m() * self.epem()
+ self.e2ep() * operand.e1em() * self.e2em()
- self.e2ep() * operand.e1ep() * self.e2ep()
- self.e2ep() * operand.e2em() * self.e1em()
+ self.e2ep() * operand.e2ep() * self.e1ep()
+ self.e2ep() * operand.ps() * self.epem()
+ self.e2ep() * operand.s() * self.m()
+ self.epem() * operand.e1ep() * self.epem()
- self.epem() * operand.e2em() * self.m()
- self.epem() * operand.epem() * self.e1ep()
+ self.epem() * operand.m() * self.e2em()
- self.epem() * operand.ps() * self.e2ep()
+ self.epem() * operand.s() * self.e1em()
- self.m() * operand.e1ep() * self.m()
- self.m() * operand.e2em() * self.epem()
+ self.m() * operand.epem() * self.e2em()
+ self.m() * operand.m() * self.e1ep()
- self.m() * operand.ps() * self.e1em()
- self.m() * operand.s() * self.e2ep(),
-(self.e1em() * operand.e1em() * self.e2ep())
+ self.e1em() * operand.e1ep() * self.e2em()
+ self.e1em() * operand.e2em() * self.e1ep()
- self.e1em() * operand.e2ep() * self.e1em()
- self.e1em() * operand.epem() * self.m()
- self.e1em() * operand.m() * self.epem()
- self.e1ep() * operand.e1em() * self.e2em()
+ self.e1ep() * operand.e1ep() * self.e2ep()
+ self.e1ep() * operand.e2em() * self.e1em()
- self.e1ep() * operand.e2ep() * self.e1ep()
- self.e1ep() * operand.ps() * self.epem()
- self.e1ep() * operand.s() * self.m()
- self.e2em() * operand.e1em() * self.e1ep()
+ self.e2em() * operand.e1ep() * self.e1em()
- self.e2em() * operand.e2em() * self.e2ep()
+ self.e2em() * operand.e2ep() * self.e2em()
+ self.e2em() * operand.ps() * self.m()
- self.e2em() * operand.s() * self.epem()
- self.e2ep() * operand.e1em() * self.e1em()
+ self.e2ep() * operand.e1ep() * self.e1ep()
- self.e2ep() * operand.e2em() * self.e2em()
+ self.e2ep() * operand.e2ep() * self.e2ep()
- self.e2ep() * operand.epem() * self.epem()
+ self.e2ep() * operand.m() * self.m()
+ self.epem() * operand.e1em() * self.m()
+ self.epem() * operand.e2ep() * self.epem()
- self.epem() * operand.epem() * self.e2ep()
- self.epem() * operand.m() * self.e1em()
+ self.epem() * operand.ps() * self.e1ep()
+ self.epem() * operand.s() * self.e2em()
+ self.m() * operand.e1em() * self.epem()
- self.m() * operand.e2ep() * self.m()
- self.m() * operand.epem() * self.e1em()
+ self.m() * operand.m() * self.e2ep()
- self.m() * operand.ps() * self.e2em()
+ self.m() * operand.s() * self.e1ep(),
-(self.e1em() * operand.e1em() * self.e1em())
+ self.e1em() * operand.e1ep() * self.e1ep()
- self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.e2ep() * self.e2ep()
- self.e1em() * operand.epem() * self.epem()
+ self.e1em() * operand.m() * self.m()
- self.e1ep() * operand.e1em() * self.e1ep()
+ self.e1ep() * operand.e1ep() * self.e1em()
- self.e1ep() * operand.e2em() * self.e2ep()
+ self.e1ep() * operand.e2ep() * self.e2em()
+ self.e1ep() * operand.ps() * self.m()
- self.e1ep() * operand.s() * self.epem()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e1ep() * self.e2ep()
- self.e2em() * operand.e2em() * self.e1em()
+ self.e2em() * operand.e2ep() * self.e1ep()
+ self.e2em() * operand.ps() * self.epem()
+ self.e2em() * operand.s() * self.m()
+ self.e2ep() * operand.e1em() * self.e2ep()
- self.e2ep() * operand.e1ep() * self.e2em()
- self.e2ep() * operand.e2em() * self.e1ep()
+ self.e2ep() * operand.e2ep() * self.e1em()
+ self.e2ep() * operand.epem() * self.m()
+ self.e2ep() * operand.m() * self.epem()
+ self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.e2ep() * self.m()
- self.epem() * operand.epem() * self.e1em()
+ self.epem() * operand.m() * self.e2ep()
- self.epem() * operand.ps() * self.e2em()
+ self.epem() * operand.s() * self.e1ep()
- self.m() * operand.e1em() * self.m()
- self.m() * operand.e2ep() * self.epem()
+ self.m() * operand.epem() * self.e2ep()
+ self.m() * operand.m() * self.e1em()
- self.m() * operand.ps() * self.e1ep()
- self.m() * operand.s() * self.e2em(),
-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e1ep() * self.e2ep()
+ self.e1em() * operand.e2em() * self.e1em()
- self.e1em() * operand.e2ep() * self.e1ep()
- self.e1em() * operand.ps() * self.epem()
- self.e1em() * operand.s() * self.m()
- self.e1ep() * operand.e1em() * self.e2ep()
+ self.e1ep() * operand.e1ep() * self.e2em()
+ self.e1ep() * operand.e2em() * self.e1ep()
- self.e1ep() * operand.e2ep() * self.e1em()
- self.e1ep() * operand.epem() * self.m()
- self.e1ep() * operand.m() * self.epem()
- self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e1ep() * self.e1ep()
- self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.e2ep() * self.e2ep()
- self.e2em() * operand.epem() * self.epem()
+ self.e2em() * operand.m() * self.m()
- self.e2ep() * operand.e1em() * self.e1ep()
+ self.e2ep() * operand.e1ep() * self.e1em()
- self.e2ep() * operand.e2em() * self.e2ep()
+ self.e2ep() * operand.e2ep() * self.e2em()
+ self.e2ep() * operand.ps() * self.m()
- self.e2ep() * operand.s() * self.epem()
+ self.epem() * operand.e1ep() * self.m()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.epem() * self.e2em()
- self.epem() * operand.m() * self.e1ep()
+ self.epem() * operand.ps() * self.e1em()
+ self.epem() * operand.s() * self.e2ep()
+ self.m() * operand.e1ep() * self.epem()
- self.m() * operand.e2em() * self.m()
- self.m() * operand.epem() * self.e1ep()
+ self.m() * operand.m() * self.e2em()
- self.m() * operand.ps() * self.e2ep()
+ self.m() * operand.s() * self.e1em(),
-(self.e1em() * operand.e1em() * self.epem())
+ self.e1em() * operand.e2ep() * self.m()
+ self.e1em() * operand.epem() * self.e1em()
- self.e1em() * operand.m() * self.e2ep()
+ self.e1em() * operand.ps() * self.e2em()
- self.e1em() * operand.s() * self.e1ep()
+ self.e1ep() * operand.e1ep() * self.epem()
- self.e1ep() * operand.e2em() * self.m()
- self.e1ep() * operand.epem() * self.e1ep()
+ self.e1ep() * operand.m() * self.e2em()
- self.e1ep() * operand.ps() * self.e2ep()
+ self.e1ep() * operand.s() * self.e1em()
- self.e2em() * operand.e1ep() * self.m()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.epem() * self.e2em()
+ self.e2em() * operand.m() * self.e1ep()
- self.e2em() * operand.ps() * self.e1em()
- self.e2em() * operand.s() * self.e2ep()
+ self.e2ep() * operand.e1em() * self.m()
+ self.e2ep() * operand.e2ep() * self.epem()
- self.e2ep() * operand.epem() * self.e2ep()
- self.e2ep() * operand.m() * self.e1em()
+ self.e2ep() * operand.ps() * self.e1ep()
+ self.e2ep() * operand.s() * self.e2em()
- self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e1ep() * self.e1ep()
- self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.e2ep() * self.e2ep()
- self.epem() * operand.epem() * self.epem()
+ self.epem() * operand.m() * self.m()
+ self.m() * operand.e1em() * self.e2ep()
- self.m() * operand.e1ep() * self.e2em()
- self.m() * operand.e2em() * self.e1ep()
+ self.m() * operand.e2ep() * self.e1em()
+ self.m() * operand.epem() * self.m()
+ self.m() * operand.m() * self.epem(),
-(self.e1em() * operand.e1ep() * self.m()) - self.e1em() * operand.e2em() * self.epem()
+ self.e1em() * operand.epem() * self.e2em()
+ self.e1em() * operand.m() * self.e1ep()
- self.e1em() * operand.ps() * self.e1em()
- self.e1em() * operand.s() * self.e2ep()
+ self.e1ep() * operand.e1em() * self.m()
+ self.e1ep() * operand.e2ep() * self.epem()
- self.e1ep() * operand.epem() * self.e2ep()
- self.e1ep() * operand.m() * self.e1em()
+ self.e1ep() * operand.ps() * self.e1ep()
+ self.e1ep() * operand.s() * self.e2em()
+ self.e2em() * operand.e1em() * self.epem()
- self.e2em() * operand.e2ep() * self.m()
- self.e2em() * operand.epem() * self.e1em()
+ self.e2em() * operand.m() * self.e2ep()
- self.e2em() * operand.ps() * self.e2em()
+ self.e2em() * operand.s() * self.e1ep()
- self.e2ep() * operand.e1ep() * self.epem()
+ self.e2ep() * operand.e2em() * self.m()
+ self.e2ep() * operand.epem() * self.e1ep()
- self.e2ep() * operand.m() * self.e2em()
+ self.e2ep() * operand.ps() * self.e2ep()
- self.e2ep() * operand.s() * self.e1em()
- self.epem() * operand.e1em() * self.e2em()
+ self.epem() * operand.e1ep() * self.e2ep()
+ self.epem() * operand.e2em() * self.e1em()
- self.epem() * operand.e2ep() * self.e1ep()
- self.epem() * operand.ps() * self.epem()
- self.epem() * operand.s() * self.m()
- self.m() * operand.e1em() * self.e1ep()
+ self.m() * operand.e1ep() * self.e1em()
- self.m() * operand.e2em() * self.e2ep()
+ self.m() * operand.e2ep() * self.e2em()
+ self.m() * operand.ps() * self.m()
- self.m() * operand.s() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Motor<T>> for Unit<PointPair<T>> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(operand.s() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.s() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.s() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.ps() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.ps() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.ps() * self.as_inner().epem() * self.as_inner().m()
+ operand.s() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.s() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.s() * self.as_inner().m() * self.as_inner().m(),
-(operand.m() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.m() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.m() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().epem()
+ -T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.epem() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.e2ep() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().e2ep()
+ operand.m() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.m() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.m() * self.as_inner().m() * self.as_inner().m(),
-(operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e1ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e1ep() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e1ep() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e2ep() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().m()
+ operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e2ep() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e2ep() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e1em() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.e2ep() * self.as_inner().epem() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e1em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e1em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e2em() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.e1ep() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().m()
+ operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e2em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e2em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.e2ep() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.m() * self.as_inner().epem() * self.as_inner().m()
+ operand.epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.epem() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.epem() * self.as_inner().m() * self.as_inner().m(),
-(operand.ps() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ps() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.ps() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.s() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.s() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.s() * self.as_inner().e1ep() * self.as_inner().e2em()
+ operand.ps() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.ps() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.ps() * self.as_inner().m() * self.as_inner().m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Motor<T>>> for PointPair<T> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.e1em() * self.e1em())
+ -(operand.as_inner().s() * self.e2em() * self.e2em())
+ -(operand.as_inner().s() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().ps() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().ps() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().ps() * self.epem() * self.m()
+ operand.as_inner().s() * self.e1ep() * self.e1ep()
+ operand.as_inner().s() * self.e2ep() * self.e2ep()
+ operand.as_inner().s() * self.m() * self.m(),
-(operand.as_inner().m() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().m() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().m() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().e1em() * self.e2ep() * self.epem()
+ -T::TWO * operand.as_inner().e2em() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().epem() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().epem() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e1ep() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().e2ep() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.e2ep()
+ operand.as_inner().m() * self.e1em() * self.e1em()
+ operand.as_inner().m() * self.e2em() * self.e2em()
+ operand.as_inner().m() * self.m() * self.m(),
-(operand.as_inner().e1ep() * self.e2em() * self.e2em())
+ -(operand.as_inner().e1ep() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e1ep() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().e2em() * self.epem() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().e1em() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().epem() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().m() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().m() * self.e2em() * self.epem()
+ operand.as_inner().e1ep() * self.e1em() * self.e1em()
+ operand.as_inner().e1ep() * self.e1ep() * self.e1ep()
+ operand.as_inner().e1ep() * self.epem() * self.epem(),
-(operand.as_inner().e2ep() * self.e1em() * self.e1em())
+ -(operand.as_inner().e2ep() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e2ep() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().e2em() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().epem() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e2ep() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e1em() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().m() * self.e2ep() * self.m()
+ operand.as_inner().e2ep() * self.e2em() * self.e2em()
+ operand.as_inner().e2ep() * self.e2ep() * self.e2ep()
+ operand.as_inner().e2ep() * self.epem() * self.epem(),
-(operand.as_inner().e1em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1em() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e1em() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e1ep() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().e2ep() * self.epem() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().epem() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().m() * self.e2ep() * self.epem()
+ operand.as_inner().e1em() * self.e2em() * self.e2em()
+ operand.as_inner().e1em() * self.e2ep() * self.e2ep()
+ operand.as_inner().e1em() * self.epem() * self.epem(),
-(operand.as_inner().e2em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2em() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e2em() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().epem() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().e1ep() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e2ep() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().m() * self.e2em() * self.m()
+ operand.as_inner().e2em() * self.e1em() * self.e1em()
+ operand.as_inner().e2em() * self.e1ep() * self.e1ep()
+ operand.as_inner().e2em() * self.epem() * self.epem(),
-(operand.as_inner().epem() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().epem() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().epem() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().e1ep() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e1em() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().e2ep() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().m() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().m() * self.epem() * self.m()
+ operand.as_inner().epem() * self.e1em() * self.e1em()
+ operand.as_inner().epem() * self.e2em() * self.e2em()
+ operand.as_inner().epem() * self.m() * self.m(),
-(operand.as_inner().ps() * self.e1em() * self.e1em())
+ -(operand.as_inner().ps() * self.e2em() * self.e2em())
+ -(operand.as_inner().ps() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().s() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().s() * self.epem() * self.m()
+ T::TWO * operand.as_inner().s() * self.e1ep() * self.e2em()
+ operand.as_inner().ps() * self.e1ep() * self.e1ep()
+ operand.as_inner().ps() * self.e2ep() * self.e2ep()
+ operand.as_inner().ps() * self.m() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Motor<T>>> for Unit<PointPair<T>> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().s() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().s() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().ps()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().ps()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().ps() * self.as_inner().epem() * self.as_inner().m()
+ operand.as_inner().s() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().s() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().s() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().m() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().epem()
* self.as_inner().m()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().m() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().e1ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e1ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e1ep() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().epem()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.as_inner().e1ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e1ep() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e1ep() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e2ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e2ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e2ep() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().m()
+ operand.as_inner().e2ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e2ep() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e2ep() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().epem()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().m()
+ operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.as_inner().m() * self.as_inner().epem() * self.as_inner().m()
+ operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().epem() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().ps() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ps() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().ps() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().s()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().s() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.as_inner().s() * self.as_inner().e1ep() * self.as_inner().e2em()
+ operand.as_inner().ps() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().ps() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().ps() * self.as_inner().m() * self.as_inner().m(),
)
}
}
#[doc = "Sandwich product: [`PointPair`] x [`PointPair`] x rev([`PointPair`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<PointPair<T>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(self.e1em() * operand.e1em() * self.m()) - self.e1em() * operand.e2ep() * self.epem()
+ self.e1em() * operand.epem() * self.e2ep()
+ self.e1em() * operand.m() * self.e1em()
+ self.e1ep() * operand.e1ep() * self.m()
+ self.e1ep() * operand.e2em() * self.epem()
- self.e1ep() * operand.epem() * self.e2em()
- self.e1ep() * operand.m() * self.e1ep()
+ self.e2em() * operand.e1ep() * self.epem()
- self.e2em() * operand.e2em() * self.m()
- self.e2em() * operand.epem() * self.e1ep()
+ self.e2em() * operand.m() * self.e2em()
- self.e2ep() * operand.e1em() * self.epem()
+ self.e2ep() * operand.e2ep() * self.m()
+ self.e2ep() * operand.epem() * self.e1em()
- self.e2ep() * operand.m() * self.e2ep()
- self.epem() * operand.e1em() * self.e2ep()
+ self.epem() * operand.e1ep() * self.e2em()
+ self.epem() * operand.e2em() * self.e1ep()
- self.epem() * operand.e2ep() * self.e1em()
- self.epem() * operand.epem() * self.m()
- self.epem() * operand.m() * self.epem()
- self.m() * operand.e1em() * self.e1em()
+ self.m() * operand.e1ep() * self.e1ep()
- self.m() * operand.e2em() * self.e2em()
+ self.m() * operand.e2ep() * self.e2ep()
- self.m() * operand.epem() * self.epem()
+ self.m() * operand.m() * self.m(),
-(self.e1em() * operand.e1em() * self.e1ep())
+ self.e1em() * operand.e1ep() * self.e1em()
- self.e1em() * operand.e2em() * self.e2ep()
+ self.e1em() * operand.e2ep() * self.e2em()
- self.e1ep() * operand.e1em() * self.e1em()
+ self.e1ep() * operand.e1ep() * self.e1ep()
- self.e1ep() * operand.e2em() * self.e2em()
+ self.e1ep() * operand.e2ep() * self.e2ep()
- self.e1ep() * operand.epem() * self.epem()
+ self.e1ep() * operand.m() * self.m()
+ self.e2em() * operand.e1em() * self.e2ep()
- self.e2em() * operand.e1ep() * self.e2em()
- self.e2em() * operand.e2em() * self.e1ep()
+ self.e2em() * operand.e2ep() * self.e1em()
+ self.e2em() * operand.epem() * self.m()
+ self.e2em() * operand.m() * self.epem()
+ self.e2ep() * operand.e1em() * self.e2em()
- self.e2ep() * operand.e1ep() * self.e2ep()
- self.e2ep() * operand.e2em() * self.e1em()
+ self.e2ep() * operand.e2ep() * self.e1ep()
+ self.epem() * operand.e1ep() * self.epem()
- self.epem() * operand.e2em() * self.m()
- self.epem() * operand.epem() * self.e1ep()
+ self.epem() * operand.m() * self.e2em()
- self.m() * operand.e1ep() * self.m()
- self.m() * operand.e2em() * self.epem()
+ self.m() * operand.epem() * self.e2em()
+ self.m() * operand.m() * self.e1ep(),
-(self.e1em() * operand.e1em() * self.e2ep())
+ self.e1em() * operand.e1ep() * self.e2em()
+ self.e1em() * operand.e2em() * self.e1ep()
- self.e1em() * operand.e2ep() * self.e1em()
- self.e1em() * operand.epem() * self.m()
- self.e1em() * operand.m() * self.epem()
- self.e1ep() * operand.e1em() * self.e2em()
+ self.e1ep() * operand.e1ep() * self.e2ep()
+ self.e1ep() * operand.e2em() * self.e1em()
- self.e1ep() * operand.e2ep() * self.e1ep()
- self.e2em() * operand.e1em() * self.e1ep()
+ self.e2em() * operand.e1ep() * self.e1em()
- self.e2em() * operand.e2em() * self.e2ep()
+ self.e2em() * operand.e2ep() * self.e2em()
- self.e2ep() * operand.e1em() * self.e1em()
+ self.e2ep() * operand.e1ep() * self.e1ep()
- self.e2ep() * operand.e2em() * self.e2em()
+ self.e2ep() * operand.e2ep() * self.e2ep()
- self.e2ep() * operand.epem() * self.epem()
+ self.e2ep() * operand.m() * self.m()
+ self.epem() * operand.e1em() * self.m()
+ self.epem() * operand.e2ep() * self.epem()
- self.epem() * operand.epem() * self.e2ep()
- self.epem() * operand.m() * self.e1em()
+ self.m() * operand.e1em() * self.epem()
- self.m() * operand.e2ep() * self.m()
- self.m() * operand.epem() * self.e1em()
+ self.m() * operand.m() * self.e2ep(),
-(self.e1em() * operand.e1em() * self.e1em())
+ self.e1em() * operand.e1ep() * self.e1ep()
- self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.e2ep() * self.e2ep()
- self.e1em() * operand.epem() * self.epem()
+ self.e1em() * operand.m() * self.m()
- self.e1ep() * operand.e1em() * self.e1ep()
+ self.e1ep() * operand.e1ep() * self.e1em()
- self.e1ep() * operand.e2em() * self.e2ep()
+ self.e1ep() * operand.e2ep() * self.e2em()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e1ep() * self.e2ep()
- self.e2em() * operand.e2em() * self.e1em()
+ self.e2em() * operand.e2ep() * self.e1ep()
+ self.e2ep() * operand.e1em() * self.e2ep()
- self.e2ep() * operand.e1ep() * self.e2em()
- self.e2ep() * operand.e2em() * self.e1ep()
+ self.e2ep() * operand.e2ep() * self.e1em()
+ self.e2ep() * operand.epem() * self.m()
+ self.e2ep() * operand.m() * self.epem()
+ self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.e2ep() * self.m()
- self.epem() * operand.epem() * self.e1em()
+ self.epem() * operand.m() * self.e2ep()
- self.m() * operand.e1em() * self.m()
- self.m() * operand.e2ep() * self.epem()
+ self.m() * operand.epem() * self.e2ep()
+ self.m() * operand.m() * self.e1em(),
-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e1ep() * self.e2ep()
+ self.e1em() * operand.e2em() * self.e1em()
- self.e1em() * operand.e2ep() * self.e1ep()
- self.e1ep() * operand.e1em() * self.e2ep()
+ self.e1ep() * operand.e1ep() * self.e2em()
+ self.e1ep() * operand.e2em() * self.e1ep()
- self.e1ep() * operand.e2ep() * self.e1em()
- self.e1ep() * operand.epem() * self.m()
- self.e1ep() * operand.m() * self.epem()
- self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e1ep() * self.e1ep()
- self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.e2ep() * self.e2ep()
- self.e2em() * operand.epem() * self.epem()
+ self.e2em() * operand.m() * self.m()
- self.e2ep() * operand.e1em() * self.e1ep()
+ self.e2ep() * operand.e1ep() * self.e1em()
- self.e2ep() * operand.e2em() * self.e2ep()
+ self.e2ep() * operand.e2ep() * self.e2em()
+ self.epem() * operand.e1ep() * self.m()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.epem() * self.e2em()
- self.epem() * operand.m() * self.e1ep()
+ self.m() * operand.e1ep() * self.epem()
- self.m() * operand.e2em() * self.m()
- self.m() * operand.epem() * self.e1ep()
+ self.m() * operand.m() * self.e2em(),
-(self.e1em() * operand.e1em() * self.epem())
+ self.e1em() * operand.e2ep() * self.m()
+ self.e1em() * operand.epem() * self.e1em()
- self.e1em() * operand.m() * self.e2ep()
+ self.e1ep() * operand.e1ep() * self.epem()
- self.e1ep() * operand.e2em() * self.m()
- self.e1ep() * operand.epem() * self.e1ep()
+ self.e1ep() * operand.m() * self.e2em()
- self.e2em() * operand.e1ep() * self.m()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.epem() * self.e2em()
+ self.e2em() * operand.m() * self.e1ep()
+ self.e2ep() * operand.e1em() * self.m()
+ self.e2ep() * operand.e2ep() * self.epem()
- self.e2ep() * operand.epem() * self.e2ep()
- self.e2ep() * operand.m() * self.e1em()
- self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e1ep() * self.e1ep()
- self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.e2ep() * self.e2ep()
- self.epem() * operand.epem() * self.epem()
+ self.epem() * operand.m() * self.m()
+ self.m() * operand.e1em() * self.e2ep()
- self.m() * operand.e1ep() * self.e2em()
- self.m() * operand.e2em() * self.e1ep()
+ self.m() * operand.e2ep() * self.e1em()
+ self.m() * operand.epem() * self.m()
+ self.m() * operand.m() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<PointPair<T>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.m() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.m() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.m() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().epem()
+ -T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.epem() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.e2ep() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().e2ep()
+ operand.m() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.m() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.m() * self.as_inner().m() * self.as_inner().m(),
-(operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e1ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e1ep() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e1ep() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e2ep() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().m()
+ operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e2ep() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e2ep() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e1em() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.e2ep() * self.as_inner().epem() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e1em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e1em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e2em() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.e1ep() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().m()
+ operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e2em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e2em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ -T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.e2ep() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.m() * self.as_inner().epem() * self.as_inner().m()
+ operand.epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.epem() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.epem() * self.as_inner().m() * self.as_inner().m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<PointPair<T>>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().m() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().m() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().e1em() * self.e2ep() * self.epem()
+ -T::TWO * operand.as_inner().e2em() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().epem() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().epem() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e1ep() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().e2ep() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.e2ep()
+ operand.as_inner().m() * self.e1em() * self.e1em()
+ operand.as_inner().m() * self.e2em() * self.e2em()
+ operand.as_inner().m() * self.m() * self.m(),
-(operand.as_inner().e1ep() * self.e2em() * self.e2em())
+ -(operand.as_inner().e1ep() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e1ep() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().e2em() * self.epem() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().e1em() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().epem() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().m() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().m() * self.e2em() * self.epem()
+ operand.as_inner().e1ep() * self.e1em() * self.e1em()
+ operand.as_inner().e1ep() * self.e1ep() * self.e1ep()
+ operand.as_inner().e1ep() * self.epem() * self.epem(),
-(operand.as_inner().e2ep() * self.e1em() * self.e1em())
+ -(operand.as_inner().e2ep() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e2ep() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().e2em() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().epem() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e2ep() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e1em() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().m() * self.e2ep() * self.m()
+ operand.as_inner().e2ep() * self.e2em() * self.e2em()
+ operand.as_inner().e2ep() * self.e2ep() * self.e2ep()
+ operand.as_inner().e2ep() * self.epem() * self.epem(),
-(operand.as_inner().e1em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1em() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e1em() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e1ep() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().e2ep() * self.epem() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().epem() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().m() * self.e2ep() * self.epem()
+ operand.as_inner().e1em() * self.e2em() * self.e2em()
+ operand.as_inner().e1em() * self.e2ep() * self.e2ep()
+ operand.as_inner().e1em() * self.epem() * self.epem(),
-(operand.as_inner().e2em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2em() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e2em() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().epem() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().e1ep() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e2ep() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().m() * self.e2em() * self.m()
+ operand.as_inner().e2em() * self.e1em() * self.e1em()
+ operand.as_inner().e2em() * self.e1ep() * self.e1ep()
+ operand.as_inner().e2em() * self.epem() * self.epem(),
-(operand.as_inner().epem() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().epem() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().epem() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ -T::TWO * operand.as_inner().e1ep() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e1em() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().e2ep() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().m() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().m() * self.epem() * self.m()
+ operand.as_inner().epem() * self.e1em() * self.e1em()
+ operand.as_inner().epem() * self.e2em() * self.e2em()
+ operand.as_inner().epem() * self.m() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<PointPair<T>>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().m() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().epem()
* self.as_inner().m()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().m() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().e1ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e1ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e1ep() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().epem()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.as_inner().e1ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e1ep() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e1ep() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e2ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e2ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e2ep() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().m()
+ operand.as_inner().e2ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e2ep() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e2ep() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().epem()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().m()
+ operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.as_inner().m() * self.as_inner().epem() * self.as_inner().m()
+ operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().epem() * self.as_inner().m() * self.as_inner().m(),
)
}
}
#[doc = "Sandwich product: [`PointPair`] x [`Pseudoscalar`] x rev([`PointPair`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Pseudoscalar<T>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(self.e1em() * operand.ps() * self.e1em()) + self.e1ep() * operand.ps() * self.e1ep()
- self.e2em() * operand.ps() * self.e2em()
+ self.e2ep() * operand.ps() * self.e2ep()
- self.epem() * operand.ps() * self.epem()
+ self.m() * operand.ps() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Pseudoscalar<T>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.ps() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ps() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.ps() * self.as_inner().epem() * self.as_inner().epem())
+ operand.ps() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.ps() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.ps() * self.as_inner().m() * self.as_inner().m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Pseudoscalar<T>>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.e1em() * self.e1em())
+ -(operand.as_inner().ps() * self.e2em() * self.e2em())
+ -(operand.as_inner().ps() * self.epem() * self.epem())
+ operand.as_inner().ps() * self.e1ep() * self.e1ep()
+ operand.as_inner().ps() * self.e2ep() * self.e2ep()
+ operand.as_inner().ps() * self.m() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Pseudoscalar<T>>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ps() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().ps() * self.as_inner().epem() * self.as_inner().epem())
+ operand.as_inner().ps() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().ps() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().ps() * self.as_inner().m() * self.as_inner().m(),
)
}
}
#[doc = "Sandwich product: [`PointPair`] x [`RoundPoint`] x rev([`PointPair`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<RoundPoint<T>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
self.e1em() * operand.ep() * self.epem()
+ self.e1em() * operand.x() * self.e1em()
+ self.e1em() * operand.y() * self.e2em()
- self.e1ep() * operand.em() * self.epem()
- self.e1ep() * operand.x() * self.e1ep()
- self.e1ep() * operand.y() * self.e2ep()
- self.e2em() * operand.em() * self.m()
- self.e2em() * operand.x() * self.e2em()
+ self.e2em() * operand.y() * self.e1em()
+ self.e2ep() * operand.ep() * self.m()
+ self.e2ep() * operand.x() * self.e2ep()
- self.e2ep() * operand.y() * self.e1ep()
- self.epem() * operand.em() * self.e1ep()
+ self.epem() * operand.ep() * self.e1em()
- self.epem() * operand.x() * self.epem()
- self.m() * operand.em() * self.e2em()
+ self.m() * operand.ep() * self.e2ep()
- self.m() * operand.x() * self.m(),
self.e1em() * operand.em() * self.m() + self.e1em() * operand.x() * self.e2em()
- self.e1em() * operand.y() * self.e1em()
- self.e1ep() * operand.ep() * self.m()
- self.e1ep() * operand.x() * self.e2ep()
+ self.e1ep() * operand.y() * self.e1ep()
+ self.e2em() * operand.ep() * self.epem()
+ self.e2em() * operand.x() * self.e1em()
+ self.e2em() * operand.y() * self.e2em()
- self.e2ep() * operand.em() * self.epem()
- self.e2ep() * operand.x() * self.e1ep()
- self.e2ep() * operand.y() * self.e2ep()
- self.epem() * operand.em() * self.e2ep()
+ self.epem() * operand.ep() * self.e2em()
- self.epem() * operand.y() * self.epem()
+ self.m() * operand.em() * self.e1em()
- self.m() * operand.ep() * self.e1ep()
- self.m() * operand.y() * self.m(),
self.e1em() * operand.em() * self.e1ep() - self.e1em() * operand.ep() * self.e1em()
+ self.e1em() * operand.x() * self.epem()
+ self.e1ep() * operand.em() * self.e1em()
- self.e1ep() * operand.ep() * self.e1ep()
- self.e1ep() * operand.y() * self.m()
+ self.e2em() * operand.em() * self.e2ep()
- self.e2em() * operand.ep() * self.e2em()
+ self.e2em() * operand.y() * self.epem()
+ self.e2ep() * operand.em() * self.e2em()
- self.e2ep() * operand.ep() * self.e2ep()
+ self.e2ep() * operand.x() * self.m()
+ self.epem() * operand.ep() * self.epem()
+ self.epem() * operand.x() * self.e1em()
+ self.epem() * operand.y() * self.e2em()
+ self.m() * operand.ep() * self.m()
+ self.m() * operand.x() * self.e2ep()
- self.m() * operand.y() * self.e1ep(),
self.e1em() * operand.em() * self.e1em()
- self.e1em() * operand.ep() * self.e1ep()
- self.e1em() * operand.y() * self.m()
+ self.e1ep() * operand.em() * self.e1ep()
- self.e1ep() * operand.ep() * self.e1em()
+ self.e1ep() * operand.x() * self.epem()
+ self.e2em() * operand.em() * self.e2em()
- self.e2em() * operand.ep() * self.e2ep()
+ self.e2em() * operand.x() * self.m()
+ self.e2ep() * operand.em() * self.e2ep()
- self.e2ep() * operand.ep() * self.e2em()
+ self.e2ep() * operand.y() * self.epem()
+ self.epem() * operand.em() * self.epem()
+ self.epem() * operand.x() * self.e1ep()
+ self.epem() * operand.y() * self.e2ep()
+ self.m() * operand.em() * self.m()
+ self.m() * operand.x() * self.e2em()
- self.m() * operand.y() * self.e1em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<RoundPoint<T>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.x() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.x() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.x() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.x() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.em() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.em() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.y() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.ep() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.ep() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.y() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.x() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.x() * self.as_inner().e2ep() * self.as_inner().e2ep(),
-(operand.y() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.y() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.y() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.y() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.em() * self.as_inner().e2ep() * self.as_inner().epem()
+ -T::TWO * operand.ep() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.x() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.em() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.ep() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.x() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.y() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.y() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO * operand.y() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.x() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.x() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.y() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.ep() * self.as_inner().epem() * self.as_inner().epem()
+ operand.ep() * self.as_inner().m() * self.as_inner().m(),
-T::TWO * operand.ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.y() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.x() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.x() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.y() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.em() * self.as_inner().m() * self.as_inner().m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<RoundPoint<T>>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().x() * self.e2em() * self.e2em())
+ -(operand.as_inner().x() * self.epem() * self.epem())
+ -(operand.as_inner().x() * self.m() * self.m())
+ -T::TWO * operand.as_inner().em() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().em() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().y() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().ep() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().ep() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().y() * self.e1em() * self.e2em()
+ operand.as_inner().x() * self.e1em() * self.e1em()
+ operand.as_inner().x() * self.e2ep() * self.e2ep(),
-(operand.as_inner().y() * self.e1em() * self.e1em())
+ -(operand.as_inner().y() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().y() * self.epem() * self.epem())
+ -(operand.as_inner().y() * self.m() * self.m())
+ -T::TWO * operand.as_inner().em() * self.e2ep() * self.epem()
+ -T::TWO * operand.as_inner().ep() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().x() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().em() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().ep() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().x() * self.e1em() * self.e2em()
+ operand.as_inner().y() * self.e1ep() * self.e1ep()
+ operand.as_inner().y() * self.e2em() * self.e2em(),
-(operand.as_inner().ep() * self.e1em() * self.e1em())
+ -(operand.as_inner().ep() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().ep() * self.e2em() * self.e2em())
+ -(operand.as_inner().ep() * self.e2ep() * self.e2ep())
+ -T::TWO * operand.as_inner().y() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().em() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().em() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().x() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().x() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().y() * self.e2em() * self.epem()
+ operand.as_inner().ep() * self.epem() * self.epem()
+ operand.as_inner().ep() * self.m() * self.m(),
-T::TWO * operand.as_inner().ep() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().ep() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().y() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().x() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().x() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().y() * self.e2ep() * self.epem()
+ operand.as_inner().em() * self.e1em() * self.e1em()
+ operand.as_inner().em() * self.e1ep() * self.e1ep()
+ operand.as_inner().em() * self.e2em() * self.e2em()
+ operand.as_inner().em() * self.e2ep() * self.e2ep()
+ operand.as_inner().em() * self.epem() * self.epem()
+ operand.as_inner().em() * self.m() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<RoundPoint<T>>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().x() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().x() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().x() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().em()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().em() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO
* operand.as_inner().y()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().ep() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().x() * self.as_inner().e2ep() * self.as_inner().e2ep(),
-(operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().y() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().y() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().y() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().em()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().ep() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO
* operand.as_inner().x()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().em() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.as_inner().y() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().y() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO * operand.as_inner().y() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO
* operand.as_inner().em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.as_inner().x() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().y() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.as_inner().ep() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().ep() * self.as_inner().m() * self.as_inner().m(),
-T::TWO * operand.as_inner().ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.as_inner().x() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.as_inner().x() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.as_inner().y() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.as_inner().em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().em() * self.as_inner().m() * self.as_inner().m(),
)
}
}
#[doc = "Sandwich product: [`PointPair`] x [`Scalar`] x rev([`PointPair`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Scalar<T>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(self.e1em() * operand.s() * self.e1em()) + self.e1ep() * operand.s() * self.e1ep()
- self.e2em() * operand.s() * self.e2em()
+ self.e2ep() * operand.s() * self.e2ep()
- self.epem() * operand.s() * self.epem()
+ self.m() * operand.s() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Scalar<T>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.s() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.s() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.s() * self.as_inner().epem() * self.as_inner().epem())
+ operand.s() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.s() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.s() * self.as_inner().m() * self.as_inner().m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Scalar<T>>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.e1em() * self.e1em())
+ -(operand.as_inner().s() * self.e2em() * self.e2em())
+ -(operand.as_inner().s() * self.epem() * self.epem())
+ operand.as_inner().s() * self.e1ep() * self.e1ep()
+ operand.as_inner().s() * self.e2ep() * self.e2ep()
+ operand.as_inner().s() * self.m() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Scalar<T>>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().s() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().s() * self.as_inner().epem() * self.as_inner().epem())
+ operand.as_inner().s() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().s() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().s() * self.as_inner().m() * self.as_inner().m(),
)
}
}
#[doc = "Sandwich product: [`Pseudoscalar`] x [`Circle`] x rev([`Pseudoscalar`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Circle<T>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
self.ps() * operand.w() * self.ps(),
self.ps() * operand.e12em() * self.ps(),
self.ps() * operand.e1epem() * self.ps(),
self.ps() * operand.e2epem() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Circle<T>> for Unit<Pseudoscalar<T>> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
operand.w() * self.as_inner().ps() * self.as_inner().ps(),
operand.e12em() * self.as_inner().ps() * self.as_inner().ps(),
operand.e1epem() * self.as_inner().ps() * self.as_inner().ps(),
operand.e2epem() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Circle<T>>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
operand.as_inner().w() * self.ps() * self.ps(),
operand.as_inner().e12em() * self.ps() * self.ps(),
operand.as_inner().e1epem() * self.ps() * self.ps(),
operand.as_inner().e2epem() * self.ps() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Circle<T>>> for Unit<Pseudoscalar<T>> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
operand.as_inner().w() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().e12em() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().e1epem() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().e2epem() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[doc = "Sandwich product: [`Pseudoscalar`] x [`FlatPoint`] x rev([`Pseudoscalar`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<FlatPoint<T>> for Pseudoscalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(self.ps() * operand.e1em() * self.ps()),
-(self.ps() * operand.e2em() * self.ps()),
-(self.ps() * operand.epem() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<FlatPoint<T>> for Unit<Pseudoscalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.e1em() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.e2em() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.epem() * self.as_inner().ps() * self.as_inner().ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<FlatPoint<T>>> for Pseudoscalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.ps() * self.ps()),
-(operand.as_inner().e2em() * self.ps() * self.ps()),
-(operand.as_inner().epem() * self.ps() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<FlatPoint<T>>> for Unit<Pseudoscalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.as_inner().e2em() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.as_inner().epem() * self.as_inner().ps() * self.as_inner().ps()),
)
}
}
#[doc = "Sandwich product: [`Pseudoscalar`] x [`Line`] x rev([`Pseudoscalar`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Line<T>> for Pseudoscalar<T> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
self.ps() * operand.nx() * self.ps(),
self.ps() * operand.ny() * self.ps(),
self.ps() * operand.d() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Line<T>> for Unit<Pseudoscalar<T>> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
operand.nx() * self.as_inner().ps() * self.as_inner().ps(),
operand.ny() * self.as_inner().ps() * self.as_inner().ps(),
operand.d() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Line<T>>> for Pseudoscalar<T> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
operand.as_inner().nx() * self.ps() * self.ps(),
operand.as_inner().ny() * self.ps() * self.ps(),
operand.as_inner().d() * self.ps() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Line<T>>> for Unit<Pseudoscalar<T>> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
operand.as_inner().nx() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().ny() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().d() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[doc = "Sandwich product: [`Pseudoscalar`] x [`Motor`] x rev([`Pseudoscalar`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Motor<T>> for Pseudoscalar<T> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(self.ps() * operand.s() * self.ps()),
-(self.ps() * operand.m() * self.ps()),
-(self.ps() * operand.e1ep() * self.ps()),
-(self.ps() * operand.e2ep() * self.ps()),
-(self.ps() * operand.e1em() * self.ps()),
-(self.ps() * operand.e2em() * self.ps()),
-(self.ps() * operand.epem() * self.ps()),
-(self.ps() * operand.ps() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Motor<T>> for Unit<Pseudoscalar<T>> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(operand.s() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.m() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.e1ep() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.e2ep() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.e1em() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.e2em() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.epem() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.ps() * self.as_inner().ps() * self.as_inner().ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Motor<T>>> for Pseudoscalar<T> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.ps() * self.ps()),
-(operand.as_inner().m() * self.ps() * self.ps()),
-(operand.as_inner().e1ep() * self.ps() * self.ps()),
-(operand.as_inner().e2ep() * self.ps() * self.ps()),
-(operand.as_inner().e1em() * self.ps() * self.ps()),
-(operand.as_inner().e2em() * self.ps() * self.ps()),
-(operand.as_inner().epem() * self.ps() * self.ps()),
-(operand.as_inner().ps() * self.ps() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Motor<T>>> for Unit<Pseudoscalar<T>> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.as_inner().m() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.as_inner().e1ep() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.as_inner().e2ep() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.as_inner().e1em() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.as_inner().e2em() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.as_inner().epem() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.as_inner().ps() * self.as_inner().ps() * self.as_inner().ps()),
)
}
}
#[doc = "Sandwich product: [`Pseudoscalar`] x [`PointPair`] x rev([`Pseudoscalar`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<PointPair<T>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(self.ps() * operand.m() * self.ps()),
-(self.ps() * operand.e1ep() * self.ps()),
-(self.ps() * operand.e2ep() * self.ps()),
-(self.ps() * operand.e1em() * self.ps()),
-(self.ps() * operand.e2em() * self.ps()),
-(self.ps() * operand.epem() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<PointPair<T>> for Unit<Pseudoscalar<T>> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.m() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.e1ep() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.e2ep() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.e1em() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.e2em() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.epem() * self.as_inner().ps() * self.as_inner().ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<PointPair<T>>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.ps() * self.ps()),
-(operand.as_inner().e1ep() * self.ps() * self.ps()),
-(operand.as_inner().e2ep() * self.ps() * self.ps()),
-(operand.as_inner().e1em() * self.ps() * self.ps()),
-(operand.as_inner().e2em() * self.ps() * self.ps()),
-(operand.as_inner().epem() * self.ps() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<PointPair<T>>> for Unit<Pseudoscalar<T>> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.as_inner().e1ep() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.as_inner().e2ep() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.as_inner().e1em() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.as_inner().e2em() * self.as_inner().ps() * self.as_inner().ps()),
-(operand.as_inner().epem() * self.as_inner().ps() * self.as_inner().ps()),
)
}
}
#[doc = "Sandwich product: [`Pseudoscalar`] x [`Pseudoscalar`] x rev([`Pseudoscalar`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Pseudoscalar<T>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(self.ps() * operand.ps() * self.ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Pseudoscalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(operand.ps() * self.as_inner().ps() * self.as_inner().ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Pseudoscalar<T>>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(operand.as_inner().ps() * self.ps() * self.ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Pseudoscalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.as_inner().ps() * self.as_inner().ps()),
)
}
}
#[doc = "Sandwich product: [`Pseudoscalar`] x [`RoundPoint`] x rev([`Pseudoscalar`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<RoundPoint<T>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
self.ps() * operand.x() * self.ps(),
self.ps() * operand.y() * self.ps(),
self.ps() * operand.ep() * self.ps(),
self.ps() * operand.em() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<RoundPoint<T>> for Unit<Pseudoscalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
operand.x() * self.as_inner().ps() * self.as_inner().ps(),
operand.y() * self.as_inner().ps() * self.as_inner().ps(),
operand.ep() * self.as_inner().ps() * self.as_inner().ps(),
operand.em() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<RoundPoint<T>>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
operand.as_inner().x() * self.ps() * self.ps(),
operand.as_inner().y() * self.ps() * self.ps(),
operand.as_inner().ep() * self.ps() * self.ps(),
operand.as_inner().em() * self.ps() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<RoundPoint<T>>> for Unit<Pseudoscalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
operand.as_inner().x() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().y() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().ep() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().em() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[doc = "Sandwich product: [`Pseudoscalar`] x [`Scalar`] x rev([`Pseudoscalar`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Scalar<T>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(-(self.ps() * operand.s() * self.ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Scalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(-(operand.s() * self.as_inner().ps() * self.as_inner().ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Scalar<T>>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(-(operand.as_inner().s() * self.ps() * self.ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Scalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.as_inner().ps() * self.as_inner().ps()),
)
}
}
#[doc = "Sandwich product: [`RoundPoint`] x [`Circle`] x rev([`RoundPoint`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Circle<T>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-(self.em() * operand.e12em() * self.ep()) + self.em() * operand.e1epem() * self.y()
- self.em() * operand.e2epem() * self.x()
+ self.em() * operand.w() * self.em()
- self.ep() * operand.e12em() * self.em()
+ self.ep() * operand.w() * self.ep()
- self.x() * operand.e2epem() * self.em()
+ self.x() * operand.w() * self.x()
+ self.y() * operand.e1epem() * self.em()
+ self.y() * operand.w() * self.y(),
-(self.em() * operand.e12em() * self.em()) + self.em() * operand.w() * self.ep()
- self.ep() * operand.e12em() * self.ep()
+ self.ep() * operand.e1epem() * self.y()
- self.ep() * operand.e2epem() * self.x()
+ self.ep() * operand.w() * self.em()
+ self.x() * operand.e12em() * self.x()
- self.x() * operand.e2epem() * self.ep()
+ self.y() * operand.e12em() * self.y()
+ self.y() * operand.e1epem() * self.ep(),
-(self.em() * operand.e1epem() * self.em()) - self.em() * operand.w() * self.y()
+ self.ep() * operand.e12em() * self.y()
+ self.ep() * operand.e1epem() * self.ep()
+ self.x() * operand.e1epem() * self.x()
+ self.x() * operand.e2epem() * self.y()
+ self.y() * operand.e12em() * self.ep()
- self.y() * operand.e1epem() * self.y()
+ self.y() * operand.e2epem() * self.x()
- self.y() * operand.w() * self.em(),
-(self.em() * operand.e2epem() * self.em()) + self.em() * operand.w() * self.x()
- self.ep() * operand.e12em() * self.x()
+ self.ep() * operand.e2epem() * self.ep()
- self.x() * operand.e12em() * self.ep()
+ self.x() * operand.e1epem() * self.y()
- self.x() * operand.e2epem() * self.x()
+ self.x() * operand.w() * self.em()
+ self.y() * operand.e1epem() * self.x()
+ self.y() * operand.e2epem() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Circle<T>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.e12em() * self.as_inner().em() * self.as_inner().ep()
+ -T::TWO * operand.e2epem() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.e1epem() * self.as_inner().em() * self.as_inner().y()
+ operand.w() * self.as_inner().em() * self.as_inner().em()
+ operand.w() * self.as_inner().ep() * self.as_inner().ep()
+ operand.w() * self.as_inner().x() * self.as_inner().x()
+ operand.w() * self.as_inner().y() * self.as_inner().y(),
-(operand.e12em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.e12em() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO * operand.e2epem() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.e1epem() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.w() * self.as_inner().em() * self.as_inner().ep()
+ operand.e12em() * self.as_inner().x() * self.as_inner().x()
+ operand.e12em() * self.as_inner().y() * self.as_inner().y(),
-(operand.e1epem() * self.as_inner().em() * self.as_inner().em())
+ -(operand.e1epem() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.w() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.e12em() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.e2epem() * self.as_inner().x() * self.as_inner().y()
+ operand.e1epem() * self.as_inner().ep() * self.as_inner().ep()
+ operand.e1epem() * self.as_inner().x() * self.as_inner().x(),
-(operand.e2epem() * self.as_inner().em() * self.as_inner().em())
+ -(operand.e2epem() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.e12em() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.e1epem() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.w() * self.as_inner().em() * self.as_inner().x()
+ operand.e2epem() * self.as_inner().ep() * self.as_inner().ep()
+ operand.e2epem() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Circle<T>>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.as_inner().e12em() * self.em() * self.ep()
+ -T::TWO * operand.as_inner().e2epem() * self.em() * self.x()
+ T::TWO * operand.as_inner().e1epem() * self.em() * self.y()
+ operand.as_inner().w() * self.em() * self.em()
+ operand.as_inner().w() * self.ep() * self.ep()
+ operand.as_inner().w() * self.x() * self.x()
+ operand.as_inner().w() * self.y() * self.y(),
-(operand.as_inner().e12em() * self.em() * self.em())
+ -(operand.as_inner().e12em() * self.ep() * self.ep())
+ -T::TWO * operand.as_inner().e2epem() * self.ep() * self.x()
+ T::TWO * operand.as_inner().e1epem() * self.ep() * self.y()
+ T::TWO * operand.as_inner().w() * self.em() * self.ep()
+ operand.as_inner().e12em() * self.x() * self.x()
+ operand.as_inner().e12em() * self.y() * self.y(),
-(operand.as_inner().e1epem() * self.em() * self.em())
+ -(operand.as_inner().e1epem() * self.y() * self.y())
+ -T::TWO * operand.as_inner().w() * self.em() * self.y()
+ T::TWO * operand.as_inner().e12em() * self.ep() * self.y()
+ T::TWO * operand.as_inner().e2epem() * self.x() * self.y()
+ operand.as_inner().e1epem() * self.ep() * self.ep()
+ operand.as_inner().e1epem() * self.x() * self.x(),
-(operand.as_inner().e2epem() * self.em() * self.em())
+ -(operand.as_inner().e2epem() * self.x() * self.x())
+ -T::TWO * operand.as_inner().e12em() * self.ep() * self.x()
+ T::TWO * operand.as_inner().e1epem() * self.x() * self.y()
+ T::TWO * operand.as_inner().w() * self.em() * self.x()
+ operand.as_inner().e2epem() * self.ep() * self.ep()
+ operand.as_inner().e2epem() * self.y() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Circle<T>>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.as_inner().e12em() * self.as_inner().em() * self.as_inner().ep()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().em()
* self.as_inner().x()
+ T::TWO * operand.as_inner().e1epem() * self.as_inner().em() * self.as_inner().y()
+ operand.as_inner().w() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().w() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().w() * self.as_inner().x() * self.as_inner().x()
+ operand.as_inner().w() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().e12em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().e12em() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().ep()
* self.as_inner().x()
+ T::TWO * operand.as_inner().e1epem() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.as_inner().w() * self.as_inner().em() * self.as_inner().ep()
+ operand.as_inner().e12em() * self.as_inner().x() * self.as_inner().x()
+ operand.as_inner().e12em() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().e1epem() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().e1epem() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.as_inner().w() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.as_inner().e12em() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.as_inner().e2epem() * self.as_inner().x() * self.as_inner().y()
+ operand.as_inner().e1epem() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().e1epem() * self.as_inner().x() * self.as_inner().x(),
-(operand.as_inner().e2epem() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().e2epem() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.as_inner().e12em() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().e1epem() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.as_inner().w() * self.as_inner().em() * self.as_inner().x()
+ operand.as_inner().e2epem() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().e2epem() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[doc = "Sandwich product: [`RoundPoint`] x [`FlatPoint`] x rev([`RoundPoint`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<FlatPoint<T>> for RoundPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
self.em() * operand.e1em() * self.em() + self.ep() * operand.e1em() * self.ep()
- self.ep() * operand.epem() * self.x()
- self.x() * operand.e1em() * self.x()
- self.x() * operand.e2em() * self.y()
- self.x() * operand.epem() * self.ep()
+ self.y() * operand.e1em() * self.y()
- self.y() * operand.e2em() * self.x(),
self.em() * operand.e2em() * self.em() + self.ep() * operand.e2em() * self.ep()
- self.ep() * operand.epem() * self.y()
- self.x() * operand.e1em() * self.y()
+ self.x() * operand.e2em() * self.x()
- self.y() * operand.e1em() * self.x()
- self.y() * operand.e2em() * self.y()
- self.y() * operand.epem() * self.ep(),
self.em() * operand.epem() * self.em()
- self.ep() * operand.e1em() * self.x()
- self.ep() * operand.e2em() * self.y()
- self.ep() * operand.epem() * self.ep()
- self.x() * operand.e1em() * self.ep()
+ self.x() * operand.epem() * self.x()
- self.y() * operand.e2em() * self.ep()
+ self.y() * operand.epem() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<FlatPoint<T>> for Unit<RoundPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.e1em() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.e2em() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.epem() * self.as_inner().ep() * self.as_inner().x()
+ operand.e1em() * self.as_inner().em() * self.as_inner().em()
+ operand.e1em() * self.as_inner().ep() * self.as_inner().ep()
+ operand.e1em() * self.as_inner().y() * self.as_inner().y(),
-(operand.e2em() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.e1em() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.epem() * self.as_inner().ep() * self.as_inner().y()
+ operand.e2em() * self.as_inner().em() * self.as_inner().em()
+ operand.e2em() * self.as_inner().ep() * self.as_inner().ep()
+ operand.e2em() * self.as_inner().x() * self.as_inner().x(),
-(operand.epem() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO * operand.e1em() * self.as_inner().ep() * self.as_inner().x()
+ -T::TWO * operand.e2em() * self.as_inner().ep() * self.as_inner().y()
+ operand.epem() * self.as_inner().em() * self.as_inner().em()
+ operand.epem() * self.as_inner().x() * self.as_inner().x()
+ operand.epem() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<FlatPoint<T>>> for RoundPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.x() * self.x())
+ -T::TWO * operand.as_inner().e2em() * self.x() * self.y()
+ -T::TWO * operand.as_inner().epem() * self.ep() * self.x()
+ operand.as_inner().e1em() * self.em() * self.em()
+ operand.as_inner().e1em() * self.ep() * self.ep()
+ operand.as_inner().e1em() * self.y() * self.y(),
-(operand.as_inner().e2em() * self.y() * self.y())
+ -T::TWO * operand.as_inner().e1em() * self.x() * self.y()
+ -T::TWO * operand.as_inner().epem() * self.ep() * self.y()
+ operand.as_inner().e2em() * self.em() * self.em()
+ operand.as_inner().e2em() * self.ep() * self.ep()
+ operand.as_inner().e2em() * self.x() * self.x(),
-(operand.as_inner().epem() * self.ep() * self.ep())
+ -T::TWO * operand.as_inner().e1em() * self.ep() * self.x()
+ -T::TWO * operand.as_inner().e2em() * self.ep() * self.y()
+ operand.as_inner().epem() * self.em() * self.em()
+ operand.as_inner().epem() * self.x() * self.x()
+ operand.as_inner().epem() * self.y() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<FlatPoint<T>>> for Unit<RoundPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().x()
+ operand.as_inner().e1em() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().e1em() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().e1em() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().e2em() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().y()
+ operand.as_inner().e2em() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().e2em() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().e2em() * self.as_inner().x() * self.as_inner().x(),
-(operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().ep() * self.as_inner().x()
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().ep() * self.as_inner().y()
+ operand.as_inner().epem() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().epem() * self.as_inner().x() * self.as_inner().x()
+ operand.as_inner().epem() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[doc = "Sandwich product: [`RoundPoint`] x [`Line`] x rev([`RoundPoint`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Line<T>> for RoundPoint<T> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(self.em() * operand.nx() * self.em())
- self.ep() * operand.d() * self.x()
- self.ep() * operand.nx() * self.ep()
+ self.ep() * operand.ny() * self.y()
- self.x() * operand.d() * self.ep()
+ self.x() * operand.nx() * self.x()
+ self.y() * operand.nx() * self.y()
+ self.y() * operand.ny() * self.ep(),
-(self.em() * operand.ny() * self.em())
+ self.ep() * operand.nx() * self.y()
+ self.ep() * operand.ny() * self.ep()
+ self.x() * operand.d() * self.y()
+ self.x() * operand.ny() * self.x()
+ self.y() * operand.d() * self.x()
+ self.y() * operand.nx() * self.ep()
- self.y() * operand.ny() * self.y(),
-(self.em() * operand.d() * self.em()) + self.ep() * operand.d() * self.ep()
- self.ep() * operand.nx() * self.x()
- self.x() * operand.d() * self.x()
- self.x() * operand.nx() * self.ep()
+ self.x() * operand.ny() * self.y()
+ self.y() * operand.d() * self.y()
+ self.y() * operand.ny() * self.x(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Line<T>> for Unit<RoundPoint<T>> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(operand.nx() * self.as_inner().em() * self.as_inner().em())
+ -(operand.nx() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO * operand.d() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.ny() * self.as_inner().ep() * self.as_inner().y()
+ operand.nx() * self.as_inner().x() * self.as_inner().x()
+ operand.nx() * self.as_inner().y() * self.as_inner().y(),
-(operand.ny() * self.as_inner().em() * self.as_inner().em())
+ -(operand.ny() * self.as_inner().y() * self.as_inner().y())
+ T::TWO * operand.d() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.nx() * self.as_inner().ep() * self.as_inner().y()
+ operand.ny() * self.as_inner().ep() * self.as_inner().ep()
+ operand.ny() * self.as_inner().x() * self.as_inner().x(),
-(operand.d() * self.as_inner().em() * self.as_inner().em())
+ -(operand.d() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.nx() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.ny() * self.as_inner().x() * self.as_inner().y()
+ operand.d() * self.as_inner().ep() * self.as_inner().ep()
+ operand.d() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Line<T>>> for RoundPoint<T> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.em() * self.em())
+ -(operand.as_inner().nx() * self.ep() * self.ep())
+ -T::TWO * operand.as_inner().d() * self.ep() * self.x()
+ T::TWO * operand.as_inner().ny() * self.ep() * self.y()
+ operand.as_inner().nx() * self.x() * self.x()
+ operand.as_inner().nx() * self.y() * self.y(),
-(operand.as_inner().ny() * self.em() * self.em())
+ -(operand.as_inner().ny() * self.y() * self.y())
+ T::TWO * operand.as_inner().d() * self.x() * self.y()
+ T::TWO * operand.as_inner().nx() * self.ep() * self.y()
+ operand.as_inner().ny() * self.ep() * self.ep()
+ operand.as_inner().ny() * self.x() * self.x(),
-(operand.as_inner().d() * self.em() * self.em())
+ -(operand.as_inner().d() * self.x() * self.x())
+ -T::TWO * operand.as_inner().nx() * self.ep() * self.x()
+ T::TWO * operand.as_inner().ny() * self.x() * self.y()
+ operand.as_inner().d() * self.ep() * self.ep()
+ operand.as_inner().d() * self.y() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Line<T>>> for Unit<RoundPoint<T>> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().nx() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO * operand.as_inner().d() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().ny() * self.as_inner().ep() * self.as_inner().y()
+ operand.as_inner().nx() * self.as_inner().x() * self.as_inner().x()
+ operand.as_inner().nx() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().ny() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().ny() * self.as_inner().y() * self.as_inner().y())
+ T::TWO * operand.as_inner().d() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.as_inner().nx() * self.as_inner().ep() * self.as_inner().y()
+ operand.as_inner().ny() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().ny() * self.as_inner().x() * self.as_inner().x(),
-(operand.as_inner().d() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().d() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.as_inner().nx() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().ny() * self.as_inner().x() * self.as_inner().y()
+ operand.as_inner().d() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().d() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[doc = "Sandwich product: [`RoundPoint`] x [`Motor`] x rev([`RoundPoint`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Motor<T>> for RoundPoint<T> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
self.em() * operand.e1em() * self.x()
+ self.em() * operand.e2em() * self.y()
+ self.em() * operand.epem() * self.ep()
- self.em() * operand.s() * self.em()
- self.ep() * operand.e1ep() * self.x()
- self.ep() * operand.e2ep() * self.y()
- self.ep() * operand.epem() * self.em()
+ self.ep() * operand.s() * self.ep()
- self.x() * operand.e1em() * self.em()
+ self.x() * operand.e1ep() * self.ep()
+ self.x() * operand.m() * self.y()
+ self.x() * operand.s() * self.x()
- self.y() * operand.e2em() * self.em()
+ self.y() * operand.e2ep() * self.ep()
- self.y() * operand.m() * self.x()
+ self.y() * operand.s() * self.y(),
self.em() * operand.e1em() * self.y()
- self.em() * operand.e2em() * self.x()
- self.em() * operand.m() * self.em()
+ self.em() * operand.ps() * self.ep()
- self.ep() * operand.e1ep() * self.y()
+ self.ep() * operand.e2ep() * self.x()
+ self.ep() * operand.m() * self.ep()
- self.ep() * operand.ps() * self.em()
- self.x() * operand.e2em() * self.em()
+ self.x() * operand.e2ep() * self.ep()
- self.x() * operand.m() * self.x()
+ self.x() * operand.s() * self.y()
+ self.y() * operand.e1em() * self.em()
- self.y() * operand.e1ep() * self.ep()
- self.y() * operand.m() * self.y()
- self.y() * operand.s() * self.x(),
self.em() * operand.e1em() * self.ep()
- self.em() * operand.e1ep() * self.em()
- self.em() * operand.epem() * self.x()
- self.em() * operand.ps() * self.y()
+ self.ep() * operand.e1em() * self.em()
- self.ep() * operand.e1ep() * self.ep()
- self.ep() * operand.m() * self.y()
- self.ep() * operand.s() * self.x()
- self.x() * operand.e1ep() * self.x()
- self.x() * operand.e2ep() * self.y()
- self.x() * operand.epem() * self.em()
+ self.x() * operand.s() * self.ep()
+ self.y() * operand.e1ep() * self.y()
- self.y() * operand.e2ep() * self.x()
- self.y() * operand.m() * self.ep()
+ self.y() * operand.ps() * self.em(),
self.em() * operand.e2em() * self.ep()
- self.em() * operand.e2ep() * self.em()
- self.em() * operand.epem() * self.y()
+ self.em() * operand.ps() * self.x()
+ self.ep() * operand.e2em() * self.em()
- self.ep() * operand.e2ep() * self.ep()
+ self.ep() * operand.m() * self.x()
- self.ep() * operand.s() * self.y()
- self.x() * operand.e1ep() * self.y()
+ self.x() * operand.e2ep() * self.x()
+ self.x() * operand.m() * self.ep()
- self.x() * operand.ps() * self.em()
- self.y() * operand.e1ep() * self.x()
- self.y() * operand.e2ep() * self.y()
- self.y() * operand.epem() * self.em()
+ self.y() * operand.s() * self.ep(),
self.em() * operand.e1em() * self.em()
- self.em() * operand.e1ep() * self.ep()
- self.em() * operand.m() * self.y()
- self.em() * operand.s() * self.x()
+ self.ep() * operand.e1em() * self.ep()
- self.ep() * operand.e1ep() * self.em()
- self.ep() * operand.epem() * self.x()
- self.ep() * operand.ps() * self.y()
- self.x() * operand.e1em() * self.x()
- self.x() * operand.e2em() * self.y()
- self.x() * operand.epem() * self.ep()
+ self.x() * operand.s() * self.em()
+ self.y() * operand.e1em() * self.y()
- self.y() * operand.e2em() * self.x()
- self.y() * operand.m() * self.em()
+ self.y() * operand.ps() * self.ep(),
self.em() * operand.e2em() * self.em() - self.em() * operand.e2ep() * self.ep()
+ self.em() * operand.m() * self.x()
- self.em() * operand.s() * self.y()
+ self.ep() * operand.e2em() * self.ep()
- self.ep() * operand.e2ep() * self.em()
- self.ep() * operand.epem() * self.y()
+ self.ep() * operand.ps() * self.x()
- self.x() * operand.e1em() * self.y()
+ self.x() * operand.e2em() * self.x()
+ self.x() * operand.m() * self.em()
- self.x() * operand.ps() * self.ep()
- self.y() * operand.e1em() * self.x()
- self.y() * operand.e2em() * self.y()
- self.y() * operand.epem() * self.ep()
+ self.y() * operand.s() * self.em(),
self.em() * operand.e1ep() * self.x()
+ self.em() * operand.e2ep() * self.y()
+ self.em() * operand.epem() * self.em()
- self.em() * operand.s() * self.ep()
- self.ep() * operand.e1em() * self.x()
- self.ep() * operand.e2em() * self.y()
- self.ep() * operand.epem() * self.ep()
+ self.ep() * operand.s() * self.em()
- self.x() * operand.e1em() * self.ep()
+ self.x() * operand.e1ep() * self.em()
+ self.x() * operand.epem() * self.x()
+ self.x() * operand.ps() * self.y()
- self.y() * operand.e2em() * self.ep()
+ self.y() * operand.e2ep() * self.em()
+ self.y() * operand.epem() * self.y()
- self.y() * operand.ps() * self.x(),
self.em() * operand.e1ep() * self.y()
- self.em() * operand.e2ep() * self.x()
- self.em() * operand.m() * self.ep()
+ self.em() * operand.ps() * self.em()
- self.ep() * operand.e1em() * self.y()
+ self.ep() * operand.e2em() * self.x()
+ self.ep() * operand.m() * self.em()
- self.ep() * operand.ps() * self.ep()
- self.x() * operand.e2em() * self.ep()
+ self.x() * operand.e2ep() * self.em()
+ self.x() * operand.epem() * self.y()
- self.x() * operand.ps() * self.x()
+ self.y() * operand.e1em() * self.ep()
- self.y() * operand.e1ep() * self.em()
- self.y() * operand.epem() * self.x()
- self.y() * operand.ps() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Motor<T>> for Unit<RoundPoint<T>> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(operand.s() * self.as_inner().em() * self.as_inner().em())
+ operand.s() * self.as_inner().ep() * self.as_inner().ep()
+ operand.s() * self.as_inner().x() * self.as_inner().x()
+ operand.s() * self.as_inner().y() * self.as_inner().y(),
-(operand.m() * self.as_inner().em() * self.as_inner().em())
+ -(operand.m() * self.as_inner().x() * self.as_inner().x())
+ -(operand.m() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.e1ep() * self.as_inner().ep() * self.as_inner().y()
+ -T::TWO * operand.e2em() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.e1em() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.e2ep() * self.as_inner().ep() * self.as_inner().x()
+ operand.m() * self.as_inner().ep() * self.as_inner().ep(),
-(operand.e1ep() * self.as_inner().em() * self.as_inner().em())
+ -(operand.e1ep() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.e1ep() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.e2ep() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.epem() * self.as_inner().em() * self.as_inner().x()
+ -T::TWO * operand.m() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.e1em() * self.as_inner().em() * self.as_inner().ep()
+ operand.e1ep() * self.as_inner().y() * self.as_inner().y(),
-(operand.e2ep() * self.as_inner().em() * self.as_inner().em())
+ -(operand.e2ep() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.e2ep() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.e1ep() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.epem() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.e2em() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.m() * self.as_inner().ep() * self.as_inner().x()
+ operand.e2ep() * self.as_inner().x() * self.as_inner().x(),
-(operand.e1em() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.e1ep() * self.as_inner().em() * self.as_inner().ep()
+ -T::TWO * operand.e2em() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.epem() * self.as_inner().ep() * self.as_inner().x()
+ -T::TWO * operand.m() * self.as_inner().em() * self.as_inner().y()
+ operand.e1em() * self.as_inner().em() * self.as_inner().em()
+ operand.e1em() * self.as_inner().ep() * self.as_inner().ep()
+ operand.e1em() * self.as_inner().y() * self.as_inner().y(),
-(operand.e2em() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.e1em() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.e2ep() * self.as_inner().em() * self.as_inner().ep()
+ -T::TWO * operand.epem() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.m() * self.as_inner().em() * self.as_inner().x()
+ operand.e2em() * self.as_inner().em() * self.as_inner().em()
+ operand.e2em() * self.as_inner().ep() * self.as_inner().ep()
+ operand.e2em() * self.as_inner().x() * self.as_inner().x(),
-(operand.epem() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO * operand.e1em() * self.as_inner().ep() * self.as_inner().x()
+ -T::TWO * operand.e2em() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.e1ep() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.e2ep() * self.as_inner().em() * self.as_inner().y()
+ operand.epem() * self.as_inner().em() * self.as_inner().em()
+ operand.epem() * self.as_inner().x() * self.as_inner().x()
+ operand.epem() * self.as_inner().y() * self.as_inner().y(),
-(operand.ps() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.ps() * self.as_inner().x() * self.as_inner().x())
+ -(operand.ps() * self.as_inner().y() * self.as_inner().y())
+ operand.ps() * self.as_inner().em() * self.as_inner().em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Motor<T>>> for RoundPoint<T> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.em() * self.em())
+ operand.as_inner().s() * self.ep() * self.ep()
+ operand.as_inner().s() * self.x() * self.x()
+ operand.as_inner().s() * self.y() * self.y(),
-(operand.as_inner().m() * self.em() * self.em())
+ -(operand.as_inner().m() * self.x() * self.x())
+ -(operand.as_inner().m() * self.y() * self.y())
+ -T::TWO * operand.as_inner().e1ep() * self.ep() * self.y()
+ -T::TWO * operand.as_inner().e2em() * self.em() * self.x()
+ T::TWO * operand.as_inner().e1em() * self.em() * self.y()
+ T::TWO * operand.as_inner().e2ep() * self.ep() * self.x()
+ operand.as_inner().m() * self.ep() * self.ep(),
-(operand.as_inner().e1ep() * self.em() * self.em())
+ -(operand.as_inner().e1ep() * self.ep() * self.ep())
+ -(operand.as_inner().e1ep() * self.x() * self.x())
+ -T::TWO * operand.as_inner().e2ep() * self.x() * self.y()
+ -T::TWO * operand.as_inner().epem() * self.em() * self.x()
+ -T::TWO * operand.as_inner().m() * self.ep() * self.y()
+ T::TWO * operand.as_inner().e1em() * self.em() * self.ep()
+ operand.as_inner().e1ep() * self.y() * self.y(),
-(operand.as_inner().e2ep() * self.em() * self.em())
+ -(operand.as_inner().e2ep() * self.ep() * self.ep())
+ -(operand.as_inner().e2ep() * self.y() * self.y())
+ -T::TWO * operand.as_inner().e1ep() * self.x() * self.y()
+ -T::TWO * operand.as_inner().epem() * self.em() * self.y()
+ T::TWO * operand.as_inner().e2em() * self.em() * self.ep()
+ T::TWO * operand.as_inner().m() * self.ep() * self.x()
+ operand.as_inner().e2ep() * self.x() * self.x(),
-(operand.as_inner().e1em() * self.x() * self.x())
+ -T::TWO * operand.as_inner().e1ep() * self.em() * self.ep()
+ -T::TWO * operand.as_inner().e2em() * self.x() * self.y()
+ -T::TWO * operand.as_inner().epem() * self.ep() * self.x()
+ -T::TWO * operand.as_inner().m() * self.em() * self.y()
+ operand.as_inner().e1em() * self.em() * self.em()
+ operand.as_inner().e1em() * self.ep() * self.ep()
+ operand.as_inner().e1em() * self.y() * self.y(),
-(operand.as_inner().e2em() * self.y() * self.y())
+ -T::TWO * operand.as_inner().e1em() * self.x() * self.y()
+ -T::TWO * operand.as_inner().e2ep() * self.em() * self.ep()
+ -T::TWO * operand.as_inner().epem() * self.ep() * self.y()
+ T::TWO * operand.as_inner().m() * self.em() * self.x()
+ operand.as_inner().e2em() * self.em() * self.em()
+ operand.as_inner().e2em() * self.ep() * self.ep()
+ operand.as_inner().e2em() * self.x() * self.x(),
-(operand.as_inner().epem() * self.ep() * self.ep())
+ -T::TWO * operand.as_inner().e1em() * self.ep() * self.x()
+ -T::TWO * operand.as_inner().e2em() * self.ep() * self.y()
+ T::TWO * operand.as_inner().e1ep() * self.em() * self.x()
+ T::TWO * operand.as_inner().e2ep() * self.em() * self.y()
+ operand.as_inner().epem() * self.em() * self.em()
+ operand.as_inner().epem() * self.x() * self.x()
+ operand.as_inner().epem() * self.y() * self.y(),
-(operand.as_inner().ps() * self.ep() * self.ep())
+ -(operand.as_inner().ps() * self.x() * self.x())
+ -(operand.as_inner().ps() * self.y() * self.y())
+ operand.as_inner().ps() * self.em() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Motor<T>>> for Unit<RoundPoint<T>> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.as_inner().em() * self.as_inner().em())
+ operand.as_inner().s() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().s() * self.as_inner().x() * self.as_inner().x()
+ operand.as_inner().s() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().m() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().m() * self.as_inner().x() * self.as_inner().x())
+ -(operand.as_inner().m() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().ep() * self.as_inner().y()
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().ep() * self.as_inner().x()
+ operand.as_inner().m() * self.as_inner().ep() * self.as_inner().ep(),
-(operand.as_inner().e1ep() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().e1ep() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().e1ep() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.as_inner().e2ep() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.as_inner().epem() * self.as_inner().em() * self.as_inner().x()
+ -T::TWO * operand.as_inner().m() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().em() * self.as_inner().ep()
+ operand.as_inner().e1ep() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().e2ep() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().e2ep() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().e2ep() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.as_inner().epem() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.as_inner().m() * self.as_inner().ep() * self.as_inner().x()
+ operand.as_inner().e2ep() * self.as_inner().x() * self.as_inner().x(),
-(operand.as_inner().e1em() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().em() * self.as_inner().ep()
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().x()
+ -T::TWO * operand.as_inner().m() * self.as_inner().em() * self.as_inner().y()
+ operand.as_inner().e1em() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().e1em() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().e1em() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().e2em() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.as_inner().e2ep() * self.as_inner().em() * self.as_inner().ep()
+ -T::TWO * operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.as_inner().m() * self.as_inner().em() * self.as_inner().x()
+ operand.as_inner().e2em() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().e2em() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().e2em() * self.as_inner().x() * self.as_inner().x(),
-(operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().ep() * self.as_inner().x()
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().em() * self.as_inner().y()
+ operand.as_inner().epem() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().epem() * self.as_inner().x() * self.as_inner().x()
+ operand.as_inner().epem() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().ps() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().ps() * self.as_inner().x() * self.as_inner().x())
+ -(operand.as_inner().ps() * self.as_inner().y() * self.as_inner().y())
+ operand.as_inner().ps() * self.as_inner().em() * self.as_inner().em(),
)
}
}
#[doc = "Sandwich product: [`RoundPoint`] x [`PointPair`] x rev([`RoundPoint`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<PointPair<T>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
self.em() * operand.e1em() * self.y()
- self.em() * operand.e2em() * self.x()
- self.em() * operand.m() * self.em()
- self.ep() * operand.e1ep() * self.y()
+ self.ep() * operand.e2ep() * self.x()
+ self.ep() * operand.m() * self.ep()
- self.x() * operand.e2em() * self.em()
+ self.x() * operand.e2ep() * self.ep()
- self.x() * operand.m() * self.x()
+ self.y() * operand.e1em() * self.em()
- self.y() * operand.e1ep() * self.ep()
- self.y() * operand.m() * self.y(),
self.em() * operand.e1em() * self.ep()
- self.em() * operand.e1ep() * self.em()
- self.em() * operand.epem() * self.x()
+ self.ep() * operand.e1em() * self.em()
- self.ep() * operand.e1ep() * self.ep()
- self.ep() * operand.m() * self.y()
- self.x() * operand.e1ep() * self.x()
- self.x() * operand.e2ep() * self.y()
- self.x() * operand.epem() * self.em()
+ self.y() * operand.e1ep() * self.y()
- self.y() * operand.e2ep() * self.x()
- self.y() * operand.m() * self.ep(),
self.em() * operand.e2em() * self.ep()
- self.em() * operand.e2ep() * self.em()
- self.em() * operand.epem() * self.y()
+ self.ep() * operand.e2em() * self.em()
- self.ep() * operand.e2ep() * self.ep()
+ self.ep() * operand.m() * self.x()
- self.x() * operand.e1ep() * self.y()
+ self.x() * operand.e2ep() * self.x()
+ self.x() * operand.m() * self.ep()
- self.y() * operand.e1ep() * self.x()
- self.y() * operand.e2ep() * self.y()
- self.y() * operand.epem() * self.em(),
self.em() * operand.e1em() * self.em()
- self.em() * operand.e1ep() * self.ep()
- self.em() * operand.m() * self.y()
+ self.ep() * operand.e1em() * self.ep()
- self.ep() * operand.e1ep() * self.em()
- self.ep() * operand.epem() * self.x()
- self.x() * operand.e1em() * self.x()
- self.x() * operand.e2em() * self.y()
- self.x() * operand.epem() * self.ep()
+ self.y() * operand.e1em() * self.y()
- self.y() * operand.e2em() * self.x()
- self.y() * operand.m() * self.em(),
self.em() * operand.e2em() * self.em() - self.em() * operand.e2ep() * self.ep()
+ self.em() * operand.m() * self.x()
+ self.ep() * operand.e2em() * self.ep()
- self.ep() * operand.e2ep() * self.em()
- self.ep() * operand.epem() * self.y()
- self.x() * operand.e1em() * self.y()
+ self.x() * operand.e2em() * self.x()
+ self.x() * operand.m() * self.em()
- self.y() * operand.e1em() * self.x()
- self.y() * operand.e2em() * self.y()
- self.y() * operand.epem() * self.ep(),
self.em() * operand.e1ep() * self.x()
+ self.em() * operand.e2ep() * self.y()
+ self.em() * operand.epem() * self.em()
- self.ep() * operand.e1em() * self.x()
- self.ep() * operand.e2em() * self.y()
- self.ep() * operand.epem() * self.ep()
- self.x() * operand.e1em() * self.ep()
+ self.x() * operand.e1ep() * self.em()
+ self.x() * operand.epem() * self.x()
- self.y() * operand.e2em() * self.ep()
+ self.y() * operand.e2ep() * self.em()
+ self.y() * operand.epem() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<PointPair<T>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.m() * self.as_inner().em() * self.as_inner().em())
+ -(operand.m() * self.as_inner().x() * self.as_inner().x())
+ -(operand.m() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.e1ep() * self.as_inner().ep() * self.as_inner().y()
+ -T::TWO * operand.e2em() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.e1em() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.e2ep() * self.as_inner().ep() * self.as_inner().x()
+ operand.m() * self.as_inner().ep() * self.as_inner().ep(),
-(operand.e1ep() * self.as_inner().em() * self.as_inner().em())
+ -(operand.e1ep() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.e1ep() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.e2ep() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.epem() * self.as_inner().em() * self.as_inner().x()
+ -T::TWO * operand.m() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.e1em() * self.as_inner().em() * self.as_inner().ep()
+ operand.e1ep() * self.as_inner().y() * self.as_inner().y(),
-(operand.e2ep() * self.as_inner().em() * self.as_inner().em())
+ -(operand.e2ep() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.e2ep() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.e1ep() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.epem() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.e2em() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.m() * self.as_inner().ep() * self.as_inner().x()
+ operand.e2ep() * self.as_inner().x() * self.as_inner().x(),
-(operand.e1em() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.e1ep() * self.as_inner().em() * self.as_inner().ep()
+ -T::TWO * operand.e2em() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.epem() * self.as_inner().ep() * self.as_inner().x()
+ -T::TWO * operand.m() * self.as_inner().em() * self.as_inner().y()
+ operand.e1em() * self.as_inner().em() * self.as_inner().em()
+ operand.e1em() * self.as_inner().ep() * self.as_inner().ep()
+ operand.e1em() * self.as_inner().y() * self.as_inner().y(),
-(operand.e2em() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.e1em() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.e2ep() * self.as_inner().em() * self.as_inner().ep()
+ -T::TWO * operand.epem() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.m() * self.as_inner().em() * self.as_inner().x()
+ operand.e2em() * self.as_inner().em() * self.as_inner().em()
+ operand.e2em() * self.as_inner().ep() * self.as_inner().ep()
+ operand.e2em() * self.as_inner().x() * self.as_inner().x(),
-(operand.epem() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO * operand.e1em() * self.as_inner().ep() * self.as_inner().x()
+ -T::TWO * operand.e2em() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.e1ep() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.e2ep() * self.as_inner().em() * self.as_inner().y()
+ operand.epem() * self.as_inner().em() * self.as_inner().em()
+ operand.epem() * self.as_inner().x() * self.as_inner().x()
+ operand.epem() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<PointPair<T>>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.em() * self.em())
+ -(operand.as_inner().m() * self.x() * self.x())
+ -(operand.as_inner().m() * self.y() * self.y())
+ -T::TWO * operand.as_inner().e1ep() * self.ep() * self.y()
+ -T::TWO * operand.as_inner().e2em() * self.em() * self.x()
+ T::TWO * operand.as_inner().e1em() * self.em() * self.y()
+ T::TWO * operand.as_inner().e2ep() * self.ep() * self.x()
+ operand.as_inner().m() * self.ep() * self.ep(),
-(operand.as_inner().e1ep() * self.em() * self.em())
+ -(operand.as_inner().e1ep() * self.ep() * self.ep())
+ -(operand.as_inner().e1ep() * self.x() * self.x())
+ -T::TWO * operand.as_inner().e2ep() * self.x() * self.y()
+ -T::TWO * operand.as_inner().epem() * self.em() * self.x()
+ -T::TWO * operand.as_inner().m() * self.ep() * self.y()
+ T::TWO * operand.as_inner().e1em() * self.em() * self.ep()
+ operand.as_inner().e1ep() * self.y() * self.y(),
-(operand.as_inner().e2ep() * self.em() * self.em())
+ -(operand.as_inner().e2ep() * self.ep() * self.ep())
+ -(operand.as_inner().e2ep() * self.y() * self.y())
+ -T::TWO * operand.as_inner().e1ep() * self.x() * self.y()
+ -T::TWO * operand.as_inner().epem() * self.em() * self.y()
+ T::TWO * operand.as_inner().e2em() * self.em() * self.ep()
+ T::TWO * operand.as_inner().m() * self.ep() * self.x()
+ operand.as_inner().e2ep() * self.x() * self.x(),
-(operand.as_inner().e1em() * self.x() * self.x())
+ -T::TWO * operand.as_inner().e1ep() * self.em() * self.ep()
+ -T::TWO * operand.as_inner().e2em() * self.x() * self.y()
+ -T::TWO * operand.as_inner().epem() * self.ep() * self.x()
+ -T::TWO * operand.as_inner().m() * self.em() * self.y()
+ operand.as_inner().e1em() * self.em() * self.em()
+ operand.as_inner().e1em() * self.ep() * self.ep()
+ operand.as_inner().e1em() * self.y() * self.y(),
-(operand.as_inner().e2em() * self.y() * self.y())
+ -T::TWO * operand.as_inner().e1em() * self.x() * self.y()
+ -T::TWO * operand.as_inner().e2ep() * self.em() * self.ep()
+ -T::TWO * operand.as_inner().epem() * self.ep() * self.y()
+ T::TWO * operand.as_inner().m() * self.em() * self.x()
+ operand.as_inner().e2em() * self.em() * self.em()
+ operand.as_inner().e2em() * self.ep() * self.ep()
+ operand.as_inner().e2em() * self.x() * self.x(),
-(operand.as_inner().epem() * self.ep() * self.ep())
+ -T::TWO * operand.as_inner().e1em() * self.ep() * self.x()
+ -T::TWO * operand.as_inner().e2em() * self.ep() * self.y()
+ T::TWO * operand.as_inner().e1ep() * self.em() * self.x()
+ T::TWO * operand.as_inner().e2ep() * self.em() * self.y()
+ operand.as_inner().epem() * self.em() * self.em()
+ operand.as_inner().epem() * self.x() * self.x()
+ operand.as_inner().epem() * self.y() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<PointPair<T>>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().m() * self.as_inner().x() * self.as_inner().x())
+ -(operand.as_inner().m() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().ep() * self.as_inner().y()
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().ep() * self.as_inner().x()
+ operand.as_inner().m() * self.as_inner().ep() * self.as_inner().ep(),
-(operand.as_inner().e1ep() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().e1ep() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().e1ep() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.as_inner().e2ep() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.as_inner().epem() * self.as_inner().em() * self.as_inner().x()
+ -T::TWO * operand.as_inner().m() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().em() * self.as_inner().ep()
+ operand.as_inner().e1ep() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().e2ep() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().e2ep() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().e2ep() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.as_inner().epem() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.as_inner().m() * self.as_inner().ep() * self.as_inner().x()
+ operand.as_inner().e2ep() * self.as_inner().x() * self.as_inner().x(),
-(operand.as_inner().e1em() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().em() * self.as_inner().ep()
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().x()
+ -T::TWO * operand.as_inner().m() * self.as_inner().em() * self.as_inner().y()
+ operand.as_inner().e1em() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().e1em() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().e1em() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().e2em() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().x() * self.as_inner().y()
+ -T::TWO * operand.as_inner().e2ep() * self.as_inner().em() * self.as_inner().ep()
+ -T::TWO * operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.as_inner().m() * self.as_inner().em() * self.as_inner().x()
+ operand.as_inner().e2em() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().e2em() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().e2em() * self.as_inner().x() * self.as_inner().x(),
-(operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().ep() * self.as_inner().x()
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().em() * self.as_inner().y()
+ operand.as_inner().epem() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().epem() * self.as_inner().x() * self.as_inner().x()
+ operand.as_inner().epem() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[doc = "Sandwich product: [`RoundPoint`] x [`Pseudoscalar`] x rev([`RoundPoint`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Pseudoscalar<T>> for RoundPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
self.em() * operand.ps() * self.em()
- self.ep() * operand.ps() * self.ep()
- self.x() * operand.ps() * self.x()
- self.y() * operand.ps() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Pseudoscalar<T>> for Unit<RoundPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.ps() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.ps() * self.as_inner().x() * self.as_inner().x())
+ -(operand.ps() * self.as_inner().y() * self.as_inner().y())
+ operand.ps() * self.as_inner().em() * self.as_inner().em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Pseudoscalar<T>>> for RoundPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.ep() * self.ep())
+ -(operand.as_inner().ps() * self.x() * self.x())
+ -(operand.as_inner().ps() * self.y() * self.y())
+ operand.as_inner().ps() * self.em() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Pseudoscalar<T>>> for Unit<RoundPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().ps() * self.as_inner().x() * self.as_inner().x())
+ -(operand.as_inner().ps() * self.as_inner().y() * self.as_inner().y())
+ operand.as_inner().ps() * self.as_inner().em() * self.as_inner().em(),
)
}
}
#[doc = "Sandwich product: [`RoundPoint`] x [`RoundPoint`] x rev([`RoundPoint`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<RoundPoint<T>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(self.em() * operand.em() * self.x())
+ self.em() * operand.x() * self.em()
+ self.ep() * operand.ep() * self.x()
- self.ep() * operand.x() * self.ep()
- self.x() * operand.em() * self.em()
+ self.x() * operand.ep() * self.ep()
+ self.x() * operand.x() * self.x()
+ self.x() * operand.y() * self.y()
- self.y() * operand.x() * self.y()
+ self.y() * operand.y() * self.x(),
-(self.em() * operand.em() * self.y())
+ self.em() * operand.y() * self.em()
+ self.ep() * operand.ep() * self.y()
- self.ep() * operand.y() * self.ep()
+ self.x() * operand.x() * self.y()
- self.x() * operand.y() * self.x()
- self.y() * operand.em() * self.em()
+ self.y() * operand.ep() * self.ep()
+ self.y() * operand.x() * self.x()
+ self.y() * operand.y() * self.y(),
-(self.em() * operand.em() * self.ep()) + self.em() * operand.ep() * self.em()
- self.ep() * operand.em() * self.em()
+ self.ep() * operand.ep() * self.ep()
+ self.ep() * operand.x() * self.x()
+ self.ep() * operand.y() * self.y()
- self.x() * operand.ep() * self.x()
+ self.x() * operand.x() * self.ep()
- self.y() * operand.ep() * self.y()
+ self.y() * operand.y() * self.ep(),
-(self.em() * operand.em() * self.em())
+ self.em() * operand.ep() * self.ep()
+ self.em() * operand.x() * self.x()
+ self.em() * operand.y() * self.y()
- self.ep() * operand.em() * self.ep()
+ self.ep() * operand.ep() * self.em()
- self.x() * operand.em() * self.x()
+ self.x() * operand.x() * self.em()
- self.y() * operand.em() * self.y()
+ self.y() * operand.y() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<RoundPoint<T>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.x() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.x() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.em() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.ep() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.y() * self.as_inner().x() * self.as_inner().y()
+ operand.x() * self.as_inner().em() * self.as_inner().em()
+ operand.x() * self.as_inner().x() * self.as_inner().x(),
-(operand.y() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.y() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.em() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.ep() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.x() * self.as_inner().x() * self.as_inner().y()
+ operand.y() * self.as_inner().em() * self.as_inner().em()
+ operand.y() * self.as_inner().y() * self.as_inner().y(),
-(operand.ep() * self.as_inner().x() * self.as_inner().x())
+ -(operand.ep() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.em() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.x() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.y() * self.as_inner().ep() * self.as_inner().y()
+ operand.ep() * self.as_inner().em() * self.as_inner().em()
+ operand.ep() * self.as_inner().ep() * self.as_inner().ep(),
-(operand.em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.em() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.em() * self.as_inner().x() * self.as_inner().x())
+ -(operand.em() * self.as_inner().y() * self.as_inner().y())
+ T::TWO * operand.ep() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.x() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.y() * self.as_inner().em() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<RoundPoint<T>>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.ep() * self.ep())
+ -(operand.as_inner().x() * self.y() * self.y())
+ -T::TWO * operand.as_inner().em() * self.em() * self.x()
+ T::TWO * operand.as_inner().ep() * self.ep() * self.x()
+ T::TWO * operand.as_inner().y() * self.x() * self.y()
+ operand.as_inner().x() * self.em() * self.em()
+ operand.as_inner().x() * self.x() * self.x(),
-(operand.as_inner().y() * self.ep() * self.ep())
+ -(operand.as_inner().y() * self.x() * self.x())
+ -T::TWO * operand.as_inner().em() * self.em() * self.y()
+ T::TWO * operand.as_inner().ep() * self.ep() * self.y()
+ T::TWO * operand.as_inner().x() * self.x() * self.y()
+ operand.as_inner().y() * self.em() * self.em()
+ operand.as_inner().y() * self.y() * self.y(),
-(operand.as_inner().ep() * self.x() * self.x())
+ -(operand.as_inner().ep() * self.y() * self.y())
+ -T::TWO * operand.as_inner().em() * self.em() * self.ep()
+ T::TWO * operand.as_inner().x() * self.ep() * self.x()
+ T::TWO * operand.as_inner().y() * self.ep() * self.y()
+ operand.as_inner().ep() * self.em() * self.em()
+ operand.as_inner().ep() * self.ep() * self.ep(),
-(operand.as_inner().em() * self.em() * self.em())
+ -(operand.as_inner().em() * self.ep() * self.ep())
+ -(operand.as_inner().em() * self.x() * self.x())
+ -(operand.as_inner().em() * self.y() * self.y())
+ T::TWO * operand.as_inner().ep() * self.em() * self.ep()
+ T::TWO * operand.as_inner().x() * self.em() * self.x()
+ T::TWO * operand.as_inner().y() * self.em() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<RoundPoint<T>>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().x() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.as_inner().em() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.as_inner().ep() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().y() * self.as_inner().x() * self.as_inner().y()
+ operand.as_inner().x() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().x() * self.as_inner().x() * self.as_inner().x(),
-(operand.as_inner().y() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().y() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.as_inner().em() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.as_inner().ep() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.as_inner().x() * self.as_inner().x() * self.as_inner().y()
+ operand.as_inner().y() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().y() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().ep() * self.as_inner().x() * self.as_inner().x())
+ -(operand.as_inner().ep() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.as_inner().em() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.as_inner().x() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().y() * self.as_inner().ep() * self.as_inner().y()
+ operand.as_inner().ep() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().ep() * self.as_inner().ep() * self.as_inner().ep(),
-(operand.as_inner().em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().em() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().em() * self.as_inner().x() * self.as_inner().x())
+ -(operand.as_inner().em() * self.as_inner().y() * self.as_inner().y())
+ T::TWO * operand.as_inner().ep() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.as_inner().x() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.as_inner().y() * self.as_inner().em() * self.as_inner().y(),
)
}
}
#[doc = "Sandwich product: [`RoundPoint`] x [`Scalar`] x rev([`RoundPoint`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Scalar<T>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(self.em() * operand.s() * self.em())
+ self.ep() * operand.s() * self.ep()
+ self.x() * operand.s() * self.x()
+ self.y() * operand.s() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Scalar<T>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.s() * self.as_inner().em() * self.as_inner().em())
+ operand.s() * self.as_inner().ep() * self.as_inner().ep()
+ operand.s() * self.as_inner().x() * self.as_inner().x()
+ operand.s() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Scalar<T>>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.em() * self.em())
+ operand.as_inner().s() * self.ep() * self.ep()
+ operand.as_inner().s() * self.x() * self.x()
+ operand.as_inner().s() * self.y() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Scalar<T>>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.as_inner().em() * self.as_inner().em())
+ operand.as_inner().s() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().s() * self.as_inner().x() * self.as_inner().x()
+ operand.as_inner().s() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[doc = "Sandwich product: [`Scalar`] x [`Circle`] x rev([`Scalar`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Circle<T>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
self.s() * operand.w() * self.s(),
self.s() * operand.e12em() * self.s(),
self.s() * operand.e1epem() * self.s(),
self.s() * operand.e2epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Circle<T>> for Unit<Scalar<T>> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
operand.w() * self.as_inner().s() * self.as_inner().s(),
operand.e12em() * self.as_inner().s() * self.as_inner().s(),
operand.e1epem() * self.as_inner().s() * self.as_inner().s(),
operand.e2epem() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Circle<T>>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
operand.as_inner().w() * self.s() * self.s(),
operand.as_inner().e12em() * self.s() * self.s(),
operand.as_inner().e1epem() * self.s() * self.s(),
operand.as_inner().e2epem() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Circle<T>>> for Unit<Scalar<T>> {
type Output = Circle<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
operand.as_inner().w() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().e12em() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().e1epem() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().e2epem() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Sandwich product: [`Scalar`] x [`FlatPoint`] x rev([`Scalar`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<FlatPoint<T>> for Scalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
self.s() * operand.e1em() * self.s(),
self.s() * operand.e2em() * self.s(),
self.s() * operand.epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<FlatPoint<T>> for Unit<Scalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
operand.e1em() * self.as_inner().s() * self.as_inner().s(),
operand.e2em() * self.as_inner().s() * self.as_inner().s(),
operand.epem() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<FlatPoint<T>>> for Scalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
operand.as_inner().e1em() * self.s() * self.s(),
operand.as_inner().e2em() * self.s() * self.s(),
operand.as_inner().epem() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<FlatPoint<T>>> for Unit<Scalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
operand.as_inner().e1em() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().e2em() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().epem() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Sandwich product: [`Scalar`] x [`Line`] x rev([`Scalar`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Line<T>> for Scalar<T> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
self.s() * operand.nx() * self.s(),
self.s() * operand.ny() * self.s(),
self.s() * operand.d() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Line<T>> for Unit<Scalar<T>> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
operand.nx() * self.as_inner().s() * self.as_inner().s(),
operand.ny() * self.as_inner().s() * self.as_inner().s(),
operand.d() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Line<T>>> for Scalar<T> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
operand.as_inner().nx() * self.s() * self.s(),
operand.as_inner().ny() * self.s() * self.s(),
operand.as_inner().d() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Line<T>>> for Unit<Scalar<T>> {
type Output = Line<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
operand.as_inner().nx() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().ny() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().d() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Sandwich product: [`Scalar`] x [`Motor`] x rev([`Scalar`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Motor<T>> for Scalar<T> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
self.s() * operand.s() * self.s(),
self.s() * operand.m() * self.s(),
self.s() * operand.e1ep() * self.s(),
self.s() * operand.e2ep() * self.s(),
self.s() * operand.e1em() * self.s(),
self.s() * operand.e2em() * self.s(),
self.s() * operand.epem() * self.s(),
self.s() * operand.ps() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Motor<T>> for Unit<Scalar<T>> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
operand.s() * self.as_inner().s() * self.as_inner().s(),
operand.m() * self.as_inner().s() * self.as_inner().s(),
operand.e1ep() * self.as_inner().s() * self.as_inner().s(),
operand.e2ep() * self.as_inner().s() * self.as_inner().s(),
operand.e1em() * self.as_inner().s() * self.as_inner().s(),
operand.e2em() * self.as_inner().s() * self.as_inner().s(),
operand.epem() * self.as_inner().s() * self.as_inner().s(),
operand.ps() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Motor<T>>> for Scalar<T> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
operand.as_inner().s() * self.s() * self.s(),
operand.as_inner().m() * self.s() * self.s(),
operand.as_inner().e1ep() * self.s() * self.s(),
operand.as_inner().e2ep() * self.s() * self.s(),
operand.as_inner().e1em() * self.s() * self.s(),
operand.as_inner().e2em() * self.s() * self.s(),
operand.as_inner().epem() * self.s() * self.s(),
operand.as_inner().ps() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Motor<T>>> for Unit<Scalar<T>> {
type Output = Motor<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
operand.as_inner().s() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().m() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().e1ep() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().e2ep() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().e1em() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().e2em() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().epem() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().ps() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Sandwich product: [`Scalar`] x [`PointPair`] x rev([`Scalar`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<PointPair<T>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
self.s() * operand.m() * self.s(),
self.s() * operand.e1ep() * self.s(),
self.s() * operand.e2ep() * self.s(),
self.s() * operand.e1em() * self.s(),
self.s() * operand.e2em() * self.s(),
self.s() * operand.epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<PointPair<T>> for Unit<Scalar<T>> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
operand.m() * self.as_inner().s() * self.as_inner().s(),
operand.e1ep() * self.as_inner().s() * self.as_inner().s(),
operand.e2ep() * self.as_inner().s() * self.as_inner().s(),
operand.e1em() * self.as_inner().s() * self.as_inner().s(),
operand.e2em() * self.as_inner().s() * self.as_inner().s(),
operand.epem() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<PointPair<T>>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
operand.as_inner().m() * self.s() * self.s(),
operand.as_inner().e1ep() * self.s() * self.s(),
operand.as_inner().e2ep() * self.s() * self.s(),
operand.as_inner().e1em() * self.s() * self.s(),
operand.as_inner().e2em() * self.s() * self.s(),
operand.as_inner().epem() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<PointPair<T>>> for Unit<Scalar<T>> {
type Output = PointPair<T>;
#[inline]
fn sandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
operand.as_inner().m() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().e1ep() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().e2ep() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().e1em() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().e2em() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().epem() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Sandwich product: [`Scalar`] x [`Pseudoscalar`] x rev([`Scalar`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Pseudoscalar<T>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(self.s() * operand.ps() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Pseudoscalar<T>> for Unit<Scalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(operand.ps() * self.as_inner().s() * self.as_inner().s())
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Pseudoscalar<T>>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(operand.as_inner().ps() * self.s() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Pseudoscalar<T>>> for Unit<Scalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
operand.as_inner().ps() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Sandwich product: [`Scalar`] x [`RoundPoint`] x rev([`Scalar`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<RoundPoint<T>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
self.s() * operand.x() * self.s(),
self.s() * operand.y() * self.s(),
self.s() * operand.ep() * self.s(),
self.s() * operand.em() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<RoundPoint<T>> for Unit<Scalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
operand.x() * self.as_inner().s() * self.as_inner().s(),
operand.y() * self.as_inner().s() * self.as_inner().s(),
operand.ep() * self.as_inner().s() * self.as_inner().s(),
operand.em() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<RoundPoint<T>>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
operand.as_inner().x() * self.s() * self.s(),
operand.as_inner().y() * self.s() * self.s(),
operand.as_inner().ep() * self.s() * self.s(),
operand.as_inner().em() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<RoundPoint<T>>> for Unit<Scalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn sandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
operand.as_inner().x() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().y() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().ep() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().em() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Sandwich product: [`Scalar`] x [`Scalar`] x rev([`Scalar`]).\n\nThe sandwich product `v x a x rev(v)` applies the transformation\nrepresented by the versor `v` to the operand `a`. For rotors, this\nperforms rotation; for motors, it performs rigid body transformation."]
#[allow(unused_variables)]
impl<T: Float> Sandwich<Scalar<T>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(self.s() * operand.s() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Scalar<T>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(operand.s() * self.as_inner().s() * self.as_inner().s())
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Scalar<T>>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(operand.as_inner().s() * self.s() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> Sandwich<Unit<Scalar<T>>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn sandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(operand.as_inner().s() * self.as_inner().s() * self.as_inner().s())
}
}
#[doc = "Antisandwich product: [`Circle`] x [`Circle`] x antirev([`Circle`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Circle<T>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-(self.e12em() * operand.e12em() * self.w())
+ self.e12em() * operand.w() * self.e12em()
- self.e1epem() * operand.e1epem() * self.w()
+ self.e1epem() * operand.w() * self.e1epem()
- self.e2epem() * operand.e2epem() * self.w()
+ self.e2epem() * operand.w() * self.e2epem()
- self.w() * operand.e12em() * self.e12em()
- self.w() * operand.e1epem() * self.e1epem()
- self.w() * operand.e2epem() * self.e2epem()
+ self.w() * operand.w() * self.w(),
-(self.e12em() * operand.e12em() * self.e12em())
- self.e12em() * operand.e1epem() * self.e1epem()
- self.e12em() * operand.e2epem() * self.e2epem()
+ self.e12em() * operand.w() * self.w()
+ self.e1epem() * operand.e12em() * self.e1epem()
- self.e1epem() * operand.e1epem() * self.e12em()
+ self.e2epem() * operand.e12em() * self.e2epem()
- self.e2epem() * operand.e2epem() * self.e12em()
- self.w() * operand.e12em() * self.w()
+ self.w() * operand.w() * self.e12em(),
-(self.e12em() * operand.e12em() * self.e1epem())
+ self.e12em() * operand.e1epem() * self.e12em()
- self.e1epem() * operand.e12em() * self.e12em()
- self.e1epem() * operand.e1epem() * self.e1epem()
- self.e1epem() * operand.e2epem() * self.e2epem()
+ self.e1epem() * operand.w() * self.w()
+ self.e2epem() * operand.e1epem() * self.e2epem()
- self.e2epem() * operand.e2epem() * self.e1epem()
- self.w() * operand.e1epem() * self.w()
+ self.w() * operand.w() * self.e1epem(),
-(self.e12em() * operand.e12em() * self.e2epem())
+ self.e12em() * operand.e2epem() * self.e12em()
- self.e1epem() * operand.e1epem() * self.e2epem()
+ self.e1epem() * operand.e2epem() * self.e1epem()
- self.e2epem() * operand.e12em() * self.e12em()
- self.e2epem() * operand.e1epem() * self.e1epem()
- self.e2epem() * operand.e2epem() * self.e2epem()
+ self.e2epem() * operand.w() * self.w()
- self.w() * operand.e2epem() * self.w()
+ self.w() * operand.w() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Circle<T>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.e12em() * self.as_inner().e12em() * self.as_inner().w()
+ -T::TWO * operand.e1epem() * self.as_inner().e1epem() * self.as_inner().w()
+ -T::TWO * operand.e2epem() * self.as_inner().e2epem() * self.as_inner().w()
+ operand.w() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.w() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.w() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.w() * self.as_inner().w() * self.as_inner().w(),
-(operand.e12em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.e12em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.e1epem() * self.as_inner().e12em() * self.as_inner().e1epem()
+ -T::TWO * operand.e2epem() * self.as_inner().e12em() * self.as_inner().e2epem()
+ T::TWO * operand.w() * self.as_inner().e12em() * self.as_inner().w()
+ operand.e12em() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.e12em() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.e1epem() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.e1epem() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.e12em() * self.as_inner().e12em() * self.as_inner().e1epem()
+ -T::TWO * operand.e2epem() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.w() * self.as_inner().e1epem() * self.as_inner().w()
+ operand.e1epem() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.e1epem() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.e2epem() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.e2epem() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.e12em() * self.as_inner().e12em() * self.as_inner().e2epem()
+ -T::TWO * operand.e1epem() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.w() * self.as_inner().e2epem() * self.as_inner().w()
+ operand.e2epem() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.e2epem() * self.as_inner().e1epem() * self.as_inner().e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Circle<T>>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.as_inner().e12em() * self.e12em() * self.w()
+ -T::TWO * operand.as_inner().e1epem() * self.e1epem() * self.w()
+ -T::TWO * operand.as_inner().e2epem() * self.e2epem() * self.w()
+ operand.as_inner().w() * self.e12em() * self.e12em()
+ operand.as_inner().w() * self.e1epem() * self.e1epem()
+ operand.as_inner().w() * self.e2epem() * self.e2epem()
+ operand.as_inner().w() * self.w() * self.w(),
-(operand.as_inner().e12em() * self.e12em() * self.e12em())
+ -(operand.as_inner().e12em() * self.w() * self.w())
+ -T::TWO * operand.as_inner().e1epem() * self.e12em() * self.e1epem()
+ -T::TWO * operand.as_inner().e2epem() * self.e12em() * self.e2epem()
+ T::TWO * operand.as_inner().w() * self.e12em() * self.w()
+ operand.as_inner().e12em() * self.e1epem() * self.e1epem()
+ operand.as_inner().e12em() * self.e2epem() * self.e2epem(),
-(operand.as_inner().e1epem() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().e1epem() * self.w() * self.w())
+ -T::TWO * operand.as_inner().e12em() * self.e12em() * self.e1epem()
+ -T::TWO * operand.as_inner().e2epem() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().w() * self.e1epem() * self.w()
+ operand.as_inner().e1epem() * self.e12em() * self.e12em()
+ operand.as_inner().e1epem() * self.e2epem() * self.e2epem(),
-(operand.as_inner().e2epem() * self.e2epem() * self.e2epem())
+ -(operand.as_inner().e2epem() * self.w() * self.w())
+ -T::TWO * operand.as_inner().e12em() * self.e12em() * self.e2epem()
+ -T::TWO * operand.as_inner().e1epem() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().w() * self.e2epem() * self.w()
+ operand.as_inner().e2epem() * self.e12em() * self.e12em()
+ operand.as_inner().e2epem() * self.e1epem() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Circle<T>>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.as_inner().e12em() * self.as_inner().e12em() * self.as_inner().w()
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1epem()
* self.as_inner().w()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e2epem()
* self.as_inner().w()
+ operand.as_inner().w() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().w() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().w() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.as_inner().w() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().e12em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().e12em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ T::TWO * operand.as_inner().w() * self.as_inner().e12em() * self.as_inner().w()
+ operand.as_inner().e12em() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().e12em() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.as_inner().e1epem() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.as_inner().e1epem() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO * operand.as_inner().w() * self.as_inner().e1epem() * self.as_inner().w()
+ operand.as_inner().e1epem() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().e1epem() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.as_inner().e2epem() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.as_inner().e2epem() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO * operand.as_inner().w() * self.as_inner().e2epem() * self.as_inner().w()
+ operand.as_inner().e2epem() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().e2epem() * self.as_inner().e1epem() * self.as_inner().e1epem(),
)
}
}
#[doc = "Antisandwich product: [`Circle`] x [`FlatPoint`] x antirev([`Circle`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<FlatPoint<T>> for Circle<T> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
self.e12em() * operand.e1em() * self.e12em()
- self.e12em() * operand.epem() * self.e2epem()
+ self.e1epem() * operand.e1em() * self.e1epem()
+ self.e1epem() * operand.e2em() * self.e2epem()
- self.e2epem() * operand.e1em() * self.e2epem()
+ self.e2epem() * operand.e2em() * self.e1epem()
- self.e2epem() * operand.epem() * self.e12em()
+ self.w() * operand.e1em() * self.w(),
self.e12em() * operand.e2em() * self.e12em()
+ self.e12em() * operand.epem() * self.e1epem()
+ self.e1epem() * operand.e1em() * self.e2epem()
- self.e1epem() * operand.e2em() * self.e1epem()
+ self.e1epem() * operand.epem() * self.e12em()
+ self.e2epem() * operand.e1em() * self.e1epem()
+ self.e2epem() * operand.e2em() * self.e2epem()
+ self.w() * operand.e2em() * self.w(),
-(self.e12em() * operand.e1em() * self.e2epem())
+ self.e12em() * operand.e2em() * self.e1epem()
- self.e12em() * operand.epem() * self.e12em()
+ self.e1epem() * operand.e2em() * self.e12em()
+ self.e1epem() * operand.epem() * self.e1epem()
- self.e2epem() * operand.e1em() * self.e12em()
+ self.e2epem() * operand.epem() * self.e2epem()
+ self.w() * operand.epem() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<FlatPoint<T>> for Unit<Circle<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.e1em() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO * operand.epem() * self.as_inner().e12em() * self.as_inner().e2epem()
+ T::TWO * operand.e2em() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ operand.e1em() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.e1em() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.e1em() * self.as_inner().w() * self.as_inner().w(),
-(operand.e2em() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ T::TWO * operand.e1em() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.epem() * self.as_inner().e12em() * self.as_inner().e1epem()
+ operand.e2em() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.e2em() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.e2em() * self.as_inner().w() * self.as_inner().w(),
-(operand.epem() * self.as_inner().e12em() * self.as_inner().e12em())
+ -T::TWO * operand.e1em() * self.as_inner().e12em() * self.as_inner().e2epem()
+ T::TWO * operand.e2em() * self.as_inner().e12em() * self.as_inner().e1epem()
+ operand.epem() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.epem() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.epem() * self.as_inner().w() * self.as_inner().w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<FlatPoint<T>>> for Circle<T> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.e2epem() * self.e2epem())
+ -T::TWO * operand.as_inner().epem() * self.e12em() * self.e2epem()
+ T::TWO * operand.as_inner().e2em() * self.e1epem() * self.e2epem()
+ operand.as_inner().e1em() * self.e12em() * self.e12em()
+ operand.as_inner().e1em() * self.e1epem() * self.e1epem()
+ operand.as_inner().e1em() * self.w() * self.w(),
-(operand.as_inner().e2em() * self.e1epem() * self.e1epem())
+ T::TWO * operand.as_inner().e1em() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().epem() * self.e12em() * self.e1epem()
+ operand.as_inner().e2em() * self.e12em() * self.e12em()
+ operand.as_inner().e2em() * self.e2epem() * self.e2epem()
+ operand.as_inner().e2em() * self.w() * self.w(),
-(operand.as_inner().epem() * self.e12em() * self.e12em())
+ -T::TWO * operand.as_inner().e1em() * self.e12em() * self.e2epem()
+ T::TWO * operand.as_inner().e2em() * self.e12em() * self.e1epem()
+ operand.as_inner().epem() * self.e1epem() * self.e1epem()
+ operand.as_inner().epem() * self.e2epem() * self.e2epem()
+ operand.as_inner().epem() * self.w() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<FlatPoint<T>>> for Unit<Circle<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ operand.as_inner().e1em() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().e1em() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().e1em() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().e2em() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ operand.as_inner().e2em() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().e2em() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.as_inner().e2em() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().epem() * self.as_inner().e12em() * self.as_inner().e12em())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ operand.as_inner().epem() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().epem() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.as_inner().epem() * self.as_inner().w() * self.as_inner().w(),
)
}
}
#[doc = "Antisandwich product: [`Circle`] x [`Line`] x antirev([`Circle`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Line<T>> for Circle<T> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(self.e12em() * operand.d() * self.e2epem())
- self.e12em() * operand.nx() * self.e12em()
- self.e12em() * operand.ny() * self.e1epem()
+ self.e1epem() * operand.nx() * self.e1epem()
- self.e1epem() * operand.ny() * self.e12em()
- self.e2epem() * operand.d() * self.e12em()
+ self.e2epem() * operand.nx() * self.e2epem()
- self.w() * operand.nx() * self.w(),
-(self.e12em() * operand.nx() * self.e1epem())
+ self.e12em() * operand.ny() * self.e12em()
- self.e1epem() * operand.d() * self.e2epem()
- self.e1epem() * operand.nx() * self.e12em()
- self.e1epem() * operand.ny() * self.e1epem()
- self.e2epem() * operand.d() * self.e1epem()
+ self.e2epem() * operand.ny() * self.e2epem()
- self.w() * operand.ny() * self.w(),
self.e12em() * operand.d() * self.e12em() - self.e12em() * operand.nx() * self.e2epem()
+ self.e1epem() * operand.d() * self.e1epem()
- self.e1epem() * operand.ny() * self.e2epem()
- self.e2epem() * operand.d() * self.e2epem()
- self.e2epem() * operand.nx() * self.e12em()
- self.e2epem() * operand.ny() * self.e1epem()
- self.w() * operand.d() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Line<T>> for Unit<Circle<T>> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(operand.nx() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.nx() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.d() * self.as_inner().e12em() * self.as_inner().e2epem()
+ -T::TWO * operand.ny() * self.as_inner().e12em() * self.as_inner().e1epem()
+ operand.nx() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.nx() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.ny() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.ny() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.d() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ -T::TWO * operand.nx() * self.as_inner().e12em() * self.as_inner().e1epem()
+ operand.ny() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.ny() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.d() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.d() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.nx() * self.as_inner().e12em() * self.as_inner().e2epem()
+ -T::TWO * operand.ny() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ operand.d() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.d() * self.as_inner().e1epem() * self.as_inner().e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Line<T>>> for Circle<T> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.e12em() * self.e12em())
+ -(operand.as_inner().nx() * self.w() * self.w())
+ -T::TWO * operand.as_inner().d() * self.e12em() * self.e2epem()
+ -T::TWO * operand.as_inner().ny() * self.e12em() * self.e1epem()
+ operand.as_inner().nx() * self.e1epem() * self.e1epem()
+ operand.as_inner().nx() * self.e2epem() * self.e2epem(),
-(operand.as_inner().ny() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().ny() * self.w() * self.w())
+ -T::TWO * operand.as_inner().d() * self.e1epem() * self.e2epem()
+ -T::TWO * operand.as_inner().nx() * self.e12em() * self.e1epem()
+ operand.as_inner().ny() * self.e12em() * self.e12em()
+ operand.as_inner().ny() * self.e2epem() * self.e2epem(),
-(operand.as_inner().d() * self.e2epem() * self.e2epem())
+ -(operand.as_inner().d() * self.w() * self.w())
+ -T::TWO * operand.as_inner().nx() * self.e12em() * self.e2epem()
+ -T::TWO * operand.as_inner().ny() * self.e1epem() * self.e2epem()
+ operand.as_inner().d() * self.e12em() * self.e12em()
+ operand.as_inner().d() * self.e1epem() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Line<T>>> for Unit<Circle<T>> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().nx() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().d()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ -T::TWO
* operand.as_inner().ny()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ operand.as_inner().nx() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().nx() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.as_inner().ny() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.as_inner().ny() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().d()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ -T::TWO
* operand.as_inner().nx()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ operand.as_inner().ny() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().ny() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.as_inner().d() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.as_inner().d() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().nx()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ -T::TWO
* operand.as_inner().ny()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ operand.as_inner().d() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().d() * self.as_inner().e1epem() * self.as_inner().e1epem(),
)
}
}
#[doc = "Antisandwich product: [`Circle`] x [`Motor`] x antirev([`Circle`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Motor<T>> for Circle<T> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
self.e12em() * operand.e1ep() * self.e2epem()
- self.e12em() * operand.e2ep() * self.e1epem()
+ self.e12em() * operand.epem() * self.w()
+ self.e12em() * operand.s() * self.e12em()
- self.e1epem() * operand.e2em() * self.w()
+ self.e1epem() * operand.e2ep() * self.e12em()
- self.e1epem() * operand.m() * self.e2epem()
+ self.e1epem() * operand.s() * self.e1epem()
+ self.e2epem() * operand.e1em() * self.w()
- self.e2epem() * operand.e1ep() * self.e12em()
+ self.e2epem() * operand.m() * self.e1epem()
+ self.e2epem() * operand.s() * self.e2epem()
- self.w() * operand.e1em() * self.e2epem()
+ self.w() * operand.e2em() * self.e1epem()
- self.w() * operand.epem() * self.e12em()
- self.w() * operand.s() * self.w(),
self.e12em() * operand.e1ep() * self.e1epem()
+ self.e12em() * operand.e2ep() * self.e2epem()
+ self.e12em() * operand.m() * self.e12em()
+ self.e12em() * operand.ps() * self.w()
- self.e1epem() * operand.e1em() * self.w()
+ self.e1epem() * operand.e1ep() * self.e12em()
- self.e1epem() * operand.m() * self.e1epem()
- self.e1epem() * operand.s() * self.e2epem()
- self.e2epem() * operand.e2em() * self.w()
+ self.e2epem() * operand.e2ep() * self.e12em()
- self.e2epem() * operand.m() * self.e2epem()
+ self.e2epem() * operand.s() * self.e1epem()
- self.w() * operand.e1em() * self.e1epem()
- self.w() * operand.e2em() * self.e2epem()
- self.w() * operand.m() * self.w()
- self.w() * operand.ps() * self.e12em(),
self.e12em() * operand.e1em() * self.w() - self.e12em() * operand.e1ep() * self.e12em()
+ self.e12em() * operand.m() * self.e1epem()
+ self.e12em() * operand.s() * self.e2epem()
+ self.e1epem() * operand.e1ep() * self.e1epem()
+ self.e1epem() * operand.e2ep() * self.e2epem()
+ self.e1epem() * operand.m() * self.e12em()
+ self.e1epem() * operand.ps() * self.w()
- self.e2epem() * operand.e1ep() * self.e2epem()
+ self.e2epem() * operand.e2ep() * self.e1epem()
- self.e2epem() * operand.epem() * self.w()
- self.e2epem() * operand.s() * self.e12em()
+ self.w() * operand.e1em() * self.e12em()
- self.w() * operand.e1ep() * self.w()
- self.w() * operand.epem() * self.e2epem()
- self.w() * operand.ps() * self.e1epem(),
self.e12em() * operand.e2em() * self.w() - self.e12em() * operand.e2ep() * self.e12em()
+ self.e12em() * operand.m() * self.e2epem()
- self.e12em() * operand.s() * self.e1epem()
+ self.e1epem() * operand.e1ep() * self.e2epem()
- self.e1epem() * operand.e2ep() * self.e1epem()
+ self.e1epem() * operand.epem() * self.w()
+ self.e1epem() * operand.s() * self.e12em()
+ self.e2epem() * operand.e1ep() * self.e1epem()
+ self.e2epem() * operand.e2ep() * self.e2epem()
+ self.e2epem() * operand.m() * self.e12em()
+ self.e2epem() * operand.ps() * self.w()
+ self.w() * operand.e2em() * self.e12em()
- self.w() * operand.e2ep() * self.w()
+ self.w() * operand.epem() * self.e1epem()
- self.w() * operand.ps() * self.e2epem(),
self.e12em() * operand.e1em() * self.e12em()
- self.e12em() * operand.e1ep() * self.w()
- self.e12em() * operand.epem() * self.e2epem()
- self.e12em() * operand.ps() * self.e1epem()
+ self.e1epem() * operand.e1em() * self.e1epem()
+ self.e1epem() * operand.e2em() * self.e2epem()
+ self.e1epem() * operand.m() * self.w()
+ self.e1epem() * operand.ps() * self.e12em()
- self.e2epem() * operand.e1em() * self.e2epem()
+ self.e2epem() * operand.e2em() * self.e1epem()
- self.e2epem() * operand.epem() * self.e12em()
- self.e2epem() * operand.s() * self.w()
+ self.w() * operand.e1em() * self.w()
- self.w() * operand.e1ep() * self.e12em()
+ self.w() * operand.m() * self.e1epem()
+ self.w() * operand.s() * self.e2epem(),
self.e12em() * operand.e2em() * self.e12em() - self.e12em() * operand.e2ep() * self.w()
+ self.e12em() * operand.epem() * self.e1epem()
- self.e12em() * operand.ps() * self.e2epem()
+ self.e1epem() * operand.e1em() * self.e2epem()
- self.e1epem() * operand.e2em() * self.e1epem()
+ self.e1epem() * operand.epem() * self.e12em()
+ self.e1epem() * operand.s() * self.w()
+ self.e2epem() * operand.e1em() * self.e1epem()
+ self.e2epem() * operand.e2em() * self.e2epem()
+ self.e2epem() * operand.m() * self.w()
+ self.e2epem() * operand.ps() * self.e12em()
+ self.w() * operand.e2em() * self.w()
- self.w() * operand.e2ep() * self.e12em()
+ self.w() * operand.m() * self.e2epem()
- self.w() * operand.s() * self.e1epem(),
-(self.e12em() * operand.e1em() * self.e2epem())
+ self.e12em() * operand.e2em() * self.e1epem()
- self.e12em() * operand.epem() * self.e12em()
- self.e12em() * operand.s() * self.w()
+ self.e1epem() * operand.e2em() * self.e12em()
- self.e1epem() * operand.e2ep() * self.w()
+ self.e1epem() * operand.epem() * self.e1epem()
- self.e1epem() * operand.ps() * self.e2epem()
- self.e2epem() * operand.e1em() * self.e12em()
+ self.e2epem() * operand.e1ep() * self.w()
+ self.e2epem() * operand.epem() * self.e2epem()
+ self.e2epem() * operand.ps() * self.e1epem()
+ self.w() * operand.e1ep() * self.e2epem()
- self.w() * operand.e2ep() * self.e1epem()
+ self.w() * operand.epem() * self.w()
+ self.w() * operand.s() * self.e12em(),
-(self.e12em() * operand.e1em() * self.e1epem())
- self.e12em() * operand.e2em() * self.e2epem()
- self.e12em() * operand.m() * self.w()
- self.e12em() * operand.ps() * self.e12em()
+ self.e1epem() * operand.e1em() * self.e12em()
- self.e1epem() * operand.e1ep() * self.w()
- self.e1epem() * operand.epem() * self.e2epem()
- self.e1epem() * operand.ps() * self.e1epem()
+ self.e2epem() * operand.e2em() * self.e12em()
- self.e2epem() * operand.e2ep() * self.w()
+ self.e2epem() * operand.epem() * self.e1epem()
- self.e2epem() * operand.ps() * self.e2epem()
+ self.w() * operand.e1ep() * self.e1epem()
+ self.w() * operand.e2ep() * self.e2epem()
+ self.w() * operand.m() * self.e12em()
+ self.w() * operand.ps() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Motor<T>> for Unit<Circle<T>> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(operand.s() * self.as_inner().w() * self.as_inner().w())
+ operand.s() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.s() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.s() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.m() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.m() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.m() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.e1em() * self.as_inner().e1epem() * self.as_inner().w()
+ -T::TWO * operand.e2em() * self.as_inner().e2epem() * self.as_inner().w()
+ T::TWO * operand.e1ep() * self.as_inner().e12em() * self.as_inner().e1epem()
+ T::TWO * operand.e2ep() * self.as_inner().e12em() * self.as_inner().e2epem()
+ operand.m() * self.as_inner().e12em() * self.as_inner().e12em(),
-(operand.e1ep() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.e1ep() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.e1ep() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.epem() * self.as_inner().e2epem() * self.as_inner().w()
+ T::TWO * operand.e1em() * self.as_inner().e12em() * self.as_inner().w()
+ T::TWO * operand.e2ep() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.m() * self.as_inner().e12em() * self.as_inner().e1epem()
+ operand.e1ep() * self.as_inner().e1epem() * self.as_inner().e1epem(),
-(operand.e2ep() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.e2ep() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.e2ep() * self.as_inner().w() * self.as_inner().w())
+ T::TWO * operand.e1ep() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.e2em() * self.as_inner().e12em() * self.as_inner().w()
+ T::TWO * operand.epem() * self.as_inner().e1epem() * self.as_inner().w()
+ T::TWO * operand.m() * self.as_inner().e12em() * self.as_inner().e2epem()
+ operand.e2ep() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.e1em() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO * operand.e1ep() * self.as_inner().e12em() * self.as_inner().w()
+ -T::TWO * operand.epem() * self.as_inner().e12em() * self.as_inner().e2epem()
+ T::TWO * operand.e2em() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.m() * self.as_inner().e1epem() * self.as_inner().w()
+ operand.e1em() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.e1em() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.e1em() * self.as_inner().w() * self.as_inner().w(),
-(operand.e2em() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -T::TWO * operand.e2ep() * self.as_inner().e12em() * self.as_inner().w()
+ T::TWO * operand.e1em() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.epem() * self.as_inner().e12em() * self.as_inner().e1epem()
+ T::TWO * operand.m() * self.as_inner().e2epem() * self.as_inner().w()
+ operand.e2em() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.e2em() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.e2em() * self.as_inner().w() * self.as_inner().w(),
-(operand.epem() * self.as_inner().e12em() * self.as_inner().e12em())
+ -T::TWO * operand.e1em() * self.as_inner().e12em() * self.as_inner().e2epem()
+ -T::TWO * operand.e2ep() * self.as_inner().e1epem() * self.as_inner().w()
+ T::TWO * operand.e1ep() * self.as_inner().e2epem() * self.as_inner().w()
+ T::TWO * operand.e2em() * self.as_inner().e12em() * self.as_inner().e1epem()
+ operand.epem() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.epem() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.epem() * self.as_inner().w() * self.as_inner().w(),
-(operand.ps() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.ps() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.ps() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ operand.ps() * self.as_inner().w() * self.as_inner().w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Motor<T>>> for Circle<T> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.w() * self.w())
+ operand.as_inner().s() * self.e12em() * self.e12em()
+ operand.as_inner().s() * self.e1epem() * self.e1epem()
+ operand.as_inner().s() * self.e2epem() * self.e2epem(),
-(operand.as_inner().m() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().m() * self.e2epem() * self.e2epem())
+ -(operand.as_inner().m() * self.w() * self.w())
+ -T::TWO * operand.as_inner().e1em() * self.e1epem() * self.w()
+ -T::TWO * operand.as_inner().e2em() * self.e2epem() * self.w()
+ T::TWO * operand.as_inner().e1ep() * self.e12em() * self.e1epem()
+ T::TWO * operand.as_inner().e2ep() * self.e12em() * self.e2epem()
+ operand.as_inner().m() * self.e12em() * self.e12em(),
-(operand.as_inner().e1ep() * self.e12em() * self.e12em())
+ -(operand.as_inner().e1ep() * self.e2epem() * self.e2epem())
+ -(operand.as_inner().e1ep() * self.w() * self.w())
+ -T::TWO * operand.as_inner().epem() * self.e2epem() * self.w()
+ T::TWO * operand.as_inner().e1em() * self.e12em() * self.w()
+ T::TWO * operand.as_inner().e2ep() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().m() * self.e12em() * self.e1epem()
+ operand.as_inner().e1ep() * self.e1epem() * self.e1epem(),
-(operand.as_inner().e2ep() * self.e12em() * self.e12em())
+ -(operand.as_inner().e2ep() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().e2ep() * self.w() * self.w())
+ T::TWO * operand.as_inner().e1ep() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().e2em() * self.e12em() * self.w()
+ T::TWO * operand.as_inner().epem() * self.e1epem() * self.w()
+ T::TWO * operand.as_inner().m() * self.e12em() * self.e2epem()
+ operand.as_inner().e2ep() * self.e2epem() * self.e2epem(),
-(operand.as_inner().e1em() * self.e2epem() * self.e2epem())
+ -T::TWO * operand.as_inner().e1ep() * self.e12em() * self.w()
+ -T::TWO * operand.as_inner().epem() * self.e12em() * self.e2epem()
+ T::TWO * operand.as_inner().e2em() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().m() * self.e1epem() * self.w()
+ operand.as_inner().e1em() * self.e12em() * self.e12em()
+ operand.as_inner().e1em() * self.e1epem() * self.e1epem()
+ operand.as_inner().e1em() * self.w() * self.w(),
-(operand.as_inner().e2em() * self.e1epem() * self.e1epem())
+ -T::TWO * operand.as_inner().e2ep() * self.e12em() * self.w()
+ T::TWO * operand.as_inner().e1em() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().epem() * self.e12em() * self.e1epem()
+ T::TWO * operand.as_inner().m() * self.e2epem() * self.w()
+ operand.as_inner().e2em() * self.e12em() * self.e12em()
+ operand.as_inner().e2em() * self.e2epem() * self.e2epem()
+ operand.as_inner().e2em() * self.w() * self.w(),
-(operand.as_inner().epem() * self.e12em() * self.e12em())
+ -T::TWO * operand.as_inner().e1em() * self.e12em() * self.e2epem()
+ -T::TWO * operand.as_inner().e2ep() * self.e1epem() * self.w()
+ T::TWO * operand.as_inner().e1ep() * self.e2epem() * self.w()
+ T::TWO * operand.as_inner().e2em() * self.e12em() * self.e1epem()
+ operand.as_inner().epem() * self.e1epem() * self.e1epem()
+ operand.as_inner().epem() * self.e2epem() * self.e2epem()
+ operand.as_inner().epem() * self.w() * self.w(),
-(operand.as_inner().ps() * self.e12em() * self.e12em())
+ -(operand.as_inner().ps() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().ps() * self.e2epem() * self.e2epem())
+ operand.as_inner().ps() * self.w() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Motor<T>>> for Unit<Circle<T>> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.as_inner().w() * self.as_inner().w())
+ operand.as_inner().s() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().s() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().s() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.as_inner().m() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.as_inner().m() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.as_inner().m() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1epem()
* self.as_inner().w()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2epem()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ operand.as_inner().m() * self.as_inner().e12em() * self.as_inner().e12em(),
-(operand.as_inner().e1ep() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().e1ep()
* self.as_inner().e2epem()
* self.as_inner().e2epem())
+ -(operand.as_inner().e1ep() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2epem()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e12em()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().m()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ operand.as_inner().e1ep() * self.as_inner().e1epem() * self.as_inner().e1epem(),
-(operand.as_inner().e2ep() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().e2ep()
* self.as_inner().e1epem()
* self.as_inner().e1epem())
+ -(operand.as_inner().e2ep() * self.as_inner().w() * self.as_inner().w())
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e12em()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1epem()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().m()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ operand.as_inner().e2ep() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.as_inner().e1em() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e12em()
* self.as_inner().w()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1epem() * self.as_inner().w()
+ operand.as_inner().e1em() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().e1em() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().e1em() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().e2em() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e12em()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2epem() * self.as_inner().w()
+ operand.as_inner().e2em() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().e2em() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.as_inner().e2em() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().epem() * self.as_inner().e12em() * self.as_inner().e12em())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1epem()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2epem()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ operand.as_inner().epem() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().epem() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.as_inner().epem() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().ps() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().ps() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.as_inner().ps() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ operand.as_inner().ps() * self.as_inner().w() * self.as_inner().w(),
)
}
}
#[doc = "Antisandwich product: [`Circle`] x [`PointPair`] x antirev([`Circle`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<PointPair<T>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
self.e12em() * operand.e1ep() * self.e1epem()
+ self.e12em() * operand.e2ep() * self.e2epem()
+ self.e12em() * operand.m() * self.e12em()
- self.e1epem() * operand.e1em() * self.w()
+ self.e1epem() * operand.e1ep() * self.e12em()
- self.e1epem() * operand.m() * self.e1epem()
- self.e2epem() * operand.e2em() * self.w()
+ self.e2epem() * operand.e2ep() * self.e12em()
- self.e2epem() * operand.m() * self.e2epem()
- self.w() * operand.e1em() * self.e1epem()
- self.w() * operand.e2em() * self.e2epem()
- self.w() * operand.m() * self.w(),
self.e12em() * operand.e1em() * self.w() - self.e12em() * operand.e1ep() * self.e12em()
+ self.e12em() * operand.m() * self.e1epem()
+ self.e1epem() * operand.e1ep() * self.e1epem()
+ self.e1epem() * operand.e2ep() * self.e2epem()
+ self.e1epem() * operand.m() * self.e12em()
- self.e2epem() * operand.e1ep() * self.e2epem()
+ self.e2epem() * operand.e2ep() * self.e1epem()
- self.e2epem() * operand.epem() * self.w()
+ self.w() * operand.e1em() * self.e12em()
- self.w() * operand.e1ep() * self.w()
- self.w() * operand.epem() * self.e2epem(),
self.e12em() * operand.e2em() * self.w() - self.e12em() * operand.e2ep() * self.e12em()
+ self.e12em() * operand.m() * self.e2epem()
+ self.e1epem() * operand.e1ep() * self.e2epem()
- self.e1epem() * operand.e2ep() * self.e1epem()
+ self.e1epem() * operand.epem() * self.w()
+ self.e2epem() * operand.e1ep() * self.e1epem()
+ self.e2epem() * operand.e2ep() * self.e2epem()
+ self.e2epem() * operand.m() * self.e12em()
+ self.w() * operand.e2em() * self.e12em()
- self.w() * operand.e2ep() * self.w()
+ self.w() * operand.epem() * self.e1epem(),
self.e12em() * operand.e1em() * self.e12em()
- self.e12em() * operand.e1ep() * self.w()
- self.e12em() * operand.epem() * self.e2epem()
+ self.e1epem() * operand.e1em() * self.e1epem()
+ self.e1epem() * operand.e2em() * self.e2epem()
+ self.e1epem() * operand.m() * self.w()
- self.e2epem() * operand.e1em() * self.e2epem()
+ self.e2epem() * operand.e2em() * self.e1epem()
- self.e2epem() * operand.epem() * self.e12em()
+ self.w() * operand.e1em() * self.w()
- self.w() * operand.e1ep() * self.e12em()
+ self.w() * operand.m() * self.e1epem(),
self.e12em() * operand.e2em() * self.e12em() - self.e12em() * operand.e2ep() * self.w()
+ self.e12em() * operand.epem() * self.e1epem()
+ self.e1epem() * operand.e1em() * self.e2epem()
- self.e1epem() * operand.e2em() * self.e1epem()
+ self.e1epem() * operand.epem() * self.e12em()
+ self.e2epem() * operand.e1em() * self.e1epem()
+ self.e2epem() * operand.e2em() * self.e2epem()
+ self.e2epem() * operand.m() * self.w()
+ self.w() * operand.e2em() * self.w()
- self.w() * operand.e2ep() * self.e12em()
+ self.w() * operand.m() * self.e2epem(),
-(self.e12em() * operand.e1em() * self.e2epem())
+ self.e12em() * operand.e2em() * self.e1epem()
- self.e12em() * operand.epem() * self.e12em()
+ self.e1epem() * operand.e2em() * self.e12em()
- self.e1epem() * operand.e2ep() * self.w()
+ self.e1epem() * operand.epem() * self.e1epem()
- self.e2epem() * operand.e1em() * self.e12em()
+ self.e2epem() * operand.e1ep() * self.w()
+ self.e2epem() * operand.epem() * self.e2epem()
+ self.w() * operand.e1ep() * self.e2epem()
- self.w() * operand.e2ep() * self.e1epem()
+ self.w() * operand.epem() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<PointPair<T>> for Unit<Circle<T>> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.m() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.m() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.m() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.e1em() * self.as_inner().e1epem() * self.as_inner().w()
+ -T::TWO * operand.e2em() * self.as_inner().e2epem() * self.as_inner().w()
+ T::TWO * operand.e1ep() * self.as_inner().e12em() * self.as_inner().e1epem()
+ T::TWO * operand.e2ep() * self.as_inner().e12em() * self.as_inner().e2epem()
+ operand.m() * self.as_inner().e12em() * self.as_inner().e12em(),
-(operand.e1ep() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.e1ep() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.e1ep() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.epem() * self.as_inner().e2epem() * self.as_inner().w()
+ T::TWO * operand.e1em() * self.as_inner().e12em() * self.as_inner().w()
+ T::TWO * operand.e2ep() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.m() * self.as_inner().e12em() * self.as_inner().e1epem()
+ operand.e1ep() * self.as_inner().e1epem() * self.as_inner().e1epem(),
-(operand.e2ep() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.e2ep() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.e2ep() * self.as_inner().w() * self.as_inner().w())
+ T::TWO * operand.e1ep() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.e2em() * self.as_inner().e12em() * self.as_inner().w()
+ T::TWO * operand.epem() * self.as_inner().e1epem() * self.as_inner().w()
+ T::TWO * operand.m() * self.as_inner().e12em() * self.as_inner().e2epem()
+ operand.e2ep() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.e1em() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO * operand.e1ep() * self.as_inner().e12em() * self.as_inner().w()
+ -T::TWO * operand.epem() * self.as_inner().e12em() * self.as_inner().e2epem()
+ T::TWO * operand.e2em() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.m() * self.as_inner().e1epem() * self.as_inner().w()
+ operand.e1em() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.e1em() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.e1em() * self.as_inner().w() * self.as_inner().w(),
-(operand.e2em() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -T::TWO * operand.e2ep() * self.as_inner().e12em() * self.as_inner().w()
+ T::TWO * operand.e1em() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.epem() * self.as_inner().e12em() * self.as_inner().e1epem()
+ T::TWO * operand.m() * self.as_inner().e2epem() * self.as_inner().w()
+ operand.e2em() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.e2em() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.e2em() * self.as_inner().w() * self.as_inner().w(),
-(operand.epem() * self.as_inner().e12em() * self.as_inner().e12em())
+ -T::TWO * operand.e1em() * self.as_inner().e12em() * self.as_inner().e2epem()
+ -T::TWO * operand.e2ep() * self.as_inner().e1epem() * self.as_inner().w()
+ T::TWO * operand.e1ep() * self.as_inner().e2epem() * self.as_inner().w()
+ T::TWO * operand.e2em() * self.as_inner().e12em() * self.as_inner().e1epem()
+ operand.epem() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.epem() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.epem() * self.as_inner().w() * self.as_inner().w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<PointPair<T>>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().m() * self.e2epem() * self.e2epem())
+ -(operand.as_inner().m() * self.w() * self.w())
+ -T::TWO * operand.as_inner().e1em() * self.e1epem() * self.w()
+ -T::TWO * operand.as_inner().e2em() * self.e2epem() * self.w()
+ T::TWO * operand.as_inner().e1ep() * self.e12em() * self.e1epem()
+ T::TWO * operand.as_inner().e2ep() * self.e12em() * self.e2epem()
+ operand.as_inner().m() * self.e12em() * self.e12em(),
-(operand.as_inner().e1ep() * self.e12em() * self.e12em())
+ -(operand.as_inner().e1ep() * self.e2epem() * self.e2epem())
+ -(operand.as_inner().e1ep() * self.w() * self.w())
+ -T::TWO * operand.as_inner().epem() * self.e2epem() * self.w()
+ T::TWO * operand.as_inner().e1em() * self.e12em() * self.w()
+ T::TWO * operand.as_inner().e2ep() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().m() * self.e12em() * self.e1epem()
+ operand.as_inner().e1ep() * self.e1epem() * self.e1epem(),
-(operand.as_inner().e2ep() * self.e12em() * self.e12em())
+ -(operand.as_inner().e2ep() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().e2ep() * self.w() * self.w())
+ T::TWO * operand.as_inner().e1ep() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().e2em() * self.e12em() * self.w()
+ T::TWO * operand.as_inner().epem() * self.e1epem() * self.w()
+ T::TWO * operand.as_inner().m() * self.e12em() * self.e2epem()
+ operand.as_inner().e2ep() * self.e2epem() * self.e2epem(),
-(operand.as_inner().e1em() * self.e2epem() * self.e2epem())
+ -T::TWO * operand.as_inner().e1ep() * self.e12em() * self.w()
+ -T::TWO * operand.as_inner().epem() * self.e12em() * self.e2epem()
+ T::TWO * operand.as_inner().e2em() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().m() * self.e1epem() * self.w()
+ operand.as_inner().e1em() * self.e12em() * self.e12em()
+ operand.as_inner().e1em() * self.e1epem() * self.e1epem()
+ operand.as_inner().e1em() * self.w() * self.w(),
-(operand.as_inner().e2em() * self.e1epem() * self.e1epem())
+ -T::TWO * operand.as_inner().e2ep() * self.e12em() * self.w()
+ T::TWO * operand.as_inner().e1em() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().epem() * self.e12em() * self.e1epem()
+ T::TWO * operand.as_inner().m() * self.e2epem() * self.w()
+ operand.as_inner().e2em() * self.e12em() * self.e12em()
+ operand.as_inner().e2em() * self.e2epem() * self.e2epem()
+ operand.as_inner().e2em() * self.w() * self.w(),
-(operand.as_inner().epem() * self.e12em() * self.e12em())
+ -T::TWO * operand.as_inner().e1em() * self.e12em() * self.e2epem()
+ -T::TWO * operand.as_inner().e2ep() * self.e1epem() * self.w()
+ T::TWO * operand.as_inner().e1ep() * self.e2epem() * self.w()
+ T::TWO * operand.as_inner().e2em() * self.e12em() * self.e1epem()
+ operand.as_inner().epem() * self.e1epem() * self.e1epem()
+ operand.as_inner().epem() * self.e2epem() * self.e2epem()
+ operand.as_inner().epem() * self.w() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<PointPair<T>>> for Unit<Circle<T>> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.as_inner().m() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.as_inner().m() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1epem()
* self.as_inner().w()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2epem()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ operand.as_inner().m() * self.as_inner().e12em() * self.as_inner().e12em(),
-(operand.as_inner().e1ep() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().e1ep()
* self.as_inner().e2epem()
* self.as_inner().e2epem())
+ -(operand.as_inner().e1ep() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2epem()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e12em()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().m()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ operand.as_inner().e1ep() * self.as_inner().e1epem() * self.as_inner().e1epem(),
-(operand.as_inner().e2ep() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().e2ep()
* self.as_inner().e1epem()
* self.as_inner().e1epem())
+ -(operand.as_inner().e2ep() * self.as_inner().w() * self.as_inner().w())
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e12em()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1epem()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().m()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ operand.as_inner().e2ep() * self.as_inner().e2epem() * self.as_inner().e2epem(),
-(operand.as_inner().e1em() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e12em()
* self.as_inner().w()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1epem() * self.as_inner().w()
+ operand.as_inner().e1em() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().e1em() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().e1em() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().e2em() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e12em()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e2epem() * self.as_inner().w()
+ operand.as_inner().e2em() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().e2em() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.as_inner().e2em() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().epem() * self.as_inner().e12em() * self.as_inner().e12em())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1epem()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2epem()
* self.as_inner().w()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ operand.as_inner().epem() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().epem() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.as_inner().epem() * self.as_inner().w() * self.as_inner().w(),
)
}
}
#[doc = "Antisandwich product: [`Circle`] x [`Pseudoscalar`] x antirev([`Circle`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Pseudoscalar<T>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(self.e12em() * operand.ps() * self.e12em())
- self.e1epem() * operand.ps() * self.e1epem()
- self.e2epem() * operand.ps() * self.e2epem()
+ self.w() * operand.ps() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Pseudoscalar<T>> for Unit<Circle<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.ps() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.ps() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.ps() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ operand.ps() * self.as_inner().w() * self.as_inner().w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Pseudoscalar<T>>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.e12em() * self.e12em())
+ -(operand.as_inner().ps() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().ps() * self.e2epem() * self.e2epem())
+ operand.as_inner().ps() * self.w() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Pseudoscalar<T>>> for Unit<Circle<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().ps() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.as_inner().ps() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ operand.as_inner().ps() * self.as_inner().w() * self.as_inner().w(),
)
}
}
#[doc = "Antisandwich product: [`Circle`] x [`RoundPoint`] x antirev([`Circle`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<RoundPoint<T>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
self.e12em() * operand.ep() * self.e2epem()
- self.e12em() * operand.x() * self.e12em()
- self.e1epem() * operand.x() * self.e1epem()
- self.e1epem() * operand.y() * self.e2epem()
- self.e2epem() * operand.em() * self.w()
+ self.e2epem() * operand.ep() * self.e12em()
+ self.e2epem() * operand.x() * self.e2epem()
- self.e2epem() * operand.y() * self.e1epem()
- self.w() * operand.em() * self.e2epem()
+ self.w() * operand.x() * self.w(),
-(self.e12em() * operand.ep() * self.e1epem())
- self.e12em() * operand.y() * self.e12em()
+ self.e1epem() * operand.em() * self.w()
- self.e1epem() * operand.ep() * self.e12em()
- self.e1epem() * operand.x() * self.e2epem()
+ self.e1epem() * operand.y() * self.e1epem()
- self.e2epem() * operand.x() * self.e1epem()
- self.e2epem() * operand.y() * self.e2epem()
+ self.w() * operand.em() * self.e1epem()
+ self.w() * operand.y() * self.w(),
-(self.e12em() * operand.em() * self.w())
+ self.e12em() * operand.ep() * self.e12em()
+ self.e12em() * operand.x() * self.e2epem()
- self.e12em() * operand.y() * self.e1epem()
- self.e1epem() * operand.ep() * self.e1epem()
- self.e1epem() * operand.y() * self.e12em()
- self.e2epem() * operand.ep() * self.e2epem()
+ self.e2epem() * operand.x() * self.e12em()
- self.w() * operand.em() * self.e12em()
+ self.w() * operand.ep() * self.w(),
-(self.e12em() * operand.em() * self.e12em()) + self.e12em() * operand.ep() * self.w()
- self.e1epem() * operand.em() * self.e1epem()
- self.e1epem() * operand.y() * self.w()
- self.e2epem() * operand.em() * self.e2epem()
+ self.e2epem() * operand.x() * self.w()
- self.w() * operand.em() * self.w()
+ self.w() * operand.ep() * self.e12em()
+ self.w() * operand.x() * self.e2epem()
- self.w() * operand.y() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<RoundPoint<T>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.x() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.x() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -T::TWO * operand.em() * self.as_inner().e2epem() * self.as_inner().w()
+ -T::TWO * operand.y() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.ep() * self.as_inner().e12em() * self.as_inner().e2epem()
+ operand.x() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.x() * self.as_inner().w() * self.as_inner().w(),
-(operand.y() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.y() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO * operand.ep() * self.as_inner().e12em() * self.as_inner().e1epem()
+ -T::TWO * operand.x() * self.as_inner().e1epem() * self.as_inner().e2epem()
+ T::TWO * operand.em() * self.as_inner().e1epem() * self.as_inner().w()
+ operand.y() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.y() * self.as_inner().w() * self.as_inner().w(),
-(operand.ep() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.ep() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO * operand.em() * self.as_inner().e12em() * self.as_inner().w()
+ -T::TWO * operand.y() * self.as_inner().e12em() * self.as_inner().e1epem()
+ T::TWO * operand.x() * self.as_inner().e12em() * self.as_inner().e2epem()
+ operand.ep() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.ep() * self.as_inner().w() * self.as_inner().w(),
-(operand.em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.em() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.em() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.y() * self.as_inner().e1epem() * self.as_inner().w()
+ T::TWO * operand.ep() * self.as_inner().e12em() * self.as_inner().w()
+ T::TWO * operand.x() * self.as_inner().e2epem() * self.as_inner().w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<RoundPoint<T>>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.e12em() * self.e12em())
+ -(operand.as_inner().x() * self.e1epem() * self.e1epem())
+ -T::TWO * operand.as_inner().em() * self.e2epem() * self.w()
+ -T::TWO * operand.as_inner().y() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().ep() * self.e12em() * self.e2epem()
+ operand.as_inner().x() * self.e2epem() * self.e2epem()
+ operand.as_inner().x() * self.w() * self.w(),
-(operand.as_inner().y() * self.e12em() * self.e12em())
+ -(operand.as_inner().y() * self.e2epem() * self.e2epem())
+ -T::TWO * operand.as_inner().ep() * self.e12em() * self.e1epem()
+ -T::TWO * operand.as_inner().x() * self.e1epem() * self.e2epem()
+ T::TWO * operand.as_inner().em() * self.e1epem() * self.w()
+ operand.as_inner().y() * self.e1epem() * self.e1epem()
+ operand.as_inner().y() * self.w() * self.w(),
-(operand.as_inner().ep() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().ep() * self.e2epem() * self.e2epem())
+ -T::TWO * operand.as_inner().em() * self.e12em() * self.w()
+ -T::TWO * operand.as_inner().y() * self.e12em() * self.e1epem()
+ T::TWO * operand.as_inner().x() * self.e12em() * self.e2epem()
+ operand.as_inner().ep() * self.e12em() * self.e12em()
+ operand.as_inner().ep() * self.w() * self.w(),
-(operand.as_inner().em() * self.e12em() * self.e12em())
+ -(operand.as_inner().em() * self.e1epem() * self.e1epem())
+ -(operand.as_inner().em() * self.e2epem() * self.e2epem())
+ -(operand.as_inner().em() * self.w() * self.w())
+ -T::TWO * operand.as_inner().y() * self.e1epem() * self.w()
+ T::TWO * operand.as_inner().ep() * self.e12em() * self.w()
+ T::TWO * operand.as_inner().x() * self.e2epem() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<RoundPoint<T>>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().x() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -T::TWO
* operand.as_inner().em()
* self.as_inner().e2epem()
* self.as_inner().w()
+ -T::TWO
* operand.as_inner().y()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO
* operand.as_inner().ep()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ operand.as_inner().x() * self.as_inner().e2epem() * self.as_inner().e2epem()
+ operand.as_inner().x() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().y() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().y() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO
* operand.as_inner().ep()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ -T::TWO
* operand.as_inner().x()
* self.as_inner().e1epem()
* self.as_inner().e2epem()
+ T::TWO * operand.as_inner().em() * self.as_inner().e1epem() * self.as_inner().w()
+ operand.as_inner().y() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().y() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().ep() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.as_inner().ep() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -T::TWO * operand.as_inner().em() * self.as_inner().e12em() * self.as_inner().w()
+ -T::TWO
* operand.as_inner().y()
* self.as_inner().e12em()
* self.as_inner().e1epem()
+ T::TWO
* operand.as_inner().x()
* self.as_inner().e12em()
* self.as_inner().e2epem()
+ operand.as_inner().ep() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().ep() * self.as_inner().w() * self.as_inner().w(),
-(operand.as_inner().em() * self.as_inner().e12em() * self.as_inner().e12em())
+ -(operand.as_inner().em() * self.as_inner().e1epem() * self.as_inner().e1epem())
+ -(operand.as_inner().em() * self.as_inner().e2epem() * self.as_inner().e2epem())
+ -(operand.as_inner().em() * self.as_inner().w() * self.as_inner().w())
+ -T::TWO * operand.as_inner().y() * self.as_inner().e1epem() * self.as_inner().w()
+ T::TWO * operand.as_inner().ep() * self.as_inner().e12em() * self.as_inner().w()
+ T::TWO * operand.as_inner().x() * self.as_inner().e2epem() * self.as_inner().w(),
)
}
}
#[doc = "Antisandwich product: [`Circle`] x [`Scalar`] x antirev([`Circle`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Scalar<T>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
self.e12em() * operand.s() * self.e12em()
+ self.e1epem() * operand.s() * self.e1epem()
+ self.e2epem() * operand.s() * self.e2epem()
- self.w() * operand.s() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Scalar<T>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.s() * self.as_inner().w() * self.as_inner().w())
+ operand.s() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.s() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.s() * self.as_inner().e2epem() * self.as_inner().e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Scalar<T>>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.w() * self.w())
+ operand.as_inner().s() * self.e12em() * self.e12em()
+ operand.as_inner().s() * self.e1epem() * self.e1epem()
+ operand.as_inner().s() * self.e2epem() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Scalar<T>>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.as_inner().w() * self.as_inner().w())
+ operand.as_inner().s() * self.as_inner().e12em() * self.as_inner().e12em()
+ operand.as_inner().s() * self.as_inner().e1epem() * self.as_inner().e1epem()
+ operand.as_inner().s() * self.as_inner().e2epem() * self.as_inner().e2epem(),
)
}
}
#[doc = "Antisandwich product: [`FlatPoint`] x [`Circle`] x antirev([`FlatPoint`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Circle<T>> for FlatPoint<T> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
self.e1em() * operand.w() * self.e1em()
+ self.e2em() * operand.w() * self.e2em()
+ self.epem() * operand.w() * self.epem(),
-(self.e1em() * operand.e12em() * self.e1em())
+ self.e1em() * operand.e2epem() * self.epem()
- self.e2em() * operand.e12em() * self.e2em()
- self.e2em() * operand.e1epem() * self.epem()
+ self.epem() * operand.e12em() * self.epem()
- self.epem() * operand.e1epem() * self.e2em()
+ self.epem() * operand.e2epem() * self.e1em(),
-(self.e1em() * operand.e1epem() * self.e1em())
- self.e1em() * operand.e2epem() * self.e2em()
- self.e2em() * operand.e12em() * self.epem()
+ self.e2em() * operand.e1epem() * self.e2em()
- self.e2em() * operand.e2epem() * self.e1em()
- self.epem() * operand.e12em() * self.e2em()
- self.epem() * operand.e1epem() * self.epem(),
self.e1em() * operand.e12em() * self.epem()
- self.e1em() * operand.e1epem() * self.e2em()
+ self.e1em() * operand.e2epem() * self.e1em()
- self.e2em() * operand.e1epem() * self.e1em()
- self.e2em() * operand.e2epem() * self.e2em()
+ self.epem() * operand.e12em() * self.e1em()
- self.epem() * operand.e2epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Circle<T>> for Unit<FlatPoint<T>> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
operand.w() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.w() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.w() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e12em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e12em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO * operand.e1epem() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.e2epem() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.e12em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e1epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e12em() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.e2epem() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.e1epem() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.e2epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1epem() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e12em() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.e2epem() * self.as_inner().e1em() * self.as_inner().e1em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Circle<T>>> for FlatPoint<T> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
operand.as_inner().w() * self.e1em() * self.e1em()
+ operand.as_inner().w() * self.e2em() * self.e2em()
+ operand.as_inner().w() * self.epem() * self.epem(),
-(operand.as_inner().e12em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e12em() * self.e2em() * self.e2em())
+ -T::TWO * operand.as_inner().e1epem() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().e2epem() * self.e1em() * self.epem()
+ operand.as_inner().e12em() * self.epem() * self.epem(),
-(operand.as_inner().e1epem() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1epem() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e12em() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().e2epem() * self.e1em() * self.e2em()
+ operand.as_inner().e1epem() * self.e2em() * self.e2em(),
-(operand.as_inner().e2epem() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2epem() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1epem() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e12em() * self.e1em() * self.epem()
+ operand.as_inner().e2epem() * self.e1em() * self.e1em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Circle<T>>> for Unit<FlatPoint<T>> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
operand.as_inner().w() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().w() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().w() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e12em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e12em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ operand.as_inner().e12em() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e1epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ operand.as_inner().e1epem() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().e2epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2epem() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ operand.as_inner().e2epem() * self.as_inner().e1em() * self.as_inner().e1em(),
)
}
}
#[doc = "Antisandwich product: [`FlatPoint`] x [`FlatPoint`] x antirev([`FlatPoint`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<FlatPoint<T>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
self.e1em() * operand.e1em() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.epem() * self.epem()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1em()
- self.epem() * operand.e1em() * self.epem()
+ self.epem() * operand.epem() * self.e1em(),
self.e1em() * operand.e1em() * self.e2em() - self.e1em() * operand.e2em() * self.e1em()
+ self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.epem() * self.epem()
- self.epem() * operand.e2em() * self.epem()
+ self.epem() * operand.epem() * self.e2em(),
self.e1em() * operand.e1em() * self.epem() - self.e1em() * operand.epem() * self.e1em()
+ self.e2em() * operand.e2em() * self.epem()
- self.e2em() * operand.epem() * self.e2em()
+ self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<FlatPoint<T>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e1em() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em(),
-(operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e2em() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.epem() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<FlatPoint<T>>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e1em() * self.epem() * self.epem())
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ operand.as_inner().e1em() * self.e1em() * self.e1em(),
-(operand.as_inner().e2em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e2em() * self.epem() * self.epem())
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ operand.as_inner().e2em() * self.e2em() * self.e2em(),
-(operand.as_inner().epem() * self.e1em() * self.e1em())
+ -(operand.as_inner().epem() * self.e2em() * self.e2em())
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ operand.as_inner().epem() * self.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<FlatPoint<T>>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em(),
-(operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Antisandwich product: [`FlatPoint`] x [`Line`] x antirev([`FlatPoint`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Line<T>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
self.e1em() * operand.d() * self.epem()
- self.e1em() * operand.nx() * self.e1em()
- self.e2em() * operand.nx() * self.e2em()
- self.e2em() * operand.ny() * self.epem()
+ self.epem() * operand.d() * self.e1em()
+ self.epem() * operand.nx() * self.epem()
- self.epem() * operand.ny() * self.e2em(),
-(self.e1em() * operand.d() * self.e2em())
- self.e1em() * operand.ny() * self.e1em()
- self.e2em() * operand.d() * self.e1em()
- self.e2em() * operand.nx() * self.epem()
+ self.e2em() * operand.ny() * self.e2em()
- self.epem() * operand.nx() * self.e2em()
- self.epem() * operand.ny() * self.epem(),
self.e1em() * operand.d() * self.e1em() + self.e1em() * operand.nx() * self.epem()
- self.e1em() * operand.ny() * self.e2em()
- self.e2em() * operand.d() * self.e2em()
- self.e2em() * operand.ny() * self.e1em()
- self.epem() * operand.d() * self.epem()
+ self.epem() * operand.nx() * self.e1em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Line<T>> for Unit<FlatPoint<T>> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(operand.nx() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.nx() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO * operand.ny() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.d() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.nx() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.ny() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ny() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.d() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.nx() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.ny() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.d() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.d() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.ny() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.nx() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.d() * self.as_inner().e1em() * self.as_inner().e1em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Line<T>>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.e1em() * self.e1em())
+ -(operand.as_inner().nx() * self.e2em() * self.e2em())
+ -T::TWO * operand.as_inner().ny() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().d() * self.e1em() * self.epem()
+ operand.as_inner().nx() * self.epem() * self.epem(),
-(operand.as_inner().ny() * self.e1em() * self.e1em())
+ -(operand.as_inner().ny() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().d() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().nx() * self.e2em() * self.epem()
+ operand.as_inner().ny() * self.e2em() * self.e2em(),
-(operand.as_inner().d() * self.e2em() * self.e2em())
+ -(operand.as_inner().d() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().ny() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().nx() * self.e1em() * self.epem()
+ operand.as_inner().d() * self.e1em() * self.e1em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Line<T>>> for Unit<FlatPoint<T>> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().nx() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO
* operand.as_inner().ny()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().d() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.as_inner().nx() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().ny() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ny() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().d()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().nx()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().ny() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().d() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().d() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().ny()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().nx()
* self.as_inner().e1em()
* self.as_inner().epem()
+ operand.as_inner().d() * self.as_inner().e1em() * self.as_inner().e1em(),
)
}
}
#[doc = "Antisandwich product: [`FlatPoint`] x [`Motor`] x antirev([`FlatPoint`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Motor<T>> for FlatPoint<T> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(self.e1em() * operand.e1ep() * self.epem()) - self.e1em() * operand.m() * self.e2em()
+ self.e1em() * operand.s() * self.e1em()
- self.e2em() * operand.e2ep() * self.epem()
+ self.e2em() * operand.m() * self.e1em()
+ self.e2em() * operand.s() * self.e2em()
+ self.epem() * operand.e1ep() * self.e1em()
+ self.epem() * operand.e2ep() * self.e2em()
+ self.epem() * operand.s() * self.epem(),
self.e1em() * operand.e2ep() * self.epem()
- self.e1em() * operand.m() * self.e1em()
- self.e1em() * operand.s() * self.e2em()
- self.e2em() * operand.e1ep() * self.epem()
- self.e2em() * operand.m() * self.e2em()
+ self.e2em() * operand.s() * self.e1em()
- self.epem() * operand.e1ep() * self.e2em()
+ self.epem() * operand.e2ep() * self.e1em()
+ self.epem() * operand.m() * self.epem(),
-(self.e1em() * operand.e1ep() * self.e1em())
- self.e1em() * operand.e2ep() * self.e2em()
- self.e1em() * operand.s() * self.epem()
+ self.e2em() * operand.e1ep() * self.e2em()
- self.e2em() * operand.e2ep() * self.e1em()
- self.e2em() * operand.m() * self.epem()
- self.epem() * operand.e1ep() * self.epem()
- self.epem() * operand.m() * self.e2em()
+ self.epem() * operand.s() * self.e1em(),
-(self.e1em() * operand.e1ep() * self.e2em())
+ self.e1em() * operand.e2ep() * self.e1em()
+ self.e1em() * operand.m() * self.epem()
- self.e2em() * operand.e1ep() * self.e1em()
- self.e2em() * operand.e2ep() * self.e2em()
- self.e2em() * operand.s() * self.epem()
- self.epem() * operand.e2ep() * self.epem()
+ self.epem() * operand.m() * self.e1em()
+ self.epem() * operand.s() * self.e2em(),
self.e1em() * operand.e1em() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.epem() * self.epem()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1em()
+ self.e2em() * operand.ps() * self.epem()
- self.epem() * operand.e1em() * self.epem()
+ self.epem() * operand.epem() * self.e1em()
- self.epem() * operand.ps() * self.e2em(),
self.e1em() * operand.e1em() * self.e2em()
- self.e1em() * operand.e2em() * self.e1em()
- self.e1em() * operand.ps() * self.epem()
+ self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.epem() * self.epem()
- self.epem() * operand.e2em() * self.epem()
+ self.epem() * operand.epem() * self.e2em()
+ self.epem() * operand.ps() * self.e1em(),
self.e1em() * operand.e1em() * self.epem() - self.e1em() * operand.epem() * self.e1em()
+ self.e1em() * operand.ps() * self.e2em()
+ self.e2em() * operand.e2em() * self.epem()
- self.e2em() * operand.epem() * self.e2em()
- self.e2em() * operand.ps() * self.e1em()
+ self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.epem() * self.epem(),
-(self.e1em() * operand.e2em() * self.epem())
+ self.e1em() * operand.epem() * self.e2em()
+ self.e1em() * operand.ps() * self.e1em()
+ self.e2em() * operand.e1em() * self.epem()
- self.e2em() * operand.epem() * self.e1em()
+ self.e2em() * operand.ps() * self.e2em()
- self.epem() * operand.e1em() * self.e2em()
+ self.epem() * operand.e2em() * self.e1em()
+ self.epem() * operand.ps() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Motor<T>> for Unit<FlatPoint<T>> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
operand.s() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.s() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.s() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.m() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.m() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.m() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1ep() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2ep() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1em(),
-(operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e1em() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em(),
-(operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e2em() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.epem() * self.as_inner().epem() * self.as_inner().epem(),
operand.ps() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.ps() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.ps() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Motor<T>>> for FlatPoint<T> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
operand.as_inner().s() * self.e1em() * self.e1em()
+ operand.as_inner().s() * self.e2em() * self.e2em()
+ operand.as_inner().s() * self.epem() * self.epem(),
-(operand.as_inner().m() * self.e1em() * self.e1em())
+ -(operand.as_inner().m() * self.e2em() * self.e2em())
+ -T::TWO * operand.as_inner().e1ep() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.epem()
+ operand.as_inner().m() * self.epem() * self.epem(),
-(operand.as_inner().e1ep() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1ep() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.epem()
+ operand.as_inner().e1ep() * self.e2em() * self.e2em(),
-(operand.as_inner().e2ep() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2ep() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.epem()
+ operand.as_inner().e2ep() * self.e1em() * self.e1em(),
-(operand.as_inner().e1em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e1em() * self.epem() * self.epem())
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ operand.as_inner().e1em() * self.e1em() * self.e1em(),
-(operand.as_inner().e2em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e2em() * self.epem() * self.epem())
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ operand.as_inner().e2em() * self.e2em() * self.e2em(),
-(operand.as_inner().epem() * self.e1em() * self.e1em())
+ -(operand.as_inner().epem() * self.e2em() * self.e2em())
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ operand.as_inner().epem() * self.epem() * self.epem(),
operand.as_inner().ps() * self.e1em() * self.e1em()
+ operand.as_inner().ps() * self.e2em() * self.e2em()
+ operand.as_inner().ps() * self.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Motor<T>>> for Unit<FlatPoint<T>> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
operand.as_inner().s() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().s() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().s() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ operand.as_inner().m() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e1ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1ep() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().e1ep() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().e2ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2ep() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.as_inner().e2ep() * self.as_inner().e1em() * self.as_inner().e1em(),
-(operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em(),
-(operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem(),
operand.as_inner().ps() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().ps() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().ps() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Antisandwich product: [`FlatPoint`] x [`PointPair`] x antirev([`FlatPoint`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<PointPair<T>> for FlatPoint<T> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
self.e1em() * operand.e2ep() * self.epem()
- self.e1em() * operand.m() * self.e1em()
- self.e2em() * operand.e1ep() * self.epem()
- self.e2em() * operand.m() * self.e2em()
- self.epem() * operand.e1ep() * self.e2em()
+ self.epem() * operand.e2ep() * self.e1em()
+ self.epem() * operand.m() * self.epem(),
-(self.e1em() * operand.e1ep() * self.e1em())
- self.e1em() * operand.e2ep() * self.e2em()
+ self.e2em() * operand.e1ep() * self.e2em()
- self.e2em() * operand.e2ep() * self.e1em()
- self.e2em() * operand.m() * self.epem()
- self.epem() * operand.e1ep() * self.epem()
- self.epem() * operand.m() * self.e2em(),
-(self.e1em() * operand.e1ep() * self.e2em())
+ self.e1em() * operand.e2ep() * self.e1em()
+ self.e1em() * operand.m() * self.epem()
- self.e2em() * operand.e1ep() * self.e1em()
- self.e2em() * operand.e2ep() * self.e2em()
- self.epem() * operand.e2ep() * self.epem()
+ self.epem() * operand.m() * self.e1em(),
self.e1em() * operand.e1em() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.epem() * self.epem()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1em()
- self.epem() * operand.e1em() * self.epem()
+ self.epem() * operand.epem() * self.e1em(),
self.e1em() * operand.e1em() * self.e2em() - self.e1em() * operand.e2em() * self.e1em()
+ self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.epem() * self.epem()
- self.epem() * operand.e2em() * self.epem()
+ self.epem() * operand.epem() * self.e2em(),
self.e1em() * operand.e1em() * self.epem() - self.e1em() * operand.epem() * self.e1em()
+ self.e2em() * operand.e2em() * self.epem()
- self.e2em() * operand.epem() * self.e2em()
+ self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<PointPair<T>> for Unit<FlatPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.m() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.m() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.m() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1ep() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2ep() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1em(),
-(operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e1em() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em(),
-(operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e2em() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.epem() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<PointPair<T>>> for FlatPoint<T> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.e1em() * self.e1em())
+ -(operand.as_inner().m() * self.e2em() * self.e2em())
+ -T::TWO * operand.as_inner().e1ep() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.epem()
+ operand.as_inner().m() * self.epem() * self.epem(),
-(operand.as_inner().e1ep() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1ep() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.epem()
+ operand.as_inner().e1ep() * self.e2em() * self.e2em(),
-(operand.as_inner().e2ep() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2ep() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.epem()
+ operand.as_inner().e2ep() * self.e1em() * self.e1em(),
-(operand.as_inner().e1em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e1em() * self.epem() * self.epem())
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ operand.as_inner().e1em() * self.e1em() * self.e1em(),
-(operand.as_inner().e2em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e2em() * self.epem() * self.epem())
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ operand.as_inner().e2em() * self.e2em() * self.e2em(),
-(operand.as_inner().epem() * self.e1em() * self.e1em())
+ -(operand.as_inner().epem() * self.e2em() * self.e2em())
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ operand.as_inner().epem() * self.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<PointPair<T>>> for Unit<FlatPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().e2em())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ operand.as_inner().m() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e1ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1ep() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().e1ep() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().e2ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2ep() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.as_inner().e2ep() * self.as_inner().e1em() * self.as_inner().e1em(),
-(operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em(),
-(operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Antisandwich product: [`FlatPoint`] x [`Pseudoscalar`] x antirev([`FlatPoint`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Pseudoscalar<T>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
self.e1em() * operand.ps() * self.e1em()
+ self.e2em() * operand.ps() * self.e2em()
+ self.epem() * operand.ps() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Pseudoscalar<T>> for Unit<FlatPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
operand.ps() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.ps() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.ps() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Pseudoscalar<T>>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
operand.as_inner().ps() * self.e1em() * self.e1em()
+ operand.as_inner().ps() * self.e2em() * self.e2em()
+ operand.as_inner().ps() * self.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Pseudoscalar<T>>> for Unit<FlatPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
operand.as_inner().ps() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().ps() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().ps() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Antisandwich product: [`FlatPoint`] x [`RoundPoint`] x antirev([`FlatPoint`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<RoundPoint<T>> for FlatPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
self.e1em() * operand.ep() * self.epem()
+ self.e1em() * operand.x() * self.e1em()
+ self.e1em() * operand.y() * self.e2em()
- self.e2em() * operand.x() * self.e2em()
+ self.e2em() * operand.y() * self.e1em()
+ self.epem() * operand.ep() * self.e1em()
- self.epem() * operand.x() * self.epem(),
self.e1em() * operand.x() * self.e2em() - self.e1em() * operand.y() * self.e1em()
+ self.e2em() * operand.ep() * self.epem()
+ self.e2em() * operand.x() * self.e1em()
+ self.e2em() * operand.y() * self.e2em()
+ self.epem() * operand.ep() * self.e2em()
- self.epem() * operand.y() * self.epem(),
-(self.e1em() * operand.ep() * self.e1em()) + self.e1em() * operand.x() * self.epem()
- self.e2em() * operand.ep() * self.e2em()
+ self.e2em() * operand.y() * self.epem()
+ self.epem() * operand.ep() * self.epem()
+ self.epem() * operand.x() * self.e1em()
+ self.epem() * operand.y() * self.e2em(),
self.e1em() * operand.em() * self.e1em()
+ self.e2em() * operand.em() * self.e2em()
+ self.epem() * operand.em() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<RoundPoint<T>> for Unit<FlatPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.x() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.x() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO * operand.ep() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.y() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.x() * self.as_inner().e1em() * self.as_inner().e1em(),
-(operand.y() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.y() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO * operand.ep() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.x() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.y() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ T::TWO * operand.x() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.y() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.ep() * self.as_inner().epem() * self.as_inner().epem(),
operand.em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.em() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<RoundPoint<T>>> for FlatPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.e2em() * self.e2em())
+ -(operand.as_inner().x() * self.epem() * self.epem())
+ T::TWO * operand.as_inner().ep() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().y() * self.e1em() * self.e2em()
+ operand.as_inner().x() * self.e1em() * self.e1em(),
-(operand.as_inner().y() * self.e1em() * self.e1em())
+ -(operand.as_inner().y() * self.epem() * self.epem())
+ T::TWO * operand.as_inner().ep() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().x() * self.e1em() * self.e2em()
+ operand.as_inner().y() * self.e2em() * self.e2em(),
-(operand.as_inner().ep() * self.e1em() * self.e1em())
+ -(operand.as_inner().ep() * self.e2em() * self.e2em())
+ T::TWO * operand.as_inner().x() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().y() * self.e2em() * self.epem()
+ operand.as_inner().ep() * self.epem() * self.epem(),
operand.as_inner().em() * self.e1em() * self.e1em()
+ operand.as_inner().em() * self.e2em() * self.e2em()
+ operand.as_inner().em() * self.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<RoundPoint<T>>> for Unit<FlatPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().x() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO
* operand.as_inner().ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().e1em(),
-(operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().y() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO
* operand.as_inner().ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.as_inner().y() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ T::TWO * operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.as_inner().y() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.as_inner().ep() * self.as_inner().epem() * self.as_inner().epem(),
operand.as_inner().em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().em() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Antisandwich product: [`FlatPoint`] x [`Scalar`] x antirev([`FlatPoint`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Scalar<T>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
self.e1em() * operand.s() * self.e1em()
+ self.e2em() * operand.s() * self.e2em()
+ self.epem() * operand.s() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Scalar<T>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
operand.s() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.s() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.s() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Scalar<T>>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
operand.as_inner().s() * self.e1em() * self.e1em()
+ operand.as_inner().s() * self.e2em() * self.e2em()
+ operand.as_inner().s() * self.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Scalar<T>>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
operand.as_inner().s() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().s() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().s() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Antisandwich product: [`Line`] x [`Circle`] x antirev([`Line`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Circle<T>> for Line<T> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
self.d() * operand.w() * self.d()
+ self.nx() * operand.w() * self.nx()
+ self.ny() * operand.w() * self.ny(),
self.d() * operand.e12em() * self.d()
- self.d() * operand.e2epem() * self.nx()
- self.nx() * operand.e12em() * self.nx()
- self.nx() * operand.e1epem() * self.ny()
- self.nx() * operand.e2epem() * self.d()
+ self.ny() * operand.e12em() * self.ny()
- self.ny() * operand.e1epem() * self.nx(),
self.d() * operand.e1epem() * self.d()
- self.d() * operand.e2epem() * self.ny()
- self.nx() * operand.e12em() * self.ny()
+ self.nx() * operand.e1epem() * self.nx()
- self.ny() * operand.e12em() * self.nx()
- self.ny() * operand.e1epem() * self.ny()
- self.ny() * operand.e2epem() * self.d(),
-(self.d() * operand.e12em() * self.nx())
- self.d() * operand.e1epem() * self.ny()
- self.d() * operand.e2epem() * self.d()
- self.nx() * operand.e12em() * self.d()
+ self.nx() * operand.e2epem() * self.nx()
- self.ny() * operand.e1epem() * self.d()
+ self.ny() * operand.e2epem() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Circle<T>> for Unit<Line<T>> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
operand.w() * self.as_inner().d() * self.as_inner().d()
+ operand.w() * self.as_inner().nx() * self.as_inner().nx()
+ operand.w() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.e12em() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.e1epem() * self.as_inner().nx() * self.as_inner().ny()
+ -T::TWO * operand.e2epem() * self.as_inner().d() * self.as_inner().nx()
+ operand.e12em() * self.as_inner().d() * self.as_inner().d()
+ operand.e12em() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.e1epem() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.e12em() * self.as_inner().nx() * self.as_inner().ny()
+ -T::TWO * operand.e2epem() * self.as_inner().d() * self.as_inner().ny()
+ operand.e1epem() * self.as_inner().d() * self.as_inner().d()
+ operand.e1epem() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.e2epem() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.e12em() * self.as_inner().d() * self.as_inner().nx()
+ -T::TWO * operand.e1epem() * self.as_inner().d() * self.as_inner().ny()
+ operand.e2epem() * self.as_inner().nx() * self.as_inner().nx()
+ operand.e2epem() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Circle<T>>> for Line<T> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
operand.as_inner().w() * self.d() * self.d()
+ operand.as_inner().w() * self.nx() * self.nx()
+ operand.as_inner().w() * self.ny() * self.ny(),
-(operand.as_inner().e12em() * self.nx() * self.nx())
+ -T::TWO * operand.as_inner().e1epem() * self.nx() * self.ny()
+ -T::TWO * operand.as_inner().e2epem() * self.d() * self.nx()
+ operand.as_inner().e12em() * self.d() * self.d()
+ operand.as_inner().e12em() * self.ny() * self.ny(),
-(operand.as_inner().e1epem() * self.ny() * self.ny())
+ -T::TWO * operand.as_inner().e12em() * self.nx() * self.ny()
+ -T::TWO * operand.as_inner().e2epem() * self.d() * self.ny()
+ operand.as_inner().e1epem() * self.d() * self.d()
+ operand.as_inner().e1epem() * self.nx() * self.nx(),
-(operand.as_inner().e2epem() * self.d() * self.d())
+ -T::TWO * operand.as_inner().e12em() * self.d() * self.nx()
+ -T::TWO * operand.as_inner().e1epem() * self.d() * self.ny()
+ operand.as_inner().e2epem() * self.nx() * self.nx()
+ operand.as_inner().e2epem() * self.ny() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Circle<T>>> for Unit<Line<T>> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
operand.as_inner().w() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().w() * self.as_inner().nx() * self.as_inner().nx()
+ operand.as_inner().w() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().e12em() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().nx()
* self.as_inner().ny()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().d()
* self.as_inner().nx()
+ operand.as_inner().e12em() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().e12em() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().e1epem() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().nx()
* self.as_inner().ny()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().d()
* self.as_inner().ny()
+ operand.as_inner().e1epem() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().e1epem() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.as_inner().e2epem() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.as_inner().e12em() * self.as_inner().d() * self.as_inner().nx()
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().d()
* self.as_inner().ny()
+ operand.as_inner().e2epem() * self.as_inner().nx() * self.as_inner().nx()
+ operand.as_inner().e2epem() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[doc = "Antisandwich product: [`Line`] x [`FlatPoint`] x antirev([`Line`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<FlatPoint<T>> for Line<T> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(self.d() * operand.e1em() * self.d()) + self.d() * operand.e2em() * self.ny()
- self.d() * operand.epem() * self.nx()
+ self.nx() * operand.e1em() * self.nx()
- self.nx() * operand.epem() * self.d()
+ self.ny() * operand.e1em() * self.ny()
+ self.ny() * operand.e2em() * self.d(),
self.d() * operand.e1em() * self.ny()
+ self.d() * operand.e2em() * self.d()
+ self.nx() * operand.e2em() * self.nx()
+ self.nx() * operand.epem() * self.ny()
+ self.ny() * operand.e1em() * self.d()
- self.ny() * operand.e2em() * self.ny()
+ self.ny() * operand.epem() * self.nx(),
-(self.d() * operand.e1em() * self.nx()) + self.d() * operand.epem() * self.d()
- self.nx() * operand.e1em() * self.d()
+ self.nx() * operand.e2em() * self.ny()
- self.nx() * operand.epem() * self.nx()
+ self.ny() * operand.e2em() * self.nx()
+ self.ny() * operand.epem() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<FlatPoint<T>> for Unit<Line<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.e1em() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.epem() * self.as_inner().d() * self.as_inner().nx()
+ T::TWO * operand.e2em() * self.as_inner().d() * self.as_inner().ny()
+ operand.e1em() * self.as_inner().nx() * self.as_inner().nx()
+ operand.e1em() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.e2em() * self.as_inner().ny() * self.as_inner().ny())
+ T::TWO * operand.e1em() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.epem() * self.as_inner().nx() * self.as_inner().ny()
+ operand.e2em() * self.as_inner().d() * self.as_inner().d()
+ operand.e2em() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.epem() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.e1em() * self.as_inner().d() * self.as_inner().nx()
+ T::TWO * operand.e2em() * self.as_inner().nx() * self.as_inner().ny()
+ operand.epem() * self.as_inner().d() * self.as_inner().d()
+ operand.epem() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<FlatPoint<T>>> for Line<T> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.d() * self.d())
+ -T::TWO * operand.as_inner().epem() * self.d() * self.nx()
+ T::TWO * operand.as_inner().e2em() * self.d() * self.ny()
+ operand.as_inner().e1em() * self.nx() * self.nx()
+ operand.as_inner().e1em() * self.ny() * self.ny(),
-(operand.as_inner().e2em() * self.ny() * self.ny())
+ T::TWO * operand.as_inner().e1em() * self.d() * self.ny()
+ T::TWO * operand.as_inner().epem() * self.nx() * self.ny()
+ operand.as_inner().e2em() * self.d() * self.d()
+ operand.as_inner().e2em() * self.nx() * self.nx(),
-(operand.as_inner().epem() * self.nx() * self.nx())
+ -T::TWO * operand.as_inner().e1em() * self.d() * self.nx()
+ T::TWO * operand.as_inner().e2em() * self.nx() * self.ny()
+ operand.as_inner().epem() * self.d() * self.d()
+ operand.as_inner().epem() * self.ny() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<FlatPoint<T>>> for Unit<Line<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.as_inner().epem() * self.as_inner().d() * self.as_inner().nx()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().d() * self.as_inner().ny()
+ operand.as_inner().e1em() * self.as_inner().nx() * self.as_inner().nx()
+ operand.as_inner().e1em() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().e2em() * self.as_inner().ny() * self.as_inner().ny())
+ T::TWO * operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.as_inner().epem() * self.as_inner().nx() * self.as_inner().ny()
+ operand.as_inner().e2em() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().e2em() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.as_inner().epem() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().nx()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().nx() * self.as_inner().ny()
+ operand.as_inner().epem() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().epem() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[doc = "Antisandwich product: [`Line`] x [`Line`] x antirev([`Line`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Line<T>> for Line<T> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(self.d() * operand.d() * self.nx()) + self.d() * operand.nx() * self.d()
- self.nx() * operand.d() * self.d()
- self.nx() * operand.nx() * self.nx()
- self.nx() * operand.ny() * self.ny()
+ self.ny() * operand.nx() * self.ny()
- self.ny() * operand.ny() * self.nx(),
-(self.d() * operand.d() * self.ny()) + self.d() * operand.ny() * self.d()
- self.nx() * operand.nx() * self.ny()
+ self.nx() * operand.ny() * self.nx()
- self.ny() * operand.d() * self.d()
- self.ny() * operand.nx() * self.nx()
- self.ny() * operand.ny() * self.ny(),
-(self.d() * operand.d() * self.d())
- self.d() * operand.nx() * self.nx()
- self.d() * operand.ny() * self.ny()
+ self.nx() * operand.d() * self.nx()
- self.nx() * operand.nx() * self.d()
+ self.ny() * operand.d() * self.ny()
- self.ny() * operand.ny() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Line<T>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(operand.nx() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.d() * self.as_inner().d() * self.as_inner().nx()
+ -T::TWO * operand.ny() * self.as_inner().nx() * self.as_inner().ny()
+ operand.nx() * self.as_inner().d() * self.as_inner().d()
+ operand.nx() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.ny() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.d() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.nx() * self.as_inner().nx() * self.as_inner().ny()
+ operand.ny() * self.as_inner().d() * self.as_inner().d()
+ operand.ny() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.d() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.nx() * self.as_inner().d() * self.as_inner().nx()
+ -T::TWO * operand.ny() * self.as_inner().d() * self.as_inner().ny()
+ operand.d() * self.as_inner().nx() * self.as_inner().nx()
+ operand.d() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Line<T>>> for Line<T> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.nx() * self.nx())
+ -T::TWO * operand.as_inner().d() * self.d() * self.nx()
+ -T::TWO * operand.as_inner().ny() * self.nx() * self.ny()
+ operand.as_inner().nx() * self.d() * self.d()
+ operand.as_inner().nx() * self.ny() * self.ny(),
-(operand.as_inner().ny() * self.ny() * self.ny())
+ -T::TWO * operand.as_inner().d() * self.d() * self.ny()
+ -T::TWO * operand.as_inner().nx() * self.nx() * self.ny()
+ operand.as_inner().ny() * self.d() * self.d()
+ operand.as_inner().ny() * self.nx() * self.nx(),
-(operand.as_inner().d() * self.d() * self.d())
+ -T::TWO * operand.as_inner().nx() * self.d() * self.nx()
+ -T::TWO * operand.as_inner().ny() * self.d() * self.ny()
+ operand.as_inner().d() * self.nx() * self.nx()
+ operand.as_inner().d() * self.ny() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Line<T>>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.as_inner().d() * self.as_inner().d() * self.as_inner().nx()
+ -T::TWO * operand.as_inner().ny() * self.as_inner().nx() * self.as_inner().ny()
+ operand.as_inner().nx() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().nx() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().ny() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.as_inner().d() * self.as_inner().d() * self.as_inner().ny()
+ -T::TWO * operand.as_inner().nx() * self.as_inner().nx() * self.as_inner().ny()
+ operand.as_inner().ny() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().ny() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.as_inner().d() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.as_inner().nx() * self.as_inner().d() * self.as_inner().nx()
+ -T::TWO * operand.as_inner().ny() * self.as_inner().d() * self.as_inner().ny()
+ operand.as_inner().d() * self.as_inner().nx() * self.as_inner().nx()
+ operand.as_inner().d() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[doc = "Antisandwich product: [`Line`] x [`Motor`] x antirev([`Line`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Motor<T>> for Line<T> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(self.d() * operand.e1ep() * self.nx())
+ self.d() * operand.m() * self.ny()
+ self.d() * operand.s() * self.d()
+ self.nx() * operand.e1ep() * self.d()
- self.nx() * operand.e2ep() * self.ny()
+ self.nx() * operand.s() * self.nx()
+ self.ny() * operand.e2ep() * self.nx()
- self.ny() * operand.m() * self.d()
+ self.ny() * operand.s() * self.ny(),
self.d() * operand.e2ep() * self.nx() - self.d() * operand.m() * self.d()
+ self.d() * operand.s() * self.ny()
+ self.nx() * operand.e1ep() * self.ny()
+ self.nx() * operand.e2ep() * self.d()
+ self.nx() * operand.m() * self.nx()
+ self.ny() * operand.e1ep() * self.nx()
- self.ny() * operand.m() * self.ny()
- self.ny() * operand.s() * self.d(),
-(self.d() * operand.e1ep() * self.d()) + self.d() * operand.e2ep() * self.ny()
- self.d() * operand.s() * self.nx()
- self.nx() * operand.e1ep() * self.nx()
+ self.nx() * operand.m() * self.ny()
+ self.nx() * operand.s() * self.d()
+ self.ny() * operand.e1ep() * self.ny()
+ self.ny() * operand.e2ep() * self.d()
+ self.ny() * operand.m() * self.nx(),
self.d() * operand.e1ep() * self.ny()
+ self.d() * operand.e2ep() * self.d()
+ self.d() * operand.m() * self.nx()
- self.nx() * operand.e2ep() * self.nx()
+ self.nx() * operand.m() * self.d()
- self.nx() * operand.s() * self.ny()
+ self.ny() * operand.e1ep() * self.d()
- self.ny() * operand.e2ep() * self.ny()
+ self.ny() * operand.s() * self.nx(),
-(self.d() * operand.e1em() * self.d()) + self.d() * operand.e2em() * self.ny()
- self.d() * operand.epem() * self.nx()
+ self.nx() * operand.e1em() * self.nx()
- self.nx() * operand.epem() * self.d()
- self.nx() * operand.ps() * self.ny()
+ self.ny() * operand.e1em() * self.ny()
+ self.ny() * operand.e2em() * self.d()
+ self.ny() * operand.ps() * self.nx(),
self.d() * operand.e1em() * self.ny()
+ self.d() * operand.e2em() * self.d()
+ self.d() * operand.ps() * self.nx()
+ self.nx() * operand.e2em() * self.nx()
+ self.nx() * operand.epem() * self.ny()
- self.nx() * operand.ps() * self.d()
+ self.ny() * operand.e1em() * self.d()
- self.ny() * operand.e2em() * self.ny()
+ self.ny() * operand.epem() * self.nx(),
-(self.d() * operand.e1em() * self.nx())
+ self.d() * operand.epem() * self.d()
+ self.d() * operand.ps() * self.ny()
- self.nx() * operand.e1em() * self.d()
+ self.nx() * operand.e2em() * self.ny()
- self.nx() * operand.epem() * self.nx()
+ self.ny() * operand.e2em() * self.nx()
+ self.ny() * operand.epem() * self.ny()
- self.ny() * operand.ps() * self.d(),
self.d() * operand.e2em() * self.nx() + self.d() * operand.epem() * self.ny()
- self.d() * operand.ps() * self.d()
- self.nx() * operand.e1em() * self.ny()
- self.nx() * operand.e2em() * self.d()
- self.nx() * operand.ps() * self.nx()
+ self.ny() * operand.e1em() * self.nx()
- self.ny() * operand.epem() * self.d()
- self.ny() * operand.ps() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Motor<T>> for Unit<Line<T>> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
operand.s() * self.as_inner().d() * self.as_inner().d()
+ operand.s() * self.as_inner().nx() * self.as_inner().nx()
+ operand.s() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.m() * self.as_inner().d() * self.as_inner().d())
+ -(operand.m() * self.as_inner().ny() * self.as_inner().ny())
+ T::TWO * operand.e1ep() * self.as_inner().nx() * self.as_inner().ny()
+ T::TWO * operand.e2ep() * self.as_inner().d() * self.as_inner().nx()
+ operand.m() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.e1ep() * self.as_inner().d() * self.as_inner().d())
+ -(operand.e1ep() * self.as_inner().nx() * self.as_inner().nx())
+ T::TWO * operand.e2ep() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.m() * self.as_inner().nx() * self.as_inner().ny()
+ operand.e1ep() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.e2ep() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.e2ep() * self.as_inner().ny() * self.as_inner().ny())
+ T::TWO * operand.e1ep() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.m() * self.as_inner().d() * self.as_inner().nx()
+ operand.e2ep() * self.as_inner().d() * self.as_inner().d(),
-(operand.e1em() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.epem() * self.as_inner().d() * self.as_inner().nx()
+ T::TWO * operand.e2em() * self.as_inner().d() * self.as_inner().ny()
+ operand.e1em() * self.as_inner().nx() * self.as_inner().nx()
+ operand.e1em() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.e2em() * self.as_inner().ny() * self.as_inner().ny())
+ T::TWO * operand.e1em() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.epem() * self.as_inner().nx() * self.as_inner().ny()
+ operand.e2em() * self.as_inner().d() * self.as_inner().d()
+ operand.e2em() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.epem() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.e1em() * self.as_inner().d() * self.as_inner().nx()
+ T::TWO * operand.e2em() * self.as_inner().nx() * self.as_inner().ny()
+ operand.epem() * self.as_inner().d() * self.as_inner().d()
+ operand.epem() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.ps() * self.as_inner().d() * self.as_inner().d())
+ -(operand.ps() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.ps() * self.as_inner().ny() * self.as_inner().ny()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Motor<T>>> for Line<T> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
operand.as_inner().s() * self.d() * self.d()
+ operand.as_inner().s() * self.nx() * self.nx()
+ operand.as_inner().s() * self.ny() * self.ny(),
-(operand.as_inner().m() * self.d() * self.d())
+ -(operand.as_inner().m() * self.ny() * self.ny())
+ T::TWO * operand.as_inner().e1ep() * self.nx() * self.ny()
+ T::TWO * operand.as_inner().e2ep() * self.d() * self.nx()
+ operand.as_inner().m() * self.nx() * self.nx(),
-(operand.as_inner().e1ep() * self.d() * self.d())
+ -(operand.as_inner().e1ep() * self.nx() * self.nx())
+ T::TWO * operand.as_inner().e2ep() * self.d() * self.ny()
+ T::TWO * operand.as_inner().m() * self.nx() * self.ny()
+ operand.as_inner().e1ep() * self.ny() * self.ny(),
-(operand.as_inner().e2ep() * self.nx() * self.nx())
+ -(operand.as_inner().e2ep() * self.ny() * self.ny())
+ T::TWO * operand.as_inner().e1ep() * self.d() * self.ny()
+ T::TWO * operand.as_inner().m() * self.d() * self.nx()
+ operand.as_inner().e2ep() * self.d() * self.d(),
-(operand.as_inner().e1em() * self.d() * self.d())
+ -T::TWO * operand.as_inner().epem() * self.d() * self.nx()
+ T::TWO * operand.as_inner().e2em() * self.d() * self.ny()
+ operand.as_inner().e1em() * self.nx() * self.nx()
+ operand.as_inner().e1em() * self.ny() * self.ny(),
-(operand.as_inner().e2em() * self.ny() * self.ny())
+ T::TWO * operand.as_inner().e1em() * self.d() * self.ny()
+ T::TWO * operand.as_inner().epem() * self.nx() * self.ny()
+ operand.as_inner().e2em() * self.d() * self.d()
+ operand.as_inner().e2em() * self.nx() * self.nx(),
-(operand.as_inner().epem() * self.nx() * self.nx())
+ -T::TWO * operand.as_inner().e1em() * self.d() * self.nx()
+ T::TWO * operand.as_inner().e2em() * self.nx() * self.ny()
+ operand.as_inner().epem() * self.d() * self.d()
+ operand.as_inner().epem() * self.ny() * self.ny(),
-(operand.as_inner().ps() * self.d() * self.d())
+ -(operand.as_inner().ps() * self.nx() * self.nx())
+ -(operand.as_inner().ps() * self.ny() * self.ny()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Motor<T>>> for Unit<Line<T>> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
operand.as_inner().s() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().s() * self.as_inner().nx() * self.as_inner().nx()
+ operand.as_inner().s() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().m() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().m() * self.as_inner().ny() * self.as_inner().ny())
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().nx() * self.as_inner().ny()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().m() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.as_inner().e1ep() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().e1ep() * self.as_inner().nx() * self.as_inner().nx())
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.as_inner().m() * self.as_inner().nx() * self.as_inner().ny()
+ operand.as_inner().e1ep() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().e2ep() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.as_inner().e2ep() * self.as_inner().ny() * self.as_inner().ny())
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.as_inner().m() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().e2ep() * self.as_inner().d() * self.as_inner().d(),
-(operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.as_inner().epem() * self.as_inner().d() * self.as_inner().nx()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().d() * self.as_inner().ny()
+ operand.as_inner().e1em() * self.as_inner().nx() * self.as_inner().nx()
+ operand.as_inner().e1em() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().e2em() * self.as_inner().ny() * self.as_inner().ny())
+ T::TWO * operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.as_inner().epem() * self.as_inner().nx() * self.as_inner().ny()
+ operand.as_inner().e2em() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().e2em() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.as_inner().epem() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().nx()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().nx() * self.as_inner().ny()
+ operand.as_inner().epem() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().epem() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().ps() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().ps() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.as_inner().ps() * self.as_inner().ny() * self.as_inner().ny()),
)
}
}
#[doc = "Antisandwich product: [`Line`] x [`PointPair`] x antirev([`Line`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<PointPair<T>> for Line<T> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
self.d() * operand.e2ep() * self.nx() - self.d() * operand.m() * self.d()
+ self.nx() * operand.e1ep() * self.ny()
+ self.nx() * operand.e2ep() * self.d()
+ self.nx() * operand.m() * self.nx()
+ self.ny() * operand.e1ep() * self.nx()
- self.ny() * operand.m() * self.ny(),
-(self.d() * operand.e1ep() * self.d()) + self.d() * operand.e2ep() * self.ny()
- self.nx() * operand.e1ep() * self.nx()
+ self.nx() * operand.m() * self.ny()
+ self.ny() * operand.e1ep() * self.ny()
+ self.ny() * operand.e2ep() * self.d()
+ self.ny() * operand.m() * self.nx(),
self.d() * operand.e1ep() * self.ny()
+ self.d() * operand.e2ep() * self.d()
+ self.d() * operand.m() * self.nx()
- self.nx() * operand.e2ep() * self.nx()
+ self.nx() * operand.m() * self.d()
+ self.ny() * operand.e1ep() * self.d()
- self.ny() * operand.e2ep() * self.ny(),
-(self.d() * operand.e1em() * self.d()) + self.d() * operand.e2em() * self.ny()
- self.d() * operand.epem() * self.nx()
+ self.nx() * operand.e1em() * self.nx()
- self.nx() * operand.epem() * self.d()
+ self.ny() * operand.e1em() * self.ny()
+ self.ny() * operand.e2em() * self.d(),
self.d() * operand.e1em() * self.ny()
+ self.d() * operand.e2em() * self.d()
+ self.nx() * operand.e2em() * self.nx()
+ self.nx() * operand.epem() * self.ny()
+ self.ny() * operand.e1em() * self.d()
- self.ny() * operand.e2em() * self.ny()
+ self.ny() * operand.epem() * self.nx(),
-(self.d() * operand.e1em() * self.nx()) + self.d() * operand.epem() * self.d()
- self.nx() * operand.e1em() * self.d()
+ self.nx() * operand.e2em() * self.ny()
- self.nx() * operand.epem() * self.nx()
+ self.ny() * operand.e2em() * self.nx()
+ self.ny() * operand.epem() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<PointPair<T>> for Unit<Line<T>> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.m() * self.as_inner().d() * self.as_inner().d())
+ -(operand.m() * self.as_inner().ny() * self.as_inner().ny())
+ T::TWO * operand.e1ep() * self.as_inner().nx() * self.as_inner().ny()
+ T::TWO * operand.e2ep() * self.as_inner().d() * self.as_inner().nx()
+ operand.m() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.e1ep() * self.as_inner().d() * self.as_inner().d())
+ -(operand.e1ep() * self.as_inner().nx() * self.as_inner().nx())
+ T::TWO * operand.e2ep() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.m() * self.as_inner().nx() * self.as_inner().ny()
+ operand.e1ep() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.e2ep() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.e2ep() * self.as_inner().ny() * self.as_inner().ny())
+ T::TWO * operand.e1ep() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.m() * self.as_inner().d() * self.as_inner().nx()
+ operand.e2ep() * self.as_inner().d() * self.as_inner().d(),
-(operand.e1em() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.epem() * self.as_inner().d() * self.as_inner().nx()
+ T::TWO * operand.e2em() * self.as_inner().d() * self.as_inner().ny()
+ operand.e1em() * self.as_inner().nx() * self.as_inner().nx()
+ operand.e1em() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.e2em() * self.as_inner().ny() * self.as_inner().ny())
+ T::TWO * operand.e1em() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.epem() * self.as_inner().nx() * self.as_inner().ny()
+ operand.e2em() * self.as_inner().d() * self.as_inner().d()
+ operand.e2em() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.epem() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.e1em() * self.as_inner().d() * self.as_inner().nx()
+ T::TWO * operand.e2em() * self.as_inner().nx() * self.as_inner().ny()
+ operand.epem() * self.as_inner().d() * self.as_inner().d()
+ operand.epem() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<PointPair<T>>> for Line<T> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.d() * self.d())
+ -(operand.as_inner().m() * self.ny() * self.ny())
+ T::TWO * operand.as_inner().e1ep() * self.nx() * self.ny()
+ T::TWO * operand.as_inner().e2ep() * self.d() * self.nx()
+ operand.as_inner().m() * self.nx() * self.nx(),
-(operand.as_inner().e1ep() * self.d() * self.d())
+ -(operand.as_inner().e1ep() * self.nx() * self.nx())
+ T::TWO * operand.as_inner().e2ep() * self.d() * self.ny()
+ T::TWO * operand.as_inner().m() * self.nx() * self.ny()
+ operand.as_inner().e1ep() * self.ny() * self.ny(),
-(operand.as_inner().e2ep() * self.nx() * self.nx())
+ -(operand.as_inner().e2ep() * self.ny() * self.ny())
+ T::TWO * operand.as_inner().e1ep() * self.d() * self.ny()
+ T::TWO * operand.as_inner().m() * self.d() * self.nx()
+ operand.as_inner().e2ep() * self.d() * self.d(),
-(operand.as_inner().e1em() * self.d() * self.d())
+ -T::TWO * operand.as_inner().epem() * self.d() * self.nx()
+ T::TWO * operand.as_inner().e2em() * self.d() * self.ny()
+ operand.as_inner().e1em() * self.nx() * self.nx()
+ operand.as_inner().e1em() * self.ny() * self.ny(),
-(operand.as_inner().e2em() * self.ny() * self.ny())
+ T::TWO * operand.as_inner().e1em() * self.d() * self.ny()
+ T::TWO * operand.as_inner().epem() * self.nx() * self.ny()
+ operand.as_inner().e2em() * self.d() * self.d()
+ operand.as_inner().e2em() * self.nx() * self.nx(),
-(operand.as_inner().epem() * self.nx() * self.nx())
+ -T::TWO * operand.as_inner().e1em() * self.d() * self.nx()
+ T::TWO * operand.as_inner().e2em() * self.nx() * self.ny()
+ operand.as_inner().epem() * self.d() * self.d()
+ operand.as_inner().epem() * self.ny() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<PointPair<T>>> for Unit<Line<T>> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().m() * self.as_inner().ny() * self.as_inner().ny())
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().nx() * self.as_inner().ny()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().m() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.as_inner().e1ep() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().e1ep() * self.as_inner().nx() * self.as_inner().nx())
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.as_inner().m() * self.as_inner().nx() * self.as_inner().ny()
+ operand.as_inner().e1ep() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().e2ep() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.as_inner().e2ep() * self.as_inner().ny() * self.as_inner().ny())
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.as_inner().m() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().e2ep() * self.as_inner().d() * self.as_inner().d(),
-(operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().d())
+ -T::TWO * operand.as_inner().epem() * self.as_inner().d() * self.as_inner().nx()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().d() * self.as_inner().ny()
+ operand.as_inner().e1em() * self.as_inner().nx() * self.as_inner().nx()
+ operand.as_inner().e1em() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().e2em() * self.as_inner().ny() * self.as_inner().ny())
+ T::TWO * operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.as_inner().epem() * self.as_inner().nx() * self.as_inner().ny()
+ operand.as_inner().e2em() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().e2em() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.as_inner().epem() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().d() * self.as_inner().nx()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().nx() * self.as_inner().ny()
+ operand.as_inner().epem() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().epem() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[doc = "Antisandwich product: [`Line`] x [`Pseudoscalar`] x antirev([`Line`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Pseudoscalar<T>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(self.d() * operand.ps() * self.d())
- self.nx() * operand.ps() * self.nx()
- self.ny() * operand.ps() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Pseudoscalar<T>> for Unit<Line<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.ps() * self.as_inner().d() * self.as_inner().d())
+ -(operand.ps() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.ps() * self.as_inner().ny() * self.as_inner().ny()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Pseudoscalar<T>>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.d() * self.d())
+ -(operand.as_inner().ps() * self.nx() * self.nx())
+ -(operand.as_inner().ps() * self.ny() * self.ny()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Pseudoscalar<T>>> for Unit<Line<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().ps() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.as_inner().ps() * self.as_inner().ny() * self.as_inner().ny()),
)
}
}
#[doc = "Antisandwich product: [`Line`] x [`RoundPoint`] x antirev([`Line`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<RoundPoint<T>> for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
self.d() * operand.ep() * self.nx() + self.d() * operand.x() * self.d()
- self.d() * operand.y() * self.ny()
+ self.nx() * operand.ep() * self.d()
- self.nx() * operand.x() * self.nx()
- self.ny() * operand.x() * self.ny()
- self.ny() * operand.y() * self.d(),
-(self.d() * operand.x() * self.ny())
- self.d() * operand.y() * self.d()
- self.nx() * operand.ep() * self.ny()
- self.nx() * operand.y() * self.nx()
- self.ny() * operand.ep() * self.nx()
- self.ny() * operand.x() * self.d()
+ self.ny() * operand.y() * self.ny(),
-(self.d() * operand.ep() * self.d())
+ self.d() * operand.x() * self.nx()
+ self.nx() * operand.ep() * self.nx()
+ self.nx() * operand.x() * self.d()
- self.nx() * operand.y() * self.ny()
- self.ny() * operand.ep() * self.ny()
- self.ny() * operand.y() * self.nx(),
-(self.d() * operand.em() * self.d())
- self.nx() * operand.em() * self.nx()
- self.ny() * operand.em() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<RoundPoint<T>> for Unit<Line<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.x() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.x() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.y() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.ep() * self.as_inner().d() * self.as_inner().nx()
+ operand.x() * self.as_inner().d() * self.as_inner().d(),
-(operand.y() * self.as_inner().d() * self.as_inner().d())
+ -(operand.y() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.ep() * self.as_inner().nx() * self.as_inner().ny()
+ -T::TWO * operand.x() * self.as_inner().d() * self.as_inner().ny()
+ operand.y() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.ep() * self.as_inner().d() * self.as_inner().d())
+ -(operand.ep() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.y() * self.as_inner().nx() * self.as_inner().ny()
+ T::TWO * operand.x() * self.as_inner().d() * self.as_inner().nx()
+ operand.ep() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.em() * self.as_inner().d() * self.as_inner().d())
+ -(operand.em() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.em() * self.as_inner().ny() * self.as_inner().ny()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<RoundPoint<T>>> for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.nx() * self.nx())
+ -(operand.as_inner().x() * self.ny() * self.ny())
+ -T::TWO * operand.as_inner().y() * self.d() * self.ny()
+ T::TWO * operand.as_inner().ep() * self.d() * self.nx()
+ operand.as_inner().x() * self.d() * self.d(),
-(operand.as_inner().y() * self.d() * self.d())
+ -(operand.as_inner().y() * self.nx() * self.nx())
+ -T::TWO * operand.as_inner().ep() * self.nx() * self.ny()
+ -T::TWO * operand.as_inner().x() * self.d() * self.ny()
+ operand.as_inner().y() * self.ny() * self.ny(),
-(operand.as_inner().ep() * self.d() * self.d())
+ -(operand.as_inner().ep() * self.ny() * self.ny())
+ -T::TWO * operand.as_inner().y() * self.nx() * self.ny()
+ T::TWO * operand.as_inner().x() * self.d() * self.nx()
+ operand.as_inner().ep() * self.nx() * self.nx(),
-(operand.as_inner().em() * self.d() * self.d())
+ -(operand.as_inner().em() * self.nx() * self.nx())
+ -(operand.as_inner().em() * self.ny() * self.ny()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<RoundPoint<T>>> for Unit<Line<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.as_inner().x() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.as_inner().y() * self.as_inner().d() * self.as_inner().ny()
+ T::TWO * operand.as_inner().ep() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().x() * self.as_inner().d() * self.as_inner().d(),
-(operand.as_inner().y() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().y() * self.as_inner().nx() * self.as_inner().nx())
+ -T::TWO * operand.as_inner().ep() * self.as_inner().nx() * self.as_inner().ny()
+ -T::TWO * operand.as_inner().x() * self.as_inner().d() * self.as_inner().ny()
+ operand.as_inner().y() * self.as_inner().ny() * self.as_inner().ny(),
-(operand.as_inner().ep() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().ep() * self.as_inner().ny() * self.as_inner().ny())
+ -T::TWO * operand.as_inner().y() * self.as_inner().nx() * self.as_inner().ny()
+ T::TWO * operand.as_inner().x() * self.as_inner().d() * self.as_inner().nx()
+ operand.as_inner().ep() * self.as_inner().nx() * self.as_inner().nx(),
-(operand.as_inner().em() * self.as_inner().d() * self.as_inner().d())
+ -(operand.as_inner().em() * self.as_inner().nx() * self.as_inner().nx())
+ -(operand.as_inner().em() * self.as_inner().ny() * self.as_inner().ny()),
)
}
}
#[doc = "Antisandwich product: [`Line`] x [`Scalar`] x antirev([`Line`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Scalar<T>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
self.d() * operand.s() * self.d()
+ self.nx() * operand.s() * self.nx()
+ self.ny() * operand.s() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Scalar<T>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
operand.s() * self.as_inner().d() * self.as_inner().d()
+ operand.s() * self.as_inner().nx() * self.as_inner().nx()
+ operand.s() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Scalar<T>>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
operand.as_inner().s() * self.d() * self.d()
+ operand.as_inner().s() * self.nx() * self.nx()
+ operand.as_inner().s() * self.ny() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Scalar<T>>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
operand.as_inner().s() * self.as_inner().d() * self.as_inner().d()
+ operand.as_inner().s() * self.as_inner().nx() * self.as_inner().nx()
+ operand.as_inner().s() * self.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[doc = "Antisandwich product: [`Motor`] x [`Circle`] x antirev([`Motor`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Circle<T>> for Motor<T> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-(self.e1em() * operand.e12em() * self.e1ep())
+ self.e1em() * operand.e1epem() * self.m()
+ self.e1em() * operand.e2epem() * self.s()
+ self.e1em() * operand.w() * self.e1em()
- self.e1ep() * operand.e12em() * self.e1em()
+ self.e1ep() * operand.e1epem() * self.ps()
+ self.e1ep() * operand.e2epem() * self.epem()
+ self.e1ep() * operand.w() * self.e1ep()
- self.e2em() * operand.e12em() * self.e2ep()
- self.e2em() * operand.e1epem() * self.s()
+ self.e2em() * operand.e2epem() * self.m()
+ self.e2em() * operand.w() * self.e2em()
- self.e2ep() * operand.e12em() * self.e2em()
- self.e2ep() * operand.e1epem() * self.epem()
+ self.e2ep() * operand.e2epem() * self.ps()
+ self.e2ep() * operand.w() * self.e2ep()
+ self.epem() * operand.e12em() * self.s()
- self.epem() * operand.e1epem() * self.e2ep()
+ self.epem() * operand.e2epem() * self.e1ep()
+ self.epem() * operand.w() * self.epem()
+ self.m() * operand.e12em() * self.ps()
+ self.m() * operand.e1epem() * self.e1em()
+ self.m() * operand.e2epem() * self.e2em()
+ self.m() * operand.w() * self.m()
+ self.ps() * operand.e12em() * self.m()
+ self.ps() * operand.e1epem() * self.e1ep()
+ self.ps() * operand.e2epem() * self.e2ep()
+ self.ps() * operand.w() * self.ps()
+ self.s() * operand.e12em() * self.epem()
- self.s() * operand.e1epem() * self.e2em()
+ self.s() * operand.e2epem() * self.e1em()
+ self.s() * operand.w() * self.s(),
-(self.e1em() * operand.e12em() * self.e1em())
+ self.e1em() * operand.e1epem() * self.ps()
+ self.e1em() * operand.e2epem() * self.epem()
+ self.e1em() * operand.w() * self.e1ep()
- self.e1ep() * operand.e12em() * self.e1ep()
+ self.e1ep() * operand.e1epem() * self.m()
+ self.e1ep() * operand.e2epem() * self.s()
+ self.e1ep() * operand.w() * self.e1em()
- self.e2em() * operand.e12em() * self.e2em()
- self.e2em() * operand.e1epem() * self.epem()
+ self.e2em() * operand.e2epem() * self.ps()
+ self.e2em() * operand.w() * self.e2ep()
- self.e2ep() * operand.e12em() * self.e2ep()
- self.e2ep() * operand.e1epem() * self.s()
+ self.e2ep() * operand.e2epem() * self.m()
+ self.e2ep() * operand.w() * self.e2em()
+ self.epem() * operand.e12em() * self.epem()
- self.epem() * operand.e1epem() * self.e2em()
+ self.epem() * operand.e2epem() * self.e1em()
+ self.epem() * operand.w() * self.s()
+ self.m() * operand.e12em() * self.m()
+ self.m() * operand.e1epem() * self.e1ep()
+ self.m() * operand.e2epem() * self.e2ep()
+ self.m() * operand.w() * self.ps()
+ self.ps() * operand.e12em() * self.ps()
+ self.ps() * operand.e1epem() * self.e1em()
+ self.ps() * operand.e2epem() * self.e2em()
+ self.ps() * operand.w() * self.m()
+ self.s() * operand.e12em() * self.s()
- self.s() * operand.e1epem() * self.e2ep()
+ self.s() * operand.e2epem() * self.e1ep()
+ self.s() * operand.w() * self.epem(),
-(self.e1em() * operand.e12em() * self.ps())
- self.e1em() * operand.e1epem() * self.e1em()
- self.e1em() * operand.e2epem() * self.e2em()
- self.e1em() * operand.w() * self.m()
+ self.e1ep() * operand.e12em() * self.m()
+ self.e1ep() * operand.e1epem() * self.e1ep()
+ self.e1ep() * operand.e2epem() * self.e2ep()
+ self.e1ep() * operand.w() * self.ps()
- self.e2em() * operand.e12em() * self.epem()
+ self.e2em() * operand.e1epem() * self.e2em()
- self.e2em() * operand.e2epem() * self.e1em()
- self.e2em() * operand.w() * self.s()
+ self.e2ep() * operand.e12em() * self.s()
- self.e2ep() * operand.e1epem() * self.e2ep()
+ self.e2ep() * operand.e2epem() * self.e1ep()
+ self.e2ep() * operand.w() * self.epem()
- self.epem() * operand.e12em() * self.e2em()
- self.epem() * operand.e1epem() * self.epem()
+ self.epem() * operand.e2epem() * self.ps()
+ self.epem() * operand.w() * self.e2ep()
+ self.m() * operand.e12em() * self.e1ep()
- self.m() * operand.e1epem() * self.m()
- self.m() * operand.e2epem() * self.s()
- self.m() * operand.w() * self.e1em()
- self.ps() * operand.e12em() * self.e1em()
+ self.ps() * operand.e1epem() * self.ps()
+ self.ps() * operand.e2epem() * self.epem()
+ self.ps() * operand.w() * self.e1ep()
+ self.s() * operand.e12em() * self.e2ep()
+ self.s() * operand.e1epem() * self.s()
- self.s() * operand.e2epem() * self.m()
- self.s() * operand.w() * self.e2em(),
self.e1em() * operand.e12em() * self.epem()
- self.e1em() * operand.e1epem() * self.e2em()
+ self.e1em() * operand.e2epem() * self.e1em()
+ self.e1em() * operand.w() * self.s()
- self.e1ep() * operand.e12em() * self.s()
+ self.e1ep() * operand.e1epem() * self.e2ep()
- self.e1ep() * operand.e2epem() * self.e1ep()
- self.e1ep() * operand.w() * self.epem()
- self.e2em() * operand.e12em() * self.ps()
- self.e2em() * operand.e1epem() * self.e1em()
- self.e2em() * operand.e2epem() * self.e2em()
- self.e2em() * operand.w() * self.m()
+ self.e2ep() * operand.e12em() * self.m()
+ self.e2ep() * operand.e1epem() * self.e1ep()
+ self.e2ep() * operand.e2epem() * self.e2ep()
+ self.e2ep() * operand.w() * self.ps()
+ self.epem() * operand.e12em() * self.e1em()
- self.epem() * operand.e1epem() * self.ps()
- self.epem() * operand.e2epem() * self.epem()
- self.epem() * operand.w() * self.e1ep()
+ self.m() * operand.e12em() * self.e2ep()
+ self.m() * operand.e1epem() * self.s()
- self.m() * operand.e2epem() * self.m()
- self.m() * operand.w() * self.e2em()
- self.ps() * operand.e12em() * self.e2em()
- self.ps() * operand.e1epem() * self.epem()
+ self.ps() * operand.e2epem() * self.ps()
+ self.ps() * operand.w() * self.e2ep()
- self.s() * operand.e12em() * self.e1ep()
+ self.s() * operand.e1epem() * self.m()
+ self.s() * operand.e2epem() * self.s()
+ self.s() * operand.w() * self.e1em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Circle<T>> for Unit<Motor<T>> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.e12em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.e12em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.e1epem() * self.as_inner().e2em() * self.as_inner().s()
+ -T::TWO * operand.e1epem() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.e12em() * self.as_inner().epem() * self.as_inner().s()
+ T::TWO * operand.e12em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.e1epem() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.e1epem() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO * operand.e2epem() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.e2epem() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.e2epem() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.e2epem() * self.as_inner().e2ep() * self.as_inner().ps()
+ operand.w() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.w() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.w() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.w() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.w() * self.as_inner().epem() * self.as_inner().epem()
+ operand.w() * self.as_inner().m() * self.as_inner().m()
+ operand.w() * self.as_inner().ps() * self.as_inner().ps()
+ operand.w() * self.as_inner().s() * self.as_inner().s(),
-(operand.e12em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e12em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e12em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e12em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO * operand.e1epem() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.e1epem() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.e1epem() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.e1epem() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e2epem() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e2epem() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.e2epem() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.e2epem() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.w() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.w() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.w() * self.as_inner().epem() * self.as_inner().s()
+ T::TWO * operand.w() * self.as_inner().m() * self.as_inner().ps()
+ operand.e12em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.e12em() * self.as_inner().m() * self.as_inner().m()
+ operand.e12em() * self.as_inner().ps() * self.as_inner().ps()
+ operand.e12em() * self.as_inner().s() * self.as_inner().s(),
-(operand.e1epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e1epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e1epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e12em() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.e12em() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.e2epem() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e2epem() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO * operand.w() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.w() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.e12em() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e12em() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.e2epem() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e2epem() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO * operand.w() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO * operand.w() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.e1epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e1epem() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e1epem() * self.as_inner().ps() * self.as_inner().ps()
+ operand.e1epem() * self.as_inner().s() * self.as_inner().s(),
-(operand.e2epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e2epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e2epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e12em() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.e12em() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO * operand.e1epem() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e1epem() * self.as_inner().epem() * self.as_inner().ps()
+ -T::TWO * operand.w() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.w() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.e12em() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e12em() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.e1epem() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e1epem() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.w() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.w() * self.as_inner().e2ep() * self.as_inner().ps()
+ operand.e2epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e2epem() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e2epem() * self.as_inner().ps() * self.as_inner().ps()
+ operand.e2epem() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Circle<T>>> for Motor<T> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.as_inner().e12em() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().e12em() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().e1epem() * self.e2em() * self.s()
+ -T::TWO * operand.as_inner().e1epem() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().e12em() * self.epem() * self.s()
+ T::TWO * operand.as_inner().e12em() * self.m() * self.ps()
+ T::TWO * operand.as_inner().e1epem() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().e1epem() * self.e1ep() * self.ps()
+ T::TWO * operand.as_inner().e2epem() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().e2epem() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().e2epem() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().e2epem() * self.e2ep() * self.ps()
+ operand.as_inner().w() * self.e1em() * self.e1em()
+ operand.as_inner().w() * self.e1ep() * self.e1ep()
+ operand.as_inner().w() * self.e2em() * self.e2em()
+ operand.as_inner().w() * self.e2ep() * self.e2ep()
+ operand.as_inner().w() * self.epem() * self.epem()
+ operand.as_inner().w() * self.m() * self.m()
+ operand.as_inner().w() * self.ps() * self.ps()
+ operand.as_inner().w() * self.s() * self.s(),
-(operand.as_inner().e12em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e12em() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e12em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e12em() * self.e2ep() * self.e2ep())
+ -T::TWO * operand.as_inner().e1epem() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().e1epem() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().e1epem() * self.e1em() * self.ps()
+ T::TWO * operand.as_inner().e1epem() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e2epem() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e2epem() * self.e1ep() * self.s()
+ T::TWO * operand.as_inner().e2epem() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().e2epem() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().w() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().w() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().w() * self.epem() * self.s()
+ T::TWO * operand.as_inner().w() * self.m() * self.ps()
+ operand.as_inner().e12em() * self.epem() * self.epem()
+ operand.as_inner().e12em() * self.m() * self.m()
+ operand.as_inner().e12em() * self.ps() * self.ps()
+ operand.as_inner().e12em() * self.s() * self.s(),
-(operand.as_inner().e1epem() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1epem() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e1epem() * self.epem() * self.epem())
+ -(operand.as_inner().e1epem() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e12em() * self.e1em() * self.ps()
+ -T::TWO * operand.as_inner().e12em() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().e2epem() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e2epem() * self.m() * self.s()
+ -T::TWO * operand.as_inner().w() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().w() * self.e2em() * self.s()
+ T::TWO * operand.as_inner().e12em() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e12em() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().e2epem() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e2epem() * self.epem() * self.ps()
+ T::TWO * operand.as_inner().w() * self.e1ep() * self.ps()
+ T::TWO * operand.as_inner().w() * self.e2ep() * self.epem()
+ operand.as_inner().e1epem() * self.e1ep() * self.e1ep()
+ operand.as_inner().e1epem() * self.e2em() * self.e2em()
+ operand.as_inner().e1epem() * self.ps() * self.ps()
+ operand.as_inner().e1epem() * self.s() * self.s(),
-(operand.as_inner().e2epem() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e2epem() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2epem() * self.epem() * self.epem())
+ -(operand.as_inner().e2epem() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e12em() * self.e1ep() * self.s()
+ -T::TWO * operand.as_inner().e12em() * self.e2em() * self.ps()
+ -T::TWO * operand.as_inner().e1epem() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e1epem() * self.epem() * self.ps()
+ -T::TWO * operand.as_inner().w() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().w() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().e12em() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e12em() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().e1epem() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e1epem() * self.m() * self.s()
+ T::TWO * operand.as_inner().w() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().w() * self.e2ep() * self.ps()
+ operand.as_inner().e2epem() * self.e1em() * self.e1em()
+ operand.as_inner().e2epem() * self.e2ep() * self.e2ep()
+ operand.as_inner().e2epem() * self.ps() * self.ps()
+ operand.as_inner().e2epem() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Circle<T>>> for Unit<Motor<T>> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.as_inner().e12em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e2em()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().epem()
* self.as_inner().s()
+ T::TWO * operand.as_inner().e12em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1em()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1ep()
* self.as_inner().ps()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1em()
* self.as_inner().s()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e2em()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e2ep()
* self.as_inner().ps()
+ operand.as_inner().w() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().w() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().w() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().w() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().w() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().w() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().w() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().w() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().e12em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e12em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e12em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e12em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e2ep()
* self.as_inner().s()
+ T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1em()
* self.as_inner().ps()
+ T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1ep()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1ep()
* self.as_inner().s()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e2em()
* self.as_inner().ps()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e2ep()
* self.as_inner().m()
+ T::TWO * operand.as_inner().w() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.as_inner().w() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.as_inner().w() * self.as_inner().epem() * self.as_inner().s()
+ T::TWO * operand.as_inner().w() * self.as_inner().m() * self.as_inner().ps()
+ operand.as_inner().e12em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().e12em() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().e12em() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().e12em() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().e1epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e1epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e1epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e1em()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO * operand.as_inner().e2epem() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO * operand.as_inner().w() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.as_inner().w() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e1ep()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2ep()
* self.as_inner().s()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().epem()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().w() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO * operand.as_inner().w() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.as_inner().e1epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e1epem() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e1epem() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().e1epem() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().e2epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e2epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e2epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e1ep()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2em()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().epem()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().w()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().w() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2ep()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().e1epem() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.as_inner().w() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.as_inner().w() * self.as_inner().e2ep() * self.as_inner().ps()
+ operand.as_inner().e2epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e2epem() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e2epem() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().e2epem() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Antisandwich product: [`Motor`] x [`FlatPoint`] x antirev([`Motor`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<FlatPoint<T>> for Motor<T> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
self.e1em() * operand.e1em() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.epem() * self.epem()
+ self.e1ep() * operand.e1em() * self.e1ep()
+ self.e1ep() * operand.e2em() * self.e2ep()
+ self.e1ep() * operand.epem() * self.s()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1em()
- self.e2em() * operand.epem() * self.ps()
- self.e2ep() * operand.e1em() * self.e2ep()
+ self.e2ep() * operand.e2em() * self.e1ep()
- self.e2ep() * operand.epem() * self.m()
- self.epem() * operand.e1em() * self.epem()
+ self.epem() * operand.e2em() * self.ps()
+ self.epem() * operand.epem() * self.e1em()
+ self.m() * operand.e1em() * self.m()
+ self.m() * operand.e2em() * self.s()
- self.m() * operand.epem() * self.e2ep()
+ self.ps() * operand.e1em() * self.ps()
+ self.ps() * operand.e2em() * self.epem()
- self.ps() * operand.epem() * self.e2em()
- self.s() * operand.e1em() * self.s()
+ self.s() * operand.e2em() * self.m()
+ self.s() * operand.epem() * self.e1ep(),
self.e1em() * operand.e1em() * self.e2em() - self.e1em() * operand.e2em() * self.e1em()
+ self.e1em() * operand.epem() * self.ps()
+ self.e1ep() * operand.e1em() * self.e2ep()
- self.e1ep() * operand.e2em() * self.e1ep()
+ self.e1ep() * operand.epem() * self.m()
+ self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.epem() * self.epem()
+ self.e2ep() * operand.e1em() * self.e1ep()
+ self.e2ep() * operand.e2em() * self.e2ep()
+ self.e2ep() * operand.epem() * self.s()
- self.epem() * operand.e1em() * self.ps()
- self.epem() * operand.e2em() * self.epem()
+ self.epem() * operand.epem() * self.e2em()
- self.m() * operand.e1em() * self.s()
+ self.m() * operand.e2em() * self.m()
+ self.m() * operand.epem() * self.e1ep()
- self.ps() * operand.e1em() * self.epem()
+ self.ps() * operand.e2em() * self.ps()
+ self.ps() * operand.epem() * self.e1em()
- self.s() * operand.e1em() * self.m()
- self.s() * operand.e2em() * self.s()
+ self.s() * operand.epem() * self.e2ep(),
self.e1em() * operand.e1em() * self.epem()
- self.e1em() * operand.e2em() * self.ps()
- self.e1em() * operand.epem() * self.e1em()
- self.e1ep() * operand.e1em() * self.s()
+ self.e1ep() * operand.e2em() * self.m()
+ self.e1ep() * operand.epem() * self.e1ep()
+ self.e2em() * operand.e1em() * self.ps()
+ self.e2em() * operand.e2em() * self.epem()
- self.e2em() * operand.epem() * self.e2em()
- self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.e2em() * self.s()
+ self.e2ep() * operand.epem() * self.e2ep()
+ self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.epem() * self.epem()
- self.m() * operand.e1em() * self.e2ep()
+ self.m() * operand.e2em() * self.e1ep()
- self.m() * operand.epem() * self.m()
+ self.ps() * operand.e1em() * self.e2em()
- self.ps() * operand.e2em() * self.e1em()
+ self.ps() * operand.epem() * self.ps()
- self.s() * operand.e1em() * self.e1ep()
- self.s() * operand.e2em() * self.e2ep()
- self.s() * operand.epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<FlatPoint<T>> for Unit<Motor<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e1em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e1em() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e1em() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO * operand.e2em() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().s()
+ operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e1em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e1em() * self.as_inner().m() * self.as_inner().m()
+ operand.e1em() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e2em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e2em() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e2em() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().ps()
+ -T::TWO * operand.e1em() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().s()
+ operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e2em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e2em() * self.as_inner().m() * self.as_inner().m()
+ operand.e2em() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.epem() * self.as_inner().m() * self.as_inner().m())
+ -(operand.epem() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.e2em() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.epem() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.epem() * self.as_inner().epem() * self.as_inner().epem()
+ operand.epem() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<FlatPoint<T>>> for Motor<T> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e1em() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e1em() * self.epem() * self.epem())
+ -(operand.as_inner().e1em() * self.s() * self.s())
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.ps()
+ -T::TWO * operand.as_inner().epem() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e2em() * self.epem() * self.ps()
+ T::TWO * operand.as_inner().e2em() * self.m() * self.s()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.s()
+ operand.as_inner().e1em() * self.e1em() * self.e1em()
+ operand.as_inner().e1em() * self.e1ep() * self.e1ep()
+ operand.as_inner().e1em() * self.m() * self.m()
+ operand.as_inner().e1em() * self.ps() * self.ps(),
-(operand.as_inner().e2em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e2em() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e2em() * self.epem() * self.epem())
+ -(operand.as_inner().e2em() * self.s() * self.s())
+ -T::TWO * operand.as_inner().e1em() * self.epem() * self.ps()
+ -T::TWO * operand.as_inner().e1em() * self.m() * self.s()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().epem() * self.e2ep() * self.s()
+ operand.as_inner().e2em() * self.e2em() * self.e2em()
+ operand.as_inner().e2em() * self.e2ep() * self.e2ep()
+ operand.as_inner().e2em() * self.m() * self.m()
+ operand.as_inner().e2em() * self.ps() * self.ps(),
-(operand.as_inner().epem() * self.e1em() * self.e1em())
+ -(operand.as_inner().epem() * self.e2em() * self.e2em())
+ -(operand.as_inner().epem() * self.m() * self.m())
+ -(operand.as_inner().epem() * self.s() * self.s())
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.s()
+ -T::TWO * operand.as_inner().e1em() * self.e2ep() * self.m()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.ps()
+ -T::TWO * operand.as_inner().e2em() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e1em() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ operand.as_inner().epem() * self.e1ep() * self.e1ep()
+ operand.as_inner().epem() * self.e2ep() * self.e2ep()
+ operand.as_inner().epem() * self.epem() * self.epem()
+ operand.as_inner().epem() * self.ps() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<FlatPoint<T>>> for Unit<Motor<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e1em() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().epem()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().s()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().s()
+ operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e1em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().e1em() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e2em() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().epem()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().s()
+ operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e2em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().e2em() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().epem() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().epem() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2ep()
* self.as_inner().s()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().epem() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[doc = "Antisandwich product: [`Motor`] x [`Line`] x antirev([`Motor`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Line<T>> for Motor<T> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
self.e1em() * operand.d() * self.epem() - self.e1em() * operand.nx() * self.e1em()
+ self.e1em() * operand.ny() * self.ps()
+ self.e1ep() * operand.d() * self.s()
- self.e1ep() * operand.nx() * self.e1ep()
+ self.e1ep() * operand.ny() * self.m()
+ self.e2em() * operand.d() * self.ps()
- self.e2em() * operand.nx() * self.e2em()
- self.e2em() * operand.ny() * self.epem()
+ self.e2ep() * operand.d() * self.m()
- self.e2ep() * operand.nx() * self.e2ep()
- self.e2ep() * operand.ny() * self.s()
+ self.epem() * operand.d() * self.e1em()
+ self.epem() * operand.nx() * self.epem()
- self.epem() * operand.ny() * self.e2em()
+ self.m() * operand.d() * self.e2ep()
+ self.m() * operand.nx() * self.m()
+ self.m() * operand.ny() * self.e1ep()
+ self.ps() * operand.d() * self.e2em()
+ self.ps() * operand.nx() * self.ps()
+ self.ps() * operand.ny() * self.e1em()
+ self.s() * operand.d() * self.e1ep()
+ self.s() * operand.nx() * self.s()
- self.s() * operand.ny() * self.e2ep(),
-(self.e1em() * operand.d() * self.e2em())
- self.e1em() * operand.nx() * self.ps()
- self.e1em() * operand.ny() * self.e1em()
+ self.e1ep() * operand.d() * self.e2ep()
+ self.e1ep() * operand.nx() * self.m()
+ self.e1ep() * operand.ny() * self.e1ep()
- self.e2em() * operand.d() * self.e1em()
- self.e2em() * operand.nx() * self.epem()
+ self.e2em() * operand.ny() * self.e2em()
+ self.e2ep() * operand.d() * self.e1ep()
+ self.e2ep() * operand.nx() * self.s()
- self.e2ep() * operand.ny() * self.e2ep()
+ self.epem() * operand.d() * self.ps()
- self.epem() * operand.nx() * self.e2em()
- self.epem() * operand.ny() * self.epem()
- self.m() * operand.d() * self.s()
+ self.m() * operand.nx() * self.e1ep()
- self.m() * operand.ny() * self.m()
+ self.ps() * operand.d() * self.epem()
- self.ps() * operand.nx() * self.e1em()
+ self.ps() * operand.ny() * self.ps()
- self.s() * operand.d() * self.m()
+ self.s() * operand.nx() * self.e2ep()
+ self.s() * operand.ny() * self.s(),
self.e1em() * operand.d() * self.e1em() + self.e1em() * operand.nx() * self.epem()
- self.e1em() * operand.ny() * self.e2em()
- self.e1ep() * operand.d() * self.e1ep()
- self.e1ep() * operand.nx() * self.s()
+ self.e1ep() * operand.ny() * self.e2ep()
- self.e2em() * operand.d() * self.e2em()
- self.e2em() * operand.nx() * self.ps()
- self.e2em() * operand.ny() * self.e1em()
+ self.e2ep() * operand.d() * self.e2ep()
+ self.e2ep() * operand.nx() * self.m()
+ self.e2ep() * operand.ny() * self.e1ep()
- self.epem() * operand.d() * self.epem()
+ self.epem() * operand.nx() * self.e1em()
- self.epem() * operand.ny() * self.ps()
- self.m() * operand.d() * self.m()
+ self.m() * operand.nx() * self.e2ep()
+ self.m() * operand.ny() * self.s()
+ self.ps() * operand.d() * self.ps()
- self.ps() * operand.nx() * self.e2em()
- self.ps() * operand.ny() * self.epem()
+ self.s() * operand.d() * self.s()
- self.s() * operand.nx() * self.e1ep()
+ self.s() * operand.ny() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Line<T>> for Unit<Motor<T>> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(operand.nx() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.nx() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.nx() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.nx() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO * operand.ny() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.ny() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.d() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.d() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.d() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.d() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.ny() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.ny() * self.as_inner().e1ep() * self.as_inner().m()
+ operand.nx() * self.as_inner().epem() * self.as_inner().epem()
+ operand.nx() * self.as_inner().m() * self.as_inner().m()
+ operand.nx() * self.as_inner().ps() * self.as_inner().ps()
+ operand.nx() * self.as_inner().s() * self.as_inner().s(),
-(operand.ny() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ny() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.ny() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.ny() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.d() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.d() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO * operand.nx() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.nx() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.d() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.d() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO * operand.nx() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.nx() * self.as_inner().e2ep() * self.as_inner().s()
+ operand.ny() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.ny() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.ny() * self.as_inner().ps() * self.as_inner().ps()
+ operand.ny() * self.as_inner().s() * self.as_inner().s(),
-(operand.d() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.d() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.d() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.d() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.nx() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.nx() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO * operand.ny() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.ny() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO * operand.nx() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.nx() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.ny() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.ny() * self.as_inner().m() * self.as_inner().s()
+ operand.d() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.d() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.d() * self.as_inner().ps() * self.as_inner().ps()
+ operand.d() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Line<T>>> for Motor<T> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.e1em() * self.e1em())
+ -(operand.as_inner().nx() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().nx() * self.e2em() * self.e2em())
+ -(operand.as_inner().nx() * self.e2ep() * self.e2ep())
+ -T::TWO * operand.as_inner().ny() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().ny() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().d() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().d() * self.e1ep() * self.s()
+ T::TWO * operand.as_inner().d() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().d() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().ny() * self.e1em() * self.ps()
+ T::TWO * operand.as_inner().ny() * self.e1ep() * self.m()
+ operand.as_inner().nx() * self.epem() * self.epem()
+ operand.as_inner().nx() * self.m() * self.m()
+ operand.as_inner().nx() * self.ps() * self.ps()
+ operand.as_inner().nx() * self.s() * self.s(),
-(operand.as_inner().ny() * self.e1em() * self.e1em())
+ -(operand.as_inner().ny() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().ny() * self.epem() * self.epem())
+ -(operand.as_inner().ny() * self.m() * self.m())
+ -T::TWO * operand.as_inner().d() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().d() * self.m() * self.s()
+ -T::TWO * operand.as_inner().nx() * self.e1em() * self.ps()
+ -T::TWO * operand.as_inner().nx() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().d() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().d() * self.epem() * self.ps()
+ T::TWO * operand.as_inner().nx() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().nx() * self.e2ep() * self.s()
+ operand.as_inner().ny() * self.e1ep() * self.e1ep()
+ operand.as_inner().ny() * self.e2em() * self.e2em()
+ operand.as_inner().ny() * self.ps() * self.ps()
+ operand.as_inner().ny() * self.s() * self.s(),
-(operand.as_inner().d() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().d() * self.e2em() * self.e2em())
+ -(operand.as_inner().d() * self.epem() * self.epem())
+ -(operand.as_inner().d() * self.m() * self.m())
+ -T::TWO * operand.as_inner().nx() * self.e1ep() * self.s()
+ -T::TWO * operand.as_inner().nx() * self.e2em() * self.ps()
+ -T::TWO * operand.as_inner().ny() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().ny() * self.epem() * self.ps()
+ T::TWO * operand.as_inner().nx() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().nx() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().ny() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().ny() * self.m() * self.s()
+ operand.as_inner().d() * self.e1em() * self.e1em()
+ operand.as_inner().d() * self.e2ep() * self.e2ep()
+ operand.as_inner().d() * self.ps() * self.ps()
+ operand.as_inner().d() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Line<T>>> for Unit<Motor<T>> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().nx() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().nx() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().nx() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO
* operand.as_inner().ny()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().ny() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().d() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.as_inner().d() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().d() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.as_inner().d() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().ny() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.as_inner().ny() * self.as_inner().e1ep() * self.as_inner().m()
+ operand.as_inner().nx() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().nx() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().nx() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().nx() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().ny() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ny() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().ny() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().ny() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().d()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO * operand.as_inner().d() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO * operand.as_inner().nx() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO
* operand.as_inner().nx()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().d() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.as_inner().d() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO * operand.as_inner().nx() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().nx() * self.as_inner().e2ep() * self.as_inner().s()
+ operand.as_inner().ny() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().ny() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().ny() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().ny() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().d() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().d() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().d() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().d() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.as_inner().nx() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.as_inner().nx() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO
* operand.as_inner().ny()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO * operand.as_inner().ny() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().nx()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().nx() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().ny()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().ny() * self.as_inner().m() * self.as_inner().s()
+ operand.as_inner().d() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().d() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().d() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().d() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Antisandwich product: [`Motor`] x [`Motor`] x antirev([`Motor`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Motor<T>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(self.e1em() * operand.e1em() * self.s()) - self.e1em() * operand.e1ep() * self.epem()
+ self.e1em() * operand.e2em() * self.m()
+ self.e1em() * operand.e2ep() * self.ps()
+ self.e1em() * operand.epem() * self.e1ep()
- self.e1em() * operand.m() * self.e2em()
- self.e1em() * operand.ps() * self.e2ep()
+ self.e1em() * operand.s() * self.e1em()
+ self.e1ep() * operand.e1em() * self.epem()
+ self.e1ep() * operand.e1ep() * self.s()
- self.e1ep() * operand.e2em() * self.ps()
- self.e1ep() * operand.e2ep() * self.m()
- self.e1ep() * operand.epem() * self.e1em()
+ self.e1ep() * operand.m() * self.e2ep()
+ self.e1ep() * operand.ps() * self.e2em()
- self.e1ep() * operand.s() * self.e1ep()
- self.e2em() * operand.e1em() * self.m()
- self.e2em() * operand.e1ep() * self.ps()
- self.e2em() * operand.e2em() * self.s()
- self.e2em() * operand.e2ep() * self.epem()
+ self.e2em() * operand.epem() * self.e2ep()
+ self.e2em() * operand.m() * self.e1em()
+ self.e2em() * operand.ps() * self.e1ep()
+ self.e2em() * operand.s() * self.e2em()
+ self.e2ep() * operand.e1em() * self.ps()
+ self.e2ep() * operand.e1ep() * self.m()
+ self.e2ep() * operand.e2em() * self.epem()
+ self.e2ep() * operand.e2ep() * self.s()
- self.e2ep() * operand.epem() * self.e2em()
- self.e2ep() * operand.m() * self.e1ep()
- self.e2ep() * operand.ps() * self.e1em()
- self.e2ep() * operand.s() * self.e2ep()
- self.epem() * operand.e1em() * self.e1ep()
+ self.epem() * operand.e1ep() * self.e1em()
- self.epem() * operand.e2em() * self.e2ep()
+ self.epem() * operand.e2ep() * self.e2em()
- self.epem() * operand.epem() * self.s()
+ self.epem() * operand.m() * self.ps()
- self.epem() * operand.ps() * self.m()
+ self.epem() * operand.s() * self.epem()
+ self.m() * operand.e1em() * self.e2em()
- self.m() * operand.e1ep() * self.e2ep()
- self.m() * operand.e2em() * self.e1em()
+ self.m() * operand.e2ep() * self.e1ep()
+ self.m() * operand.epem() * self.ps()
+ self.m() * operand.m() * self.s()
- self.m() * operand.ps() * self.epem()
- self.m() * operand.s() * self.m()
- self.ps() * operand.e1em() * self.e2ep()
+ self.ps() * operand.e1ep() * self.e2em()
+ self.ps() * operand.e2em() * self.e1ep()
- self.ps() * operand.e2ep() * self.e1em()
- self.ps() * operand.epem() * self.m()
- self.ps() * operand.m() * self.epem()
+ self.ps() * operand.ps() * self.s()
+ self.ps() * operand.s() * self.ps()
+ self.s() * operand.e1em() * self.e1em()
- self.s() * operand.e1ep() * self.e1ep()
+ self.s() * operand.e2em() * self.e2em()
- self.s() * operand.e2ep() * self.e2ep()
+ self.s() * operand.epem() * self.epem()
- self.s() * operand.m() * self.m()
+ self.s() * operand.ps() * self.ps()
- self.s() * operand.s() * self.s(),
self.e1em() * operand.e1em() * self.m()
+ self.e1em() * operand.e1ep() * self.ps()
+ self.e1em() * operand.e2em() * self.s()
+ self.e1em() * operand.e2ep() * self.epem()
- self.e1em() * operand.epem() * self.e2ep()
- self.e1em() * operand.m() * self.e1em()
- self.e1em() * operand.ps() * self.e1ep()
- self.e1em() * operand.s() * self.e2em()
- self.e1ep() * operand.e1em() * self.ps()
- self.e1ep() * operand.e1ep() * self.m()
- self.e1ep() * operand.e2em() * self.epem()
- self.e1ep() * operand.e2ep() * self.s()
+ self.e1ep() * operand.epem() * self.e2em()
+ self.e1ep() * operand.m() * self.e1ep()
+ self.e1ep() * operand.ps() * self.e1em()
+ self.e1ep() * operand.s() * self.e2ep()
- self.e2em() * operand.e1em() * self.s()
- self.e2em() * operand.e1ep() * self.epem()
+ self.e2em() * operand.e2em() * self.m()
+ self.e2em() * operand.e2ep() * self.ps()
+ self.e2em() * operand.epem() * self.e1ep()
- self.e2em() * operand.m() * self.e2em()
- self.e2em() * operand.ps() * self.e2ep()
+ self.e2em() * operand.s() * self.e1em()
+ self.e2ep() * operand.e1em() * self.epem()
+ self.e2ep() * operand.e1ep() * self.s()
- self.e2ep() * operand.e2em() * self.ps()
- self.e2ep() * operand.e2ep() * self.m()
- self.e2ep() * operand.epem() * self.e1em()
+ self.e2ep() * operand.m() * self.e2ep()
+ self.e2ep() * operand.ps() * self.e2em()
- self.e2ep() * operand.s() * self.e1ep()
+ self.epem() * operand.e1em() * self.e2ep()
- self.epem() * operand.e1ep() * self.e2em()
- self.epem() * operand.e2em() * self.e1ep()
+ self.epem() * operand.e2ep() * self.e1em()
+ self.epem() * operand.epem() * self.m()
+ self.epem() * operand.m() * self.epem()
- self.epem() * operand.ps() * self.s()
- self.epem() * operand.s() * self.ps()
+ self.m() * operand.e1em() * self.e1em()
- self.m() * operand.e1ep() * self.e1ep()
+ self.m() * operand.e2em() * self.e2em()
- self.m() * operand.e2ep() * self.e2ep()
+ self.m() * operand.epem() * self.epem()
- self.m() * operand.m() * self.m()
+ self.m() * operand.ps() * self.ps()
- self.m() * operand.s() * self.s()
- self.ps() * operand.e1em() * self.e1ep()
+ self.ps() * operand.e1ep() * self.e1em()
- self.ps() * operand.e2em() * self.e2ep()
+ self.ps() * operand.e2ep() * self.e2em()
- self.ps() * operand.epem() * self.s()
+ self.ps() * operand.m() * self.ps()
- self.ps() * operand.ps() * self.m()
+ self.ps() * operand.s() * self.epem()
- self.s() * operand.e1em() * self.e2em()
+ self.s() * operand.e1ep() * self.e2ep()
+ self.s() * operand.e2em() * self.e1em()
- self.s() * operand.e2ep() * self.e1ep()
- self.s() * operand.epem() * self.ps()
- self.s() * operand.m() * self.s()
+ self.s() * operand.ps() * self.epem()
+ self.s() * operand.s() * self.m(),
self.e1em() * operand.e1em() * self.e1ep() - self.e1em() * operand.e1ep() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2ep()
- self.e1em() * operand.e2ep() * self.e2em()
+ self.e1em() * operand.epem() * self.s()
- self.e1em() * operand.m() * self.ps()
+ self.e1em() * operand.ps() * self.m()
- self.e1em() * operand.s() * self.epem()
+ self.e1ep() * operand.e1em() * self.e1em()
- self.e1ep() * operand.e1ep() * self.e1ep()
+ self.e1ep() * operand.e2em() * self.e2em()
- self.e1ep() * operand.e2ep() * self.e2ep()
+ self.e1ep() * operand.epem() * self.epem()
- self.e1ep() * operand.m() * self.m()
+ self.e1ep() * operand.ps() * self.ps()
- self.e1ep() * operand.s() * self.s()
- self.e2em() * operand.e1em() * self.e2ep()
+ self.e2em() * operand.e1ep() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1ep()
- self.e2em() * operand.e2ep() * self.e1em()
- self.e2em() * operand.epem() * self.m()
- self.e2em() * operand.m() * self.epem()
+ self.e2em() * operand.ps() * self.s()
+ self.e2em() * operand.s() * self.ps()
- self.e2ep() * operand.e1em() * self.e2em()
+ self.e2ep() * operand.e1ep() * self.e2ep()
+ self.e2ep() * operand.e2em() * self.e1em()
- self.e2ep() * operand.e2ep() * self.e1ep()
- self.e2ep() * operand.epem() * self.ps()
- self.e2ep() * operand.m() * self.s()
+ self.e2ep() * operand.ps() * self.epem()
+ self.e2ep() * operand.s() * self.m()
- self.epem() * operand.e1em() * self.s()
- self.epem() * operand.e1ep() * self.epem()
+ self.epem() * operand.e2em() * self.m()
+ self.epem() * operand.e2ep() * self.ps()
+ self.epem() * operand.epem() * self.e1ep()
- self.epem() * operand.m() * self.e2em()
- self.epem() * operand.ps() * self.e2ep()
+ self.epem() * operand.s() * self.e1em()
+ self.m() * operand.e1em() * self.ps()
+ self.m() * operand.e1ep() * self.m()
+ self.m() * operand.e2em() * self.epem()
+ self.m() * operand.e2ep() * self.s()
- self.m() * operand.epem() * self.e2em()
- self.m() * operand.m() * self.e1ep()
- self.m() * operand.ps() * self.e1em()
- self.m() * operand.s() * self.e2ep()
+ self.ps() * operand.e1em() * self.m()
+ self.ps() * operand.e1ep() * self.ps()
+ self.ps() * operand.e2em() * self.s()
+ self.ps() * operand.e2ep() * self.epem()
- self.ps() * operand.epem() * self.e2ep()
- self.ps() * operand.m() * self.e1em()
- self.ps() * operand.ps() * self.e1ep()
- self.ps() * operand.s() * self.e2em()
- self.s() * operand.e1em() * self.epem()
- self.s() * operand.e1ep() * self.s()
+ self.s() * operand.e2em() * self.ps()
+ self.s() * operand.e2ep() * self.m()
+ self.s() * operand.epem() * self.e1em()
- self.s() * operand.m() * self.e2ep()
- self.s() * operand.ps() * self.e2em()
+ self.s() * operand.s() * self.e1ep(),
self.e1em() * operand.e1em() * self.e2ep()
- self.e1em() * operand.e1ep() * self.e2em()
- self.e1em() * operand.e2em() * self.e1ep()
+ self.e1em() * operand.e2ep() * self.e1em()
+ self.e1em() * operand.epem() * self.m()
+ self.e1em() * operand.m() * self.epem()
- self.e1em() * operand.ps() * self.s()
- self.e1em() * operand.s() * self.ps()
+ self.e1ep() * operand.e1em() * self.e2em()
- self.e1ep() * operand.e1ep() * self.e2ep()
- self.e1ep() * operand.e2em() * self.e1em()
+ self.e1ep() * operand.e2ep() * self.e1ep()
+ self.e1ep() * operand.epem() * self.ps()
+ self.e1ep() * operand.m() * self.s()
- self.e1ep() * operand.ps() * self.epem()
- self.e1ep() * operand.s() * self.m()
+ self.e2em() * operand.e1em() * self.e1ep()
- self.e2em() * operand.e1ep() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2ep()
- self.e2em() * operand.e2ep() * self.e2em()
+ self.e2em() * operand.epem() * self.s()
- self.e2em() * operand.m() * self.ps()
+ self.e2em() * operand.ps() * self.m()
- self.e2em() * operand.s() * self.epem()
+ self.e2ep() * operand.e1em() * self.e1em()
- self.e2ep() * operand.e1ep() * self.e1ep()
+ self.e2ep() * operand.e2em() * self.e2em()
- self.e2ep() * operand.e2ep() * self.e2ep()
+ self.e2ep() * operand.epem() * self.epem()
- self.e2ep() * operand.m() * self.m()
+ self.e2ep() * operand.ps() * self.ps()
- self.e2ep() * operand.s() * self.s()
- self.epem() * operand.e1em() * self.m()
- self.epem() * operand.e1ep() * self.ps()
- self.epem() * operand.e2em() * self.s()
- self.epem() * operand.e2ep() * self.epem()
+ self.epem() * operand.epem() * self.e2ep()
+ self.epem() * operand.m() * self.e1em()
+ self.epem() * operand.ps() * self.e1ep()
+ self.epem() * operand.s() * self.e2em()
- self.m() * operand.e1em() * self.epem()
- self.m() * operand.e1ep() * self.s()
+ self.m() * operand.e2em() * self.ps()
+ self.m() * operand.e2ep() * self.m()
+ self.m() * operand.epem() * self.e1em()
- self.m() * operand.m() * self.e2ep()
- self.m() * operand.ps() * self.e2em()
+ self.m() * operand.s() * self.e1ep()
- self.ps() * operand.e1em() * self.s()
- self.ps() * operand.e1ep() * self.epem()
+ self.ps() * operand.e2em() * self.m()
+ self.ps() * operand.e2ep() * self.ps()
+ self.ps() * operand.epem() * self.e1ep()
- self.ps() * operand.m() * self.e2em()
- self.ps() * operand.ps() * self.e2ep()
+ self.ps() * operand.s() * self.e1em()
- self.s() * operand.e1em() * self.ps()
- self.s() * operand.e1ep() * self.m()
- self.s() * operand.e2em() * self.epem()
- self.s() * operand.e2ep() * self.s()
+ self.s() * operand.epem() * self.e2em()
+ self.s() * operand.m() * self.e1ep()
+ self.s() * operand.ps() * self.e1em()
+ self.s() * operand.s() * self.e2ep(),
self.e1em() * operand.e1em() * self.e1em() - self.e1em() * operand.e1ep() * self.e1ep()
+ self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.e2ep() * self.e2ep()
+ self.e1em() * operand.epem() * self.epem()
- self.e1em() * operand.m() * self.m()
+ self.e1em() * operand.ps() * self.ps()
- self.e1em() * operand.s() * self.s()
+ self.e1ep() * operand.e1em() * self.e1ep()
- self.e1ep() * operand.e1ep() * self.e1em()
+ self.e1ep() * operand.e2em() * self.e2ep()
- self.e1ep() * operand.e2ep() * self.e2em()
+ self.e1ep() * operand.epem() * self.s()
- self.e1ep() * operand.m() * self.ps()
+ self.e1ep() * operand.ps() * self.m()
- self.e1ep() * operand.s() * self.epem()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e1ep() * self.e2ep()
+ self.e2em() * operand.e2em() * self.e1em()
- self.e2em() * operand.e2ep() * self.e1ep()
- self.e2em() * operand.epem() * self.ps()
- self.e2em() * operand.m() * self.s()
+ self.e2em() * operand.ps() * self.epem()
+ self.e2em() * operand.s() * self.m()
- self.e2ep() * operand.e1em() * self.e2ep()
+ self.e2ep() * operand.e1ep() * self.e2em()
+ self.e2ep() * operand.e2em() * self.e1ep()
- self.e2ep() * operand.e2ep() * self.e1em()
- self.e2ep() * operand.epem() * self.m()
- self.e2ep() * operand.m() * self.epem()
+ self.e2ep() * operand.ps() * self.s()
+ self.e2ep() * operand.s() * self.ps()
- self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.e1ep() * self.s()
+ self.epem() * operand.e2em() * self.ps()
+ self.epem() * operand.e2ep() * self.m()
+ self.epem() * operand.epem() * self.e1em()
- self.epem() * operand.m() * self.e2ep()
- self.epem() * operand.ps() * self.e2em()
+ self.epem() * operand.s() * self.e1ep()
+ self.m() * operand.e1em() * self.m()
+ self.m() * operand.e1ep() * self.ps()
+ self.m() * operand.e2em() * self.s()
+ self.m() * operand.e2ep() * self.epem()
- self.m() * operand.epem() * self.e2ep()
- self.m() * operand.m() * self.e1em()
- self.m() * operand.ps() * self.e1ep()
- self.m() * operand.s() * self.e2em()
+ self.ps() * operand.e1em() * self.ps()
+ self.ps() * operand.e1ep() * self.m()
+ self.ps() * operand.e2em() * self.epem()
+ self.ps() * operand.e2ep() * self.s()
- self.ps() * operand.epem() * self.e2em()
- self.ps() * operand.m() * self.e1ep()
- self.ps() * operand.ps() * self.e1em()
- self.ps() * operand.s() * self.e2ep()
- self.s() * operand.e1em() * self.s()
- self.s() * operand.e1ep() * self.epem()
+ self.s() * operand.e2em() * self.m()
+ self.s() * operand.e2ep() * self.ps()
+ self.s() * operand.epem() * self.e1ep()
- self.s() * operand.m() * self.e2em()
- self.s() * operand.ps() * self.e2ep()
+ self.s() * operand.s() * self.e1em(),
self.e1em() * operand.e1em() * self.e2em()
- self.e1em() * operand.e1ep() * self.e2ep()
- self.e1em() * operand.e2em() * self.e1em()
+ self.e1em() * operand.e2ep() * self.e1ep()
+ self.e1em() * operand.epem() * self.ps()
+ self.e1em() * operand.m() * self.s()
- self.e1em() * operand.ps() * self.epem()
- self.e1em() * operand.s() * self.m()
+ self.e1ep() * operand.e1em() * self.e2ep()
- self.e1ep() * operand.e1ep() * self.e2em()
- self.e1ep() * operand.e2em() * self.e1ep()
+ self.e1ep() * operand.e2ep() * self.e1em()
+ self.e1ep() * operand.epem() * self.m()
+ self.e1ep() * operand.m() * self.epem()
- self.e1ep() * operand.ps() * self.s()
- self.e1ep() * operand.s() * self.ps()
+ self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e1ep() * self.e1ep()
+ self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.e2ep() * self.e2ep()
+ self.e2em() * operand.epem() * self.epem()
- self.e2em() * operand.m() * self.m()
+ self.e2em() * operand.ps() * self.ps()
- self.e2em() * operand.s() * self.s()
+ self.e2ep() * operand.e1em() * self.e1ep()
- self.e2ep() * operand.e1ep() * self.e1em()
+ self.e2ep() * operand.e2em() * self.e2ep()
- self.e2ep() * operand.e2ep() * self.e2em()
+ self.e2ep() * operand.epem() * self.s()
- self.e2ep() * operand.m() * self.ps()
+ self.e2ep() * operand.ps() * self.m()
- self.e2ep() * operand.s() * self.epem()
- self.epem() * operand.e1em() * self.ps()
- self.epem() * operand.e1ep() * self.m()
- self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.e2ep() * self.s()
+ self.epem() * operand.epem() * self.e2em()
+ self.epem() * operand.m() * self.e1ep()
+ self.epem() * operand.ps() * self.e1em()
+ self.epem() * operand.s() * self.e2ep()
- self.m() * operand.e1em() * self.s()
- self.m() * operand.e1ep() * self.epem()
+ self.m() * operand.e2em() * self.m()
+ self.m() * operand.e2ep() * self.ps()
+ self.m() * operand.epem() * self.e1ep()
- self.m() * operand.m() * self.e2em()
- self.m() * operand.ps() * self.e2ep()
+ self.m() * operand.s() * self.e1em()
- self.ps() * operand.e1em() * self.epem()
- self.ps() * operand.e1ep() * self.s()
+ self.ps() * operand.e2em() * self.ps()
+ self.ps() * operand.e2ep() * self.m()
+ self.ps() * operand.epem() * self.e1em()
- self.ps() * operand.m() * self.e2ep()
- self.ps() * operand.ps() * self.e2em()
+ self.ps() * operand.s() * self.e1ep()
- self.s() * operand.e1em() * self.m()
- self.s() * operand.e1ep() * self.ps()
- self.s() * operand.e2em() * self.s()
- self.s() * operand.e2ep() * self.epem()
+ self.s() * operand.epem() * self.e2ep()
+ self.s() * operand.m() * self.e1em()
+ self.s() * operand.ps() * self.e1ep()
+ self.s() * operand.s() * self.e2em(),
self.e1em() * operand.e1em() * self.epem() + self.e1em() * operand.e1ep() * self.s()
- self.e1em() * operand.e2em() * self.ps()
- self.e1em() * operand.e2ep() * self.m()
- self.e1em() * operand.epem() * self.e1em()
+ self.e1em() * operand.m() * self.e2ep()
+ self.e1em() * operand.ps() * self.e2em()
- self.e1em() * operand.s() * self.e1ep()
- self.e1ep() * operand.e1em() * self.s()
- self.e1ep() * operand.e1ep() * self.epem()
+ self.e1ep() * operand.e2em() * self.m()
+ self.e1ep() * operand.e2ep() * self.ps()
+ self.e1ep() * operand.epem() * self.e1ep()
- self.e1ep() * operand.m() * self.e2em()
- self.e1ep() * operand.ps() * self.e2ep()
+ self.e1ep() * operand.s() * self.e1em()
+ self.e2em() * operand.e1em() * self.ps()
+ self.e2em() * operand.e1ep() * self.m()
+ self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.e2ep() * self.s()
- self.e2em() * operand.epem() * self.e2em()
- self.e2em() * operand.m() * self.e1ep()
- self.e2em() * operand.ps() * self.e1em()
- self.e2em() * operand.s() * self.e2ep()
- self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.e1ep() * self.ps()
- self.e2ep() * operand.e2em() * self.s()
- self.e2ep() * operand.e2ep() * self.epem()
+ self.e2ep() * operand.epem() * self.e2ep()
+ self.e2ep() * operand.m() * self.e1em()
+ self.e2ep() * operand.ps() * self.e1ep()
+ self.e2ep() * operand.s() * self.e2em()
+ self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e1ep() * self.e1ep()
+ self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.e2ep() * self.e2ep()
+ self.epem() * operand.epem() * self.epem()
- self.epem() * operand.m() * self.m()
+ self.epem() * operand.ps() * self.ps()
- self.epem() * operand.s() * self.s()
- self.m() * operand.e1em() * self.e2ep()
+ self.m() * operand.e1ep() * self.e2em()
+ self.m() * operand.e2em() * self.e1ep()
- self.m() * operand.e2ep() * self.e1em()
- self.m() * operand.epem() * self.m()
- self.m() * operand.m() * self.epem()
+ self.m() * operand.ps() * self.s()
+ self.m() * operand.s() * self.ps()
+ self.ps() * operand.e1em() * self.e2em()
- self.ps() * operand.e1ep() * self.e2ep()
- self.ps() * operand.e2em() * self.e1em()
+ self.ps() * operand.e2ep() * self.e1ep()
+ self.ps() * operand.epem() * self.ps()
+ self.ps() * operand.m() * self.s()
- self.ps() * operand.ps() * self.epem()
- self.ps() * operand.s() * self.m()
- self.s() * operand.e1em() * self.e1ep()
+ self.s() * operand.e1ep() * self.e1em()
- self.s() * operand.e2em() * self.e2ep()
+ self.s() * operand.e2ep() * self.e2em()
- self.s() * operand.epem() * self.s()
+ self.s() * operand.m() * self.ps()
- self.s() * operand.ps() * self.m()
+ self.s() * operand.s() * self.epem(),
-(self.e1em() * operand.e1em() * self.ps())
- self.e1em() * operand.e1ep() * self.m()
- self.e1em() * operand.e2em() * self.epem()
- self.e1em() * operand.e2ep() * self.s()
+ self.e1em() * operand.epem() * self.e2em()
+ self.e1em() * operand.m() * self.e1ep()
+ self.e1em() * operand.ps() * self.e1em()
+ self.e1em() * operand.s() * self.e2ep()
+ self.e1ep() * operand.e1em() * self.m()
+ self.e1ep() * operand.e1ep() * self.ps()
+ self.e1ep() * operand.e2em() * self.s()
+ self.e1ep() * operand.e2ep() * self.epem()
- self.e1ep() * operand.epem() * self.e2ep()
- self.e1ep() * operand.m() * self.e1em()
- self.e1ep() * operand.ps() * self.e1ep()
- self.e1ep() * operand.s() * self.e2em()
+ self.e2em() * operand.e1em() * self.epem()
+ self.e2em() * operand.e1ep() * self.s()
- self.e2em() * operand.e2em() * self.ps()
- self.e2em() * operand.e2ep() * self.m()
- self.e2em() * operand.epem() * self.e1em()
+ self.e2em() * operand.m() * self.e2ep()
+ self.e2em() * operand.ps() * self.e2em()
- self.e2em() * operand.s() * self.e1ep()
- self.e2ep() * operand.e1em() * self.s()
- self.e2ep() * operand.e1ep() * self.epem()
+ self.e2ep() * operand.e2em() * self.m()
+ self.e2ep() * operand.e2ep() * self.ps()
+ self.e2ep() * operand.epem() * self.e1ep()
- self.e2ep() * operand.m() * self.e2em()
- self.e2ep() * operand.ps() * self.e2ep()
+ self.e2ep() * operand.s() * self.e1em()
- self.epem() * operand.e1em() * self.e2em()
+ self.epem() * operand.e1ep() * self.e2ep()
+ self.epem() * operand.e2em() * self.e1em()
- self.epem() * operand.e2ep() * self.e1ep()
- self.epem() * operand.epem() * self.ps()
- self.epem() * operand.m() * self.s()
+ self.epem() * operand.ps() * self.epem()
+ self.epem() * operand.s() * self.m()
- self.m() * operand.e1em() * self.e1ep()
+ self.m() * operand.e1ep() * self.e1em()
- self.m() * operand.e2em() * self.e2ep()
+ self.m() * operand.e2ep() * self.e2em()
- self.m() * operand.epem() * self.s()
+ self.m() * operand.m() * self.ps()
- self.m() * operand.ps() * self.m()
+ self.m() * operand.s() * self.epem()
+ self.ps() * operand.e1em() * self.e1em()
- self.ps() * operand.e1ep() * self.e1ep()
+ self.ps() * operand.e2em() * self.e2em()
- self.ps() * operand.e2ep() * self.e2ep()
+ self.ps() * operand.epem() * self.epem()
- self.ps() * operand.m() * self.m()
+ self.ps() * operand.ps() * self.ps()
- self.ps() * operand.s() * self.s()
+ self.s() * operand.e1em() * self.e2ep()
- self.s() * operand.e1ep() * self.e2em()
- self.s() * operand.e2em() * self.e1ep()
+ self.s() * operand.e2ep() * self.e1em()
+ self.s() * operand.epem() * self.m()
+ self.s() * operand.m() * self.epem()
- self.s() * operand.ps() * self.s()
- self.s() * operand.s() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Motor<T>> for Unit<Motor<T>> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(operand.s() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.s() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.s() * self.as_inner().m() * self.as_inner().m())
+ -(operand.s() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO * operand.ps() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.ps() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.ps() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.ps() * self.as_inner().ps() * self.as_inner().s()
+ operand.s() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.s() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.s() * self.as_inner().epem() * self.as_inner().epem()
+ operand.s() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.m() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.m() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.m() * self.as_inner().m() * self.as_inner().m())
+ -(operand.m() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().ps()
+ -T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().s()
+ -T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.e2em() * self.as_inner().e2ep() * self.as_inner().ps()
+ -T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.e2ep() * self.as_inner().e2ep() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.epem() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.e1ep() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e2ep() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.epem() * self.as_inner().epem() * self.as_inner().m()
+ operand.m() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.m() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.m() * self.as_inner().epem() * self.as_inner().epem()
+ operand.m() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e1ep() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e1ep() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().ps()
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.e1em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e2em() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO * operand.e2ep() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO * operand.e2ep() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().epem()
+ operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e1ep() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e1ep() * self.as_inner().m() * self.as_inner().m()
+ operand.e1ep() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e2ep() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e2ep() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().m()
+ -T::TWO * operand.e1em() * self.as_inner().ps() * self.as_inner().s()
+ -T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.e1ep() * self.as_inner().epem() * self.as_inner().ps()
+ -T::TWO * operand.e1ep() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.e2em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().s()
+ operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e2ep() * self.as_inner().m() * self.as_inner().m()
+ operand.e2ep() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e1em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e1em() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e1em() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.e1ep() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().m()
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().ps()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().s()
+ -T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.e1ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO * operand.e2em() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.e2ep() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e2ep() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().s()
+ operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e1em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e1em() * self.as_inner().m() * self.as_inner().m()
+ operand.e1em() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e2em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e2em() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e2em() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().ps()
+ -T::TWO * operand.e1em() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.e1ep() * self.as_inner().epem() * self.as_inner().m()
+ -T::TWO * operand.e1ep() * self.as_inner().ps() * self.as_inner().s()
+ -T::TWO * operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.e2ep() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().ps()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.e2ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().epem()
+ operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e2em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e2em() * self.as_inner().m() * self.as_inner().m()
+ operand.e2em() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.epem() * self.as_inner().m() * self.as_inner().m())
+ -(operand.epem() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ -T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.e1ep() * self.as_inner().e2ep() * self.as_inner().ps()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.e2em() * self.as_inner().e2ep() * self.as_inner().s()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.e2ep() * self.as_inner().e2ep() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.m() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO * operand.e2ep() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.m() * self.as_inner().ps() * self.as_inner().s()
+ operand.epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.epem() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.epem() * self.as_inner().epem() * self.as_inner().epem()
+ operand.epem() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.ps() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.ps() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.ps() * self.as_inner().m() * self.as_inner().m())
+ -(operand.ps() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO * operand.s() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.s() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO * operand.s() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.s() * self.as_inner().epem() * self.as_inner().m()
+ operand.ps() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.ps() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.ps() * self.as_inner().epem() * self.as_inner().epem()
+ operand.ps() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Motor<T>>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().s() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().s() * self.m() * self.m())
+ -(operand.as_inner().s() * self.s() * self.s())
+ -T::TWO * operand.as_inner().ps() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().ps() * self.epem() * self.m()
+ T::TWO * operand.as_inner().ps() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().ps() * self.ps() * self.s()
+ operand.as_inner().s() * self.e1em() * self.e1em()
+ operand.as_inner().s() * self.e2em() * self.e2em()
+ operand.as_inner().s() * self.epem() * self.epem()
+ operand.as_inner().s() * self.ps() * self.ps(),
-(operand.as_inner().m() * self.e1em() * self.e1em())
+ -(operand.as_inner().m() * self.e2em() * self.e2em())
+ -(operand.as_inner().m() * self.m() * self.m())
+ -(operand.as_inner().m() * self.s() * self.s())
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.ps()
+ -T::TWO * operand.as_inner().e1em() * self.e2em() * self.s()
+ -T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().e1ep() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().e2em() * self.e2ep() * self.ps()
+ -T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.s()
+ -T::TWO * operand.as_inner().e2ep() * self.e2ep() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().epem() * self.ps() * self.s()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().e1em() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.ps()
+ T::TWO * operand.as_inner().e1ep() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().e2em() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e2ep() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().epem() * self.epem() * self.m()
+ operand.as_inner().m() * self.e1ep() * self.e1ep()
+ operand.as_inner().m() * self.e2ep() * self.e2ep()
+ operand.as_inner().m() * self.epem() * self.epem()
+ operand.as_inner().m() * self.ps() * self.ps(),
-(operand.as_inner().e1ep() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1ep() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e1ep() * self.epem() * self.epem())
+ -(operand.as_inner().e1ep() * self.s() * self.s())
+ -T::TWO * operand.as_inner().e1em() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().e1em() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e2ep() * self.ps()
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.ps()
+ -T::TWO * operand.as_inner().m() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().e1em() * self.m() * self.ps()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().e2em() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e2em() * self.ps() * self.s()
+ T::TWO * operand.as_inner().e2ep() * self.epem() * self.ps()
+ T::TWO * operand.as_inner().e2ep() * self.m() * self.s()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.epem()
+ operand.as_inner().e1ep() * self.e2em() * self.e2em()
+ operand.as_inner().e1ep() * self.e2ep() * self.e2ep()
+ operand.as_inner().e1ep() * self.m() * self.m()
+ operand.as_inner().e1ep() * self.ps() * self.ps(),
-(operand.as_inner().e2ep() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2ep() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e2ep() * self.epem() * self.epem())
+ -(operand.as_inner().e2ep() * self.s() * self.s())
+ -T::TWO * operand.as_inner().e1em() * self.epem() * self.m()
+ -T::TWO * operand.as_inner().e1em() * self.ps() * self.s()
+ -T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().e1ep() * self.epem() * self.ps()
+ -T::TWO * operand.as_inner().e1ep() * self.m() * self.s()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().e2em() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.ps()
+ -T::TWO * operand.as_inner().m() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().e2em() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().e2em() * self.m() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e2em() * self.s()
+ T::TWO * operand.as_inner().epem() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().m() * self.e1ep() * self.s()
+ operand.as_inner().e2ep() * self.e1em() * self.e1em()
+ operand.as_inner().e2ep() * self.e1ep() * self.e1ep()
+ operand.as_inner().e2ep() * self.m() * self.m()
+ operand.as_inner().e2ep() * self.ps() * self.ps(),
-(operand.as_inner().e1em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e1em() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e1em() * self.epem() * self.epem())
+ -(operand.as_inner().e1em() * self.s() * self.s())
+ -T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().e1ep() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.ps()
+ -T::TWO * operand.as_inner().epem() * self.e2ep() * self.m()
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().m() * self.e1ep() * self.ps()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.s()
+ -T::TWO * operand.as_inner().m() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().e1ep() * self.m() * self.ps()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e2em() * self.epem() * self.ps()
+ T::TWO * operand.as_inner().e2em() * self.m() * self.s()
+ T::TWO * operand.as_inner().e2ep() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e2ep() * self.ps() * self.s()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.s()
+ operand.as_inner().e1em() * self.e1em() * self.e1em()
+ operand.as_inner().e1em() * self.e1ep() * self.e1ep()
+ operand.as_inner().e1em() * self.m() * self.m()
+ operand.as_inner().e1em() * self.ps() * self.ps(),
-(operand.as_inner().e2em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e2em() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e2em() * self.epem() * self.epem())
+ -(operand.as_inner().e2em() * self.s() * self.s())
+ -T::TWO * operand.as_inner().e1em() * self.epem() * self.ps()
+ -T::TWO * operand.as_inner().e1em() * self.m() * self.s()
+ -T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().e1ep() * self.epem() * self.m()
+ -T::TWO * operand.as_inner().e1ep() * self.ps() * self.s()
+ -T::TWO * operand.as_inner().e2ep() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().e2ep() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().m() * self.e2ep() * self.ps()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().e2ep() * self.m() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().epem() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().m() * self.e1ep() * self.epem()
+ operand.as_inner().e2em() * self.e2em() * self.e2em()
+ operand.as_inner().e2em() * self.e2ep() * self.e2ep()
+ operand.as_inner().e2em() * self.m() * self.m()
+ operand.as_inner().e2em() * self.ps() * self.ps(),
-(operand.as_inner().epem() * self.e1em() * self.e1em())
+ -(operand.as_inner().epem() * self.e2em() * self.e2em())
+ -(operand.as_inner().epem() * self.m() * self.m())
+ -(operand.as_inner().epem() * self.s() * self.s())
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.s()
+ -T::TWO * operand.as_inner().e1em() * self.e2ep() * self.m()
+ -T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().e1ep() * self.e2ep() * self.ps()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.ps()
+ -T::TWO * operand.as_inner().e2em() * self.e2ep() * self.s()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().e2ep() * self.e2ep() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().m() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e1em() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().e1ep() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.ps()
+ T::TWO * operand.as_inner().e2ep() * self.e2em() * self.s()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().m() * self.ps() * self.s()
+ operand.as_inner().epem() * self.e1ep() * self.e1ep()
+ operand.as_inner().epem() * self.e2ep() * self.e2ep()
+ operand.as_inner().epem() * self.epem() * self.epem()
+ operand.as_inner().epem() * self.ps() * self.ps(),
-(operand.as_inner().ps() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().ps() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().ps() * self.m() * self.m())
+ -(operand.as_inner().ps() * self.s() * self.s())
+ -T::TWO * operand.as_inner().s() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().s() * self.ps() * self.s()
+ T::TWO * operand.as_inner().s() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().s() * self.epem() * self.m()
+ operand.as_inner().ps() * self.e1em() * self.e1em()
+ operand.as_inner().ps() * self.e2em() * self.e2em()
+ operand.as_inner().ps() * self.epem() * self.epem()
+ operand.as_inner().ps() * self.ps() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Motor<T>>> for Unit<Motor<T>> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().s() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().s() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().s() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO
* operand.as_inner().ps()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().ps() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO
* operand.as_inner().ps()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().ps() * self.as_inner().ps() * self.as_inner().s()
+ operand.as_inner().s() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().s() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().s() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().s() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().m() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().m() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2ep()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().epem() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2em()
* self.as_inner().ps()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().m()
+ operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().m() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().m() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.as_inner().e1ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e1ep() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e1ep() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().epem()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().epem()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ operand.as_inner().e1ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e1ep() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e1ep() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().e1ep() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.as_inner().e2ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e2ep() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e2ep() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().epem()
* self.as_inner().m()
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().ps() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().epem()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().epem()
* self.as_inner().s()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().s()
+ operand.as_inner().e2ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e2ep() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e2ep() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().e2ep() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e1em() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().epem()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().m()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().ps()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().epem()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().s()
+ operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e1em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().e1em() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e2em() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().epem()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().epem()
* self.as_inner().m()
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().ps() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().epem()
* self.as_inner().s()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().epem()
+ operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e2em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().e2em() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().epem() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().epem() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2ep()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2ep()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO * operand.as_inner().m() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.as_inner().m() * self.as_inner().ps() * self.as_inner().s()
+ operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().epem() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.as_inner().ps() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().ps() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().ps() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().ps() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO
* operand.as_inner().s()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO * operand.as_inner().s() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO * operand.as_inner().s() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.as_inner().s() * self.as_inner().epem() * self.as_inner().m()
+ operand.as_inner().ps() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().ps() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().ps() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().ps() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[doc = "Antisandwich product: [`Motor`] x [`PointPair`] x antirev([`Motor`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<PointPair<T>> for Motor<T> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
self.e1em() * operand.e1em() * self.m()
+ self.e1em() * operand.e1ep() * self.ps()
+ self.e1em() * operand.e2em() * self.s()
+ self.e1em() * operand.e2ep() * self.epem()
- self.e1em() * operand.epem() * self.e2ep()
- self.e1em() * operand.m() * self.e1em()
- self.e1ep() * operand.e1em() * self.ps()
- self.e1ep() * operand.e1ep() * self.m()
- self.e1ep() * operand.e2em() * self.epem()
- self.e1ep() * operand.e2ep() * self.s()
+ self.e1ep() * operand.epem() * self.e2em()
+ self.e1ep() * operand.m() * self.e1ep()
- self.e2em() * operand.e1em() * self.s()
- self.e2em() * operand.e1ep() * self.epem()
+ self.e2em() * operand.e2em() * self.m()
+ self.e2em() * operand.e2ep() * self.ps()
+ self.e2em() * operand.epem() * self.e1ep()
- self.e2em() * operand.m() * self.e2em()
+ self.e2ep() * operand.e1em() * self.epem()
+ self.e2ep() * operand.e1ep() * self.s()
- self.e2ep() * operand.e2em() * self.ps()
- self.e2ep() * operand.e2ep() * self.m()
- self.e2ep() * operand.epem() * self.e1em()
+ self.e2ep() * operand.m() * self.e2ep()
+ self.epem() * operand.e1em() * self.e2ep()
- self.epem() * operand.e1ep() * self.e2em()
- self.epem() * operand.e2em() * self.e1ep()
+ self.epem() * operand.e2ep() * self.e1em()
+ self.epem() * operand.epem() * self.m()
+ self.epem() * operand.m() * self.epem()
+ self.m() * operand.e1em() * self.e1em()
- self.m() * operand.e1ep() * self.e1ep()
+ self.m() * operand.e2em() * self.e2em()
- self.m() * operand.e2ep() * self.e2ep()
+ self.m() * operand.epem() * self.epem()
- self.m() * operand.m() * self.m()
- self.ps() * operand.e1em() * self.e1ep()
+ self.ps() * operand.e1ep() * self.e1em()
- self.ps() * operand.e2em() * self.e2ep()
+ self.ps() * operand.e2ep() * self.e2em()
- self.ps() * operand.epem() * self.s()
+ self.ps() * operand.m() * self.ps()
- self.s() * operand.e1em() * self.e2em()
+ self.s() * operand.e1ep() * self.e2ep()
+ self.s() * operand.e2em() * self.e1em()
- self.s() * operand.e2ep() * self.e1ep()
- self.s() * operand.epem() * self.ps()
- self.s() * operand.m() * self.s(),
self.e1em() * operand.e1em() * self.e1ep() - self.e1em() * operand.e1ep() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2ep()
- self.e1em() * operand.e2ep() * self.e2em()
+ self.e1em() * operand.epem() * self.s()
- self.e1em() * operand.m() * self.ps()
+ self.e1ep() * operand.e1em() * self.e1em()
- self.e1ep() * operand.e1ep() * self.e1ep()
+ self.e1ep() * operand.e2em() * self.e2em()
- self.e1ep() * operand.e2ep() * self.e2ep()
+ self.e1ep() * operand.epem() * self.epem()
- self.e1ep() * operand.m() * self.m()
- self.e2em() * operand.e1em() * self.e2ep()
+ self.e2em() * operand.e1ep() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1ep()
- self.e2em() * operand.e2ep() * self.e1em()
- self.e2em() * operand.epem() * self.m()
- self.e2em() * operand.m() * self.epem()
- self.e2ep() * operand.e1em() * self.e2em()
+ self.e2ep() * operand.e1ep() * self.e2ep()
+ self.e2ep() * operand.e2em() * self.e1em()
- self.e2ep() * operand.e2ep() * self.e1ep()
- self.e2ep() * operand.epem() * self.ps()
- self.e2ep() * operand.m() * self.s()
- self.epem() * operand.e1em() * self.s()
- self.epem() * operand.e1ep() * self.epem()
+ self.epem() * operand.e2em() * self.m()
+ self.epem() * operand.e2ep() * self.ps()
+ self.epem() * operand.epem() * self.e1ep()
- self.epem() * operand.m() * self.e2em()
+ self.m() * operand.e1em() * self.ps()
+ self.m() * operand.e1ep() * self.m()
+ self.m() * operand.e2em() * self.epem()
+ self.m() * operand.e2ep() * self.s()
- self.m() * operand.epem() * self.e2em()
- self.m() * operand.m() * self.e1ep()
+ self.ps() * operand.e1em() * self.m()
+ self.ps() * operand.e1ep() * self.ps()
+ self.ps() * operand.e2em() * self.s()
+ self.ps() * operand.e2ep() * self.epem()
- self.ps() * operand.epem() * self.e2ep()
- self.ps() * operand.m() * self.e1em()
- self.s() * operand.e1em() * self.epem()
- self.s() * operand.e1ep() * self.s()
+ self.s() * operand.e2em() * self.ps()
+ self.s() * operand.e2ep() * self.m()
+ self.s() * operand.epem() * self.e1em()
- self.s() * operand.m() * self.e2ep(),
self.e1em() * operand.e1em() * self.e2ep()
- self.e1em() * operand.e1ep() * self.e2em()
- self.e1em() * operand.e2em() * self.e1ep()
+ self.e1em() * operand.e2ep() * self.e1em()
+ self.e1em() * operand.epem() * self.m()
+ self.e1em() * operand.m() * self.epem()
+ self.e1ep() * operand.e1em() * self.e2em()
- self.e1ep() * operand.e1ep() * self.e2ep()
- self.e1ep() * operand.e2em() * self.e1em()
+ self.e1ep() * operand.e2ep() * self.e1ep()
+ self.e1ep() * operand.epem() * self.ps()
+ self.e1ep() * operand.m() * self.s()
+ self.e2em() * operand.e1em() * self.e1ep()
- self.e2em() * operand.e1ep() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2ep()
- self.e2em() * operand.e2ep() * self.e2em()
+ self.e2em() * operand.epem() * self.s()
- self.e2em() * operand.m() * self.ps()
+ self.e2ep() * operand.e1em() * self.e1em()
- self.e2ep() * operand.e1ep() * self.e1ep()
+ self.e2ep() * operand.e2em() * self.e2em()
- self.e2ep() * operand.e2ep() * self.e2ep()
+ self.e2ep() * operand.epem() * self.epem()
- self.e2ep() * operand.m() * self.m()
- self.epem() * operand.e1em() * self.m()
- self.epem() * operand.e1ep() * self.ps()
- self.epem() * operand.e2em() * self.s()
- self.epem() * operand.e2ep() * self.epem()
+ self.epem() * operand.epem() * self.e2ep()
+ self.epem() * operand.m() * self.e1em()
- self.m() * operand.e1em() * self.epem()
- self.m() * operand.e1ep() * self.s()
+ self.m() * operand.e2em() * self.ps()
+ self.m() * operand.e2ep() * self.m()
+ self.m() * operand.epem() * self.e1em()
- self.m() * operand.m() * self.e2ep()
- self.ps() * operand.e1em() * self.s()
- self.ps() * operand.e1ep() * self.epem()
+ self.ps() * operand.e2em() * self.m()
+ self.ps() * operand.e2ep() * self.ps()
+ self.ps() * operand.epem() * self.e1ep()
- self.ps() * operand.m() * self.e2em()
- self.s() * operand.e1em() * self.ps()
- self.s() * operand.e1ep() * self.m()
- self.s() * operand.e2em() * self.epem()
- self.s() * operand.e2ep() * self.s()
+ self.s() * operand.epem() * self.e2em()
+ self.s() * operand.m() * self.e1ep(),
self.e1em() * operand.e1em() * self.e1em() - self.e1em() * operand.e1ep() * self.e1ep()
+ self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.e2ep() * self.e2ep()
+ self.e1em() * operand.epem() * self.epem()
- self.e1em() * operand.m() * self.m()
+ self.e1ep() * operand.e1em() * self.e1ep()
- self.e1ep() * operand.e1ep() * self.e1em()
+ self.e1ep() * operand.e2em() * self.e2ep()
- self.e1ep() * operand.e2ep() * self.e2em()
+ self.e1ep() * operand.epem() * self.s()
- self.e1ep() * operand.m() * self.ps()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e1ep() * self.e2ep()
+ self.e2em() * operand.e2em() * self.e1em()
- self.e2em() * operand.e2ep() * self.e1ep()
- self.e2em() * operand.epem() * self.ps()
- self.e2em() * operand.m() * self.s()
- self.e2ep() * operand.e1em() * self.e2ep()
+ self.e2ep() * operand.e1ep() * self.e2em()
+ self.e2ep() * operand.e2em() * self.e1ep()
- self.e2ep() * operand.e2ep() * self.e1em()
- self.e2ep() * operand.epem() * self.m()
- self.e2ep() * operand.m() * self.epem()
- self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.e1ep() * self.s()
+ self.epem() * operand.e2em() * self.ps()
+ self.epem() * operand.e2ep() * self.m()
+ self.epem() * operand.epem() * self.e1em()
- self.epem() * operand.m() * self.e2ep()
+ self.m() * operand.e1em() * self.m()
+ self.m() * operand.e1ep() * self.ps()
+ self.m() * operand.e2em() * self.s()
+ self.m() * operand.e2ep() * self.epem()
- self.m() * operand.epem() * self.e2ep()
- self.m() * operand.m() * self.e1em()
+ self.ps() * operand.e1em() * self.ps()
+ self.ps() * operand.e1ep() * self.m()
+ self.ps() * operand.e2em() * self.epem()
+ self.ps() * operand.e2ep() * self.s()
- self.ps() * operand.epem() * self.e2em()
- self.ps() * operand.m() * self.e1ep()
- self.s() * operand.e1em() * self.s()
- self.s() * operand.e1ep() * self.epem()
+ self.s() * operand.e2em() * self.m()
+ self.s() * operand.e2ep() * self.ps()
+ self.s() * operand.epem() * self.e1ep()
- self.s() * operand.m() * self.e2em(),
self.e1em() * operand.e1em() * self.e2em()
- self.e1em() * operand.e1ep() * self.e2ep()
- self.e1em() * operand.e2em() * self.e1em()
+ self.e1em() * operand.e2ep() * self.e1ep()
+ self.e1em() * operand.epem() * self.ps()
+ self.e1em() * operand.m() * self.s()
+ self.e1ep() * operand.e1em() * self.e2ep()
- self.e1ep() * operand.e1ep() * self.e2em()
- self.e1ep() * operand.e2em() * self.e1ep()
+ self.e1ep() * operand.e2ep() * self.e1em()
+ self.e1ep() * operand.epem() * self.m()
+ self.e1ep() * operand.m() * self.epem()
+ self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e1ep() * self.e1ep()
+ self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.e2ep() * self.e2ep()
+ self.e2em() * operand.epem() * self.epem()
- self.e2em() * operand.m() * self.m()
+ self.e2ep() * operand.e1em() * self.e1ep()
- self.e2ep() * operand.e1ep() * self.e1em()
+ self.e2ep() * operand.e2em() * self.e2ep()
- self.e2ep() * operand.e2ep() * self.e2em()
+ self.e2ep() * operand.epem() * self.s()
- self.e2ep() * operand.m() * self.ps()
- self.epem() * operand.e1em() * self.ps()
- self.epem() * operand.e1ep() * self.m()
- self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.e2ep() * self.s()
+ self.epem() * operand.epem() * self.e2em()
+ self.epem() * operand.m() * self.e1ep()
- self.m() * operand.e1em() * self.s()
- self.m() * operand.e1ep() * self.epem()
+ self.m() * operand.e2em() * self.m()
+ self.m() * operand.e2ep() * self.ps()
+ self.m() * operand.epem() * self.e1ep()
- self.m() * operand.m() * self.e2em()
- self.ps() * operand.e1em() * self.epem()
- self.ps() * operand.e1ep() * self.s()
+ self.ps() * operand.e2em() * self.ps()
+ self.ps() * operand.e2ep() * self.m()
+ self.ps() * operand.epem() * self.e1em()
- self.ps() * operand.m() * self.e2ep()
- self.s() * operand.e1em() * self.m()
- self.s() * operand.e1ep() * self.ps()
- self.s() * operand.e2em() * self.s()
- self.s() * operand.e2ep() * self.epem()
+ self.s() * operand.epem() * self.e2ep()
+ self.s() * operand.m() * self.e1em(),
self.e1em() * operand.e1em() * self.epem() + self.e1em() * operand.e1ep() * self.s()
- self.e1em() * operand.e2em() * self.ps()
- self.e1em() * operand.e2ep() * self.m()
- self.e1em() * operand.epem() * self.e1em()
+ self.e1em() * operand.m() * self.e2ep()
- self.e1ep() * operand.e1em() * self.s()
- self.e1ep() * operand.e1ep() * self.epem()
+ self.e1ep() * operand.e2em() * self.m()
+ self.e1ep() * operand.e2ep() * self.ps()
+ self.e1ep() * operand.epem() * self.e1ep()
- self.e1ep() * operand.m() * self.e2em()
+ self.e2em() * operand.e1em() * self.ps()
+ self.e2em() * operand.e1ep() * self.m()
+ self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.e2ep() * self.s()
- self.e2em() * operand.epem() * self.e2em()
- self.e2em() * operand.m() * self.e1ep()
- self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.e1ep() * self.ps()
- self.e2ep() * operand.e2em() * self.s()
- self.e2ep() * operand.e2ep() * self.epem()
+ self.e2ep() * operand.epem() * self.e2ep()
+ self.e2ep() * operand.m() * self.e1em()
+ self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e1ep() * self.e1ep()
+ self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.e2ep() * self.e2ep()
+ self.epem() * operand.epem() * self.epem()
- self.epem() * operand.m() * self.m()
- self.m() * operand.e1em() * self.e2ep()
+ self.m() * operand.e1ep() * self.e2em()
+ self.m() * operand.e2em() * self.e1ep()
- self.m() * operand.e2ep() * self.e1em()
- self.m() * operand.epem() * self.m()
- self.m() * operand.m() * self.epem()
+ self.ps() * operand.e1em() * self.e2em()
- self.ps() * operand.e1ep() * self.e2ep()
- self.ps() * operand.e2em() * self.e1em()
+ self.ps() * operand.e2ep() * self.e1ep()
+ self.ps() * operand.epem() * self.ps()
+ self.ps() * operand.m() * self.s()
- self.s() * operand.e1em() * self.e1ep()
+ self.s() * operand.e1ep() * self.e1em()
- self.s() * operand.e2em() * self.e2ep()
+ self.s() * operand.e2ep() * self.e2em()
- self.s() * operand.epem() * self.s()
+ self.s() * operand.m() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<PointPair<T>> for Unit<Motor<T>> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.m() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.m() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.m() * self.as_inner().m() * self.as_inner().m())
+ -(operand.m() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().ps()
+ -T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().s()
+ -T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.e2em() * self.as_inner().e2ep() * self.as_inner().ps()
+ -T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.e2ep() * self.as_inner().e2ep() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.epem() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.e1ep() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e2ep() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.epem() * self.as_inner().epem() * self.as_inner().m()
+ operand.m() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.m() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.m() * self.as_inner().epem() * self.as_inner().epem()
+ operand.m() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e1ep() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e1ep() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().ps()
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.e1em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e2em() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO * operand.e2ep() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO * operand.e2ep() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().epem()
+ operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e1ep() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e1ep() * self.as_inner().m() * self.as_inner().m()
+ operand.e1ep() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e2ep() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e2ep() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().m()
+ -T::TWO * operand.e1em() * self.as_inner().ps() * self.as_inner().s()
+ -T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.e1ep() * self.as_inner().epem() * self.as_inner().ps()
+ -T::TWO * operand.e1ep() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.e2em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().s()
+ operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e2ep() * self.as_inner().m() * self.as_inner().m()
+ operand.e2ep() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e1em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e1em() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e1em() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.e1ep() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().m()
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().ps()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().s()
+ -T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.e1ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO * operand.e2em() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.e2ep() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e2ep() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().s()
+ operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e1em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e1em() * self.as_inner().m() * self.as_inner().m()
+ operand.e1em() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e2em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e2em() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e2em() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().ps()
+ -T::TWO * operand.e1em() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.e1ep() * self.as_inner().epem() * self.as_inner().m()
+ -T::TWO * operand.e1ep() * self.as_inner().ps() * self.as_inner().s()
+ -T::TWO * operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.e2ep() * self.as_inner().epem() * self.as_inner().s()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().ps()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.e2ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().epem()
+ operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e2em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e2em() * self.as_inner().m() * self.as_inner().m()
+ operand.e2em() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.epem() * self.as_inner().m() * self.as_inner().m())
+ -(operand.epem() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ -T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.e1ep() * self.as_inner().e2ep() * self.as_inner().ps()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.e2em() * self.as_inner().e2ep() * self.as_inner().s()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.e2ep() * self.as_inner().e2ep() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.m() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO * operand.e2ep() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.m() * self.as_inner().ps() * self.as_inner().s()
+ operand.epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.epem() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.epem() * self.as_inner().epem() * self.as_inner().epem()
+ operand.epem() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<PointPair<T>>> for Motor<T> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.e1em() * self.e1em())
+ -(operand.as_inner().m() * self.e2em() * self.e2em())
+ -(operand.as_inner().m() * self.m() * self.m())
+ -(operand.as_inner().m() * self.s() * self.s())
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.ps()
+ -T::TWO * operand.as_inner().e1em() * self.e2em() * self.s()
+ -T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().e1ep() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().e2em() * self.e2ep() * self.ps()
+ -T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.s()
+ -T::TWO * operand.as_inner().e2ep() * self.e2ep() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().epem() * self.ps() * self.s()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().e1em() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.ps()
+ T::TWO * operand.as_inner().e1ep() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().e2em() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e2ep() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().epem() * self.epem() * self.m()
+ operand.as_inner().m() * self.e1ep() * self.e1ep()
+ operand.as_inner().m() * self.e2ep() * self.e2ep()
+ operand.as_inner().m() * self.epem() * self.epem()
+ operand.as_inner().m() * self.ps() * self.ps(),
-(operand.as_inner().e1ep() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1ep() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e1ep() * self.epem() * self.epem())
+ -(operand.as_inner().e1ep() * self.s() * self.s())
+ -T::TWO * operand.as_inner().e1em() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().e1em() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e2ep() * self.ps()
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.ps()
+ -T::TWO * operand.as_inner().m() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().e1em() * self.m() * self.ps()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().e2em() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e2em() * self.ps() * self.s()
+ T::TWO * operand.as_inner().e2ep() * self.epem() * self.ps()
+ T::TWO * operand.as_inner().e2ep() * self.m() * self.s()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.epem()
+ operand.as_inner().e1ep() * self.e2em() * self.e2em()
+ operand.as_inner().e1ep() * self.e2ep() * self.e2ep()
+ operand.as_inner().e1ep() * self.m() * self.m()
+ operand.as_inner().e1ep() * self.ps() * self.ps(),
-(operand.as_inner().e2ep() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2ep() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e2ep() * self.epem() * self.epem())
+ -(operand.as_inner().e2ep() * self.s() * self.s())
+ -T::TWO * operand.as_inner().e1em() * self.epem() * self.m()
+ -T::TWO * operand.as_inner().e1em() * self.ps() * self.s()
+ -T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().e1ep() * self.epem() * self.ps()
+ -T::TWO * operand.as_inner().e1ep() * self.m() * self.s()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().e2em() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.ps()
+ -T::TWO * operand.as_inner().m() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().e2em() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().e2em() * self.m() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e2em() * self.s()
+ T::TWO * operand.as_inner().epem() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().m() * self.e1ep() * self.s()
+ operand.as_inner().e2ep() * self.e1em() * self.e1em()
+ operand.as_inner().e2ep() * self.e1ep() * self.e1ep()
+ operand.as_inner().e2ep() * self.m() * self.m()
+ operand.as_inner().e2ep() * self.ps() * self.ps(),
-(operand.as_inner().e1em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e1em() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e1em() * self.epem() * self.epem())
+ -(operand.as_inner().e1em() * self.s() * self.s())
+ -T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().e1ep() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.ps()
+ -T::TWO * operand.as_inner().epem() * self.e2ep() * self.m()
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().m() * self.e1ep() * self.ps()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.s()
+ -T::TWO * operand.as_inner().m() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().e1ep() * self.m() * self.ps()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e2em() * self.epem() * self.ps()
+ T::TWO * operand.as_inner().e2em() * self.m() * self.s()
+ T::TWO * operand.as_inner().e2ep() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e2ep() * self.ps() * self.s()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.s()
+ operand.as_inner().e1em() * self.e1em() * self.e1em()
+ operand.as_inner().e1em() * self.e1ep() * self.e1ep()
+ operand.as_inner().e1em() * self.m() * self.m()
+ operand.as_inner().e1em() * self.ps() * self.ps(),
-(operand.as_inner().e2em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e2em() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e2em() * self.epem() * self.epem())
+ -(operand.as_inner().e2em() * self.s() * self.s())
+ -T::TWO * operand.as_inner().e1em() * self.epem() * self.ps()
+ -T::TWO * operand.as_inner().e1em() * self.m() * self.s()
+ -T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().e1ep() * self.epem() * self.m()
+ -T::TWO * operand.as_inner().e1ep() * self.ps() * self.s()
+ -T::TWO * operand.as_inner().e2ep() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().e2ep() * self.epem() * self.s()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().m() * self.e2ep() * self.ps()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().e2ep() * self.m() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.ps()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().epem() * self.e2ep() * self.s()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().m() * self.e1ep() * self.epem()
+ operand.as_inner().e2em() * self.e2em() * self.e2em()
+ operand.as_inner().e2em() * self.e2ep() * self.e2ep()
+ operand.as_inner().e2em() * self.m() * self.m()
+ operand.as_inner().e2em() * self.ps() * self.ps(),
-(operand.as_inner().epem() * self.e1em() * self.e1em())
+ -(operand.as_inner().epem() * self.e2em() * self.e2em())
+ -(operand.as_inner().epem() * self.m() * self.m())
+ -(operand.as_inner().epem() * self.s() * self.s())
+ -T::TWO * operand.as_inner().e1em() * self.e1ep() * self.s()
+ -T::TWO * operand.as_inner().e1em() * self.e2ep() * self.m()
+ -T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().e1ep() * self.e2ep() * self.ps()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.ps()
+ -T::TWO * operand.as_inner().e2em() * self.e2ep() * self.s()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().e2ep() * self.e2ep() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().m() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e1em() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().e1ep() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().e1ep() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.ps()
+ T::TWO * operand.as_inner().e2ep() * self.e2em() * self.s()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().m() * self.ps() * self.s()
+ operand.as_inner().epem() * self.e1ep() * self.e1ep()
+ operand.as_inner().epem() * self.e2ep() * self.e2ep()
+ operand.as_inner().epem() * self.epem() * self.epem()
+ operand.as_inner().epem() * self.ps() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<PointPair<T>>> for Unit<Motor<T>> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().m() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().m() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2ep()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().epem() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2em()
* self.as_inner().ps()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().m()
+ operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().m() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().m() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.as_inner().e1ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e1ep() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e1ep() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().epem()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().epem()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ operand.as_inner().e1ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e1ep() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e1ep() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().e1ep() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.as_inner().e2ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e2ep() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e2ep() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().epem()
* self.as_inner().m()
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().ps() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().epem()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().epem()
* self.as_inner().s()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().s()
+ operand.as_inner().e2ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e2ep() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e2ep() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().e2ep() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e1em() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().epem()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().m()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().ps()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().epem()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().ps() * self.as_inner().s()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().s()
+ operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e1em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().e1em() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e2em() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().epem()
* self.as_inner().ps()
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().epem()
* self.as_inner().m()
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().ps() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().epem()
* self.as_inner().s()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().epem()
+ operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e2em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().e2em() * self.as_inner().ps() * self.as_inner().ps(),
-(operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().epem() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().epem() * self.as_inner().s() * self.as_inner().s())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2ep()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().ps()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2ep()
* self.as_inner().s()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO * operand.as_inner().m() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().ps()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.as_inner().m() * self.as_inner().ps() * self.as_inner().s()
+ operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().epem() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[doc = "Antisandwich product: [`Motor`] x [`Pseudoscalar`] x antirev([`Motor`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Pseudoscalar<T>> for Motor<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
self.e1em() * operand.ps() * self.e1em() - self.e1ep() * operand.ps() * self.e1ep()
+ self.e2em() * operand.ps() * self.e2em()
- self.e2ep() * operand.ps() * self.e2ep()
+ self.epem() * operand.ps() * self.epem()
- self.m() * operand.ps() * self.m()
+ self.ps() * operand.ps() * self.ps()
- self.s() * operand.ps() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Pseudoscalar<T>> for Unit<Motor<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.ps() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.ps() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.ps() * self.as_inner().m() * self.as_inner().m())
+ -(operand.ps() * self.as_inner().s() * self.as_inner().s())
+ operand.ps() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.ps() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.ps() * self.as_inner().epem() * self.as_inner().epem()
+ operand.ps() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Pseudoscalar<T>>> for Motor<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().ps() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().ps() * self.m() * self.m())
+ -(operand.as_inner().ps() * self.s() * self.s())
+ operand.as_inner().ps() * self.e1em() * self.e1em()
+ operand.as_inner().ps() * self.e2em() * self.e2em()
+ operand.as_inner().ps() * self.epem() * self.epem()
+ operand.as_inner().ps() * self.ps() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Pseudoscalar<T>>> for Unit<Motor<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().ps() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().ps() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().ps() * self.as_inner().s() * self.as_inner().s())
+ operand.as_inner().ps() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().ps() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().ps() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().ps() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[doc = "Antisandwich product: [`Motor`] x [`RoundPoint`] x antirev([`Motor`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<RoundPoint<T>> for Motor<T> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
self.e1em() * operand.em() * self.s()
+ self.e1em() * operand.ep() * self.epem()
+ self.e1em() * operand.x() * self.e1em()
+ self.e1em() * operand.y() * self.e2em()
- self.e1ep() * operand.em() * self.epem()
- self.e1ep() * operand.ep() * self.s()
- self.e1ep() * operand.x() * self.e1ep()
- self.e1ep() * operand.y() * self.e2ep()
- self.e2em() * operand.em() * self.m()
- self.e2em() * operand.ep() * self.ps()
- self.e2em() * operand.x() * self.e2em()
+ self.e2em() * operand.y() * self.e1em()
+ self.e2ep() * operand.em() * self.ps()
+ self.e2ep() * operand.ep() * self.m()
+ self.e2ep() * operand.x() * self.e2ep()
- self.e2ep() * operand.y() * self.e1ep()
- self.epem() * operand.em() * self.e1ep()
+ self.epem() * operand.ep() * self.e1em()
- self.epem() * operand.x() * self.epem()
+ self.epem() * operand.y() * self.ps()
- self.m() * operand.em() * self.e2em()
+ self.m() * operand.ep() * self.e2ep()
- self.m() * operand.x() * self.m()
- self.m() * operand.y() * self.s()
+ self.ps() * operand.em() * self.e2ep()
- self.ps() * operand.ep() * self.e2em()
+ self.ps() * operand.x() * self.ps()
+ self.ps() * operand.y() * self.epem()
+ self.s() * operand.em() * self.e1em()
- self.s() * operand.ep() * self.e1ep()
+ self.s() * operand.x() * self.s()
- self.s() * operand.y() * self.m(),
self.e1em() * operand.em() * self.m()
+ self.e1em() * operand.ep() * self.ps()
+ self.e1em() * operand.x() * self.e2em()
- self.e1em() * operand.y() * self.e1em()
- self.e1ep() * operand.em() * self.ps()
- self.e1ep() * operand.ep() * self.m()
- self.e1ep() * operand.x() * self.e2ep()
+ self.e1ep() * operand.y() * self.e1ep()
+ self.e2em() * operand.em() * self.s()
+ self.e2em() * operand.ep() * self.epem()
+ self.e2em() * operand.x() * self.e1em()
+ self.e2em() * operand.y() * self.e2em()
- self.e2ep() * operand.em() * self.epem()
- self.e2ep() * operand.ep() * self.s()
- self.e2ep() * operand.x() * self.e1ep()
- self.e2ep() * operand.y() * self.e2ep()
- self.epem() * operand.em() * self.e2ep()
+ self.epem() * operand.ep() * self.e2em()
- self.epem() * operand.x() * self.ps()
- self.epem() * operand.y() * self.epem()
+ self.m() * operand.em() * self.e1em()
- self.m() * operand.ep() * self.e1ep()
+ self.m() * operand.x() * self.s()
- self.m() * operand.y() * self.m()
- self.ps() * operand.em() * self.e1ep()
+ self.ps() * operand.ep() * self.e1em()
- self.ps() * operand.x() * self.epem()
+ self.ps() * operand.y() * self.ps()
+ self.s() * operand.em() * self.e2em()
- self.s() * operand.ep() * self.e2ep()
+ self.s() * operand.x() * self.m()
+ self.s() * operand.y() * self.s(),
self.e1em() * operand.em() * self.e1ep() - self.e1em() * operand.ep() * self.e1em()
+ self.e1em() * operand.x() * self.epem()
- self.e1em() * operand.y() * self.ps()
+ self.e1ep() * operand.em() * self.e1em()
- self.e1ep() * operand.ep() * self.e1ep()
+ self.e1ep() * operand.x() * self.s()
- self.e1ep() * operand.y() * self.m()
+ self.e2em() * operand.em() * self.e2ep()
- self.e2em() * operand.ep() * self.e2em()
+ self.e2em() * operand.x() * self.ps()
+ self.e2em() * operand.y() * self.epem()
+ self.e2ep() * operand.em() * self.e2em()
- self.e2ep() * operand.ep() * self.e2ep()
+ self.e2ep() * operand.x() * self.m()
+ self.e2ep() * operand.y() * self.s()
+ self.epem() * operand.em() * self.s()
+ self.epem() * operand.ep() * self.epem()
+ self.epem() * operand.x() * self.e1em()
+ self.epem() * operand.y() * self.e2em()
+ self.m() * operand.em() * self.ps()
+ self.m() * operand.ep() * self.m()
+ self.m() * operand.x() * self.e2ep()
- self.m() * operand.y() * self.e1ep()
+ self.ps() * operand.em() * self.m()
+ self.ps() * operand.ep() * self.ps()
+ self.ps() * operand.x() * self.e2em()
- self.ps() * operand.y() * self.e1em()
+ self.s() * operand.em() * self.epem()
+ self.s() * operand.ep() * self.s()
+ self.s() * operand.x() * self.e1ep()
+ self.s() * operand.y() * self.e2ep(),
self.e1em() * operand.em() * self.e1em() - self.e1em() * operand.ep() * self.e1ep()
+ self.e1em() * operand.x() * self.s()
- self.e1em() * operand.y() * self.m()
+ self.e1ep() * operand.em() * self.e1ep()
- self.e1ep() * operand.ep() * self.e1em()
+ self.e1ep() * operand.x() * self.epem()
- self.e1ep() * operand.y() * self.ps()
+ self.e2em() * operand.em() * self.e2em()
- self.e2em() * operand.ep() * self.e2ep()
+ self.e2em() * operand.x() * self.m()
+ self.e2em() * operand.y() * self.s()
+ self.e2ep() * operand.em() * self.e2ep()
- self.e2ep() * operand.ep() * self.e2em()
+ self.e2ep() * operand.x() * self.ps()
+ self.e2ep() * operand.y() * self.epem()
+ self.epem() * operand.em() * self.epem()
+ self.epem() * operand.ep() * self.s()
+ self.epem() * operand.x() * self.e1ep()
+ self.epem() * operand.y() * self.e2ep()
+ self.m() * operand.em() * self.m()
+ self.m() * operand.ep() * self.ps()
+ self.m() * operand.x() * self.e2em()
- self.m() * operand.y() * self.e1em()
+ self.ps() * operand.em() * self.ps()
+ self.ps() * operand.ep() * self.m()
+ self.ps() * operand.x() * self.e2ep()
- self.ps() * operand.y() * self.e1ep()
+ self.s() * operand.em() * self.s()
+ self.s() * operand.ep() * self.epem()
+ self.s() * operand.x() * self.e1em()
+ self.s() * operand.y() * self.e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<RoundPoint<T>> for Unit<Motor<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.x() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.x() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.x() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.x() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.em() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.em() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.ep() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.ep() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO * operand.y() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.y() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.em() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.em() * self.as_inner().e2ep() * self.as_inner().ps()
+ T::TWO * operand.ep() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.ep() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.y() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.y() * self.as_inner().epem() * self.as_inner().ps()
+ operand.x() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.x() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.x() * self.as_inner().ps() * self.as_inner().ps()
+ operand.x() * self.as_inner().s() * self.as_inner().s(),
-(operand.y() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.y() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.y() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.y() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.em() * self.as_inner().e1ep() * self.as_inner().ps()
+ -T::TWO * operand.em() * self.as_inner().e2ep() * self.as_inner().epem()
+ -T::TWO * operand.ep() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.ep() * self.as_inner().e2ep() * self.as_inner().s()
+ -T::TWO * operand.x() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.x() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO * operand.em() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.em() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.ep() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO * operand.ep() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.x() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.x() * self.as_inner().m() * self.as_inner().s()
+ operand.y() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.y() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.y() * self.as_inner().ps() * self.as_inner().ps()
+ operand.y() * self.as_inner().s() * self.as_inner().s(),
-(operand.ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO * operand.y() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.y() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.em() * self.as_inner().epem() * self.as_inner().s()
+ T::TWO * operand.em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.x() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.x() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.x() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.x() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.y() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.y() * self.as_inner().e2ep() * self.as_inner().s()
+ operand.ep() * self.as_inner().epem() * self.as_inner().epem()
+ operand.ep() * self.as_inner().m() * self.as_inner().m()
+ operand.ep() * self.as_inner().ps() * self.as_inner().ps()
+ operand.ep() * self.as_inner().s() * self.as_inner().s(),
-T::TWO * operand.ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.y() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.y() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO * operand.ep() * self.as_inner().epem() * self.as_inner().s()
+ T::TWO * operand.ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.x() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.x() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.x() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.x() * self.as_inner().e2ep() * self.as_inner().ps()
+ T::TWO * operand.y() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.y() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.em() * self.as_inner().m() * self.as_inner().m()
+ operand.em() * self.as_inner().ps() * self.as_inner().ps()
+ operand.em() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<RoundPoint<T>>> for Motor<T> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().x() * self.e2em() * self.e2em())
+ -(operand.as_inner().x() * self.epem() * self.epem())
+ -(operand.as_inner().x() * self.m() * self.m())
+ -T::TWO * operand.as_inner().em() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().em() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().ep() * self.e1ep() * self.s()
+ -T::TWO * operand.as_inner().ep() * self.e2em() * self.ps()
+ -T::TWO * operand.as_inner().y() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().y() * self.m() * self.s()
+ T::TWO * operand.as_inner().em() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().em() * self.e2ep() * self.ps()
+ T::TWO * operand.as_inner().ep() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().ep() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().y() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().y() * self.epem() * self.ps()
+ operand.as_inner().x() * self.e1em() * self.e1em()
+ operand.as_inner().x() * self.e2ep() * self.e2ep()
+ operand.as_inner().x() * self.ps() * self.ps()
+ operand.as_inner().x() * self.s() * self.s(),
-(operand.as_inner().y() * self.e1em() * self.e1em())
+ -(operand.as_inner().y() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().y() * self.epem() * self.epem())
+ -(operand.as_inner().y() * self.m() * self.m())
+ -T::TWO * operand.as_inner().em() * self.e1ep() * self.ps()
+ -T::TWO * operand.as_inner().em() * self.e2ep() * self.epem()
+ -T::TWO * operand.as_inner().ep() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().ep() * self.e2ep() * self.s()
+ -T::TWO * operand.as_inner().x() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().x() * self.epem() * self.ps()
+ T::TWO * operand.as_inner().em() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().em() * self.e2em() * self.s()
+ T::TWO * operand.as_inner().ep() * self.e1em() * self.ps()
+ T::TWO * operand.as_inner().ep() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().x() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().x() * self.m() * self.s()
+ operand.as_inner().y() * self.e1ep() * self.e1ep()
+ operand.as_inner().y() * self.e2em() * self.e2em()
+ operand.as_inner().y() * self.ps() * self.ps()
+ operand.as_inner().y() * self.s() * self.s(),
-(operand.as_inner().ep() * self.e1em() * self.e1em())
+ -(operand.as_inner().ep() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().ep() * self.e2em() * self.e2em())
+ -(operand.as_inner().ep() * self.e2ep() * self.e2ep())
+ -T::TWO * operand.as_inner().y() * self.e1em() * self.ps()
+ -T::TWO * operand.as_inner().y() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().em() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().em() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().em() * self.epem() * self.s()
+ T::TWO * operand.as_inner().em() * self.m() * self.ps()
+ T::TWO * operand.as_inner().x() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().x() * self.e1ep() * self.s()
+ T::TWO * operand.as_inner().x() * self.e2em() * self.ps()
+ T::TWO * operand.as_inner().x() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().y() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().y() * self.e2ep() * self.s()
+ operand.as_inner().ep() * self.epem() * self.epem()
+ operand.as_inner().ep() * self.m() * self.m()
+ operand.as_inner().ep() * self.ps() * self.ps()
+ operand.as_inner().ep() * self.s() * self.s(),
-T::TWO * operand.as_inner().ep() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().ep() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().y() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().y() * self.e1ep() * self.ps()
+ T::TWO * operand.as_inner().ep() * self.epem() * self.s()
+ T::TWO * operand.as_inner().ep() * self.m() * self.ps()
+ T::TWO * operand.as_inner().x() * self.e1em() * self.s()
+ T::TWO * operand.as_inner().x() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().x() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().x() * self.e2ep() * self.ps()
+ T::TWO * operand.as_inner().y() * self.e2em() * self.s()
+ T::TWO * operand.as_inner().y() * self.e2ep() * self.epem()
+ operand.as_inner().em() * self.e1em() * self.e1em()
+ operand.as_inner().em() * self.e1ep() * self.e1ep()
+ operand.as_inner().em() * self.e2em() * self.e2em()
+ operand.as_inner().em() * self.e2ep() * self.e2ep()
+ operand.as_inner().em() * self.epem() * self.epem()
+ operand.as_inner().em() * self.m() * self.m()
+ operand.as_inner().em() * self.ps() * self.ps()
+ operand.as_inner().em() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<RoundPoint<T>>> for Unit<Motor<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().x() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().x() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().x() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().em()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().em() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.as_inner().ep() * self.as_inner().e1ep() * self.as_inner().s()
+ -T::TWO * operand.as_inner().ep() * self.as_inner().e2em() * self.as_inner().ps()
+ -T::TWO
* operand.as_inner().y()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().y() * self.as_inner().m() * self.as_inner().s()
+ T::TWO * operand.as_inner().em() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.as_inner().em() * self.as_inner().e2ep() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().ep() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.as_inner().y() * self.as_inner().epem() * self.as_inner().ps()
+ operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().x() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().x() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().x() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().y() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().y() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().y() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.as_inner().em() * self.as_inner().e1ep() * self.as_inner().ps()
+ -T::TWO
* operand.as_inner().em()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().ep() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.as_inner().ep() * self.as_inner().e2ep() * self.as_inner().s()
+ -T::TWO
* operand.as_inner().x()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().x() * self.as_inner().epem() * self.as_inner().ps()
+ T::TWO * operand.as_inner().em() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.as_inner().em() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.as_inner().ep() * self.as_inner().e1em() * self.as_inner().ps()
+ T::TWO
* operand.as_inner().ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.as_inner().x() * self.as_inner().m() * self.as_inner().s()
+ operand.as_inner().y() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().y() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().y() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().y() * self.as_inner().s() * self.as_inner().s(),
-(operand.as_inner().ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO * operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().ps()
+ -T::TWO * operand.as_inner().y() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO
* operand.as_inner().em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().em() * self.as_inner().epem() * self.as_inner().s()
+ T::TWO * operand.as_inner().em() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.as_inner().x() * self.as_inner().e1ep() * self.as_inner().s()
+ T::TWO * operand.as_inner().x() * self.as_inner().e2em() * self.as_inner().ps()
+ T::TWO * operand.as_inner().x() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().y() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.as_inner().y() * self.as_inner().e2ep() * self.as_inner().s()
+ operand.as_inner().ep() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().ep() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().ep() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().ep() * self.as_inner().s() * self.as_inner().s(),
-T::TWO * operand.as_inner().ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.as_inner().y() * self.as_inner().e1ep() * self.as_inner().ps()
+ T::TWO * operand.as_inner().ep() * self.as_inner().epem() * self.as_inner().s()
+ T::TWO * operand.as_inner().ep() * self.as_inner().m() * self.as_inner().ps()
+ T::TWO * operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().s()
+ T::TWO * operand.as_inner().x() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.as_inner().x() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.as_inner().x() * self.as_inner().e2ep() * self.as_inner().ps()
+ T::TWO * operand.as_inner().y() * self.as_inner().e2em() * self.as_inner().s()
+ T::TWO * operand.as_inner().y() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.as_inner().em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().em() * self.as_inner().m() * self.as_inner().m()
+ operand.as_inner().em() * self.as_inner().ps() * self.as_inner().ps()
+ operand.as_inner().em() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Antisandwich product: [`Motor`] x [`Scalar`] x antirev([`Motor`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Scalar<T>> for Motor<T> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
self.e1em() * operand.s() * self.e1em() - self.e1ep() * operand.s() * self.e1ep()
+ self.e2em() * operand.s() * self.e2em()
- self.e2ep() * operand.s() * self.e2ep()
+ self.epem() * operand.s() * self.epem()
- self.m() * operand.s() * self.m()
+ self.ps() * operand.s() * self.ps()
- self.s() * operand.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Scalar<T>> for Unit<Motor<T>> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.s() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.s() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.s() * self.as_inner().m() * self.as_inner().m())
+ -(operand.s() * self.as_inner().s() * self.as_inner().s())
+ operand.s() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.s() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.s() * self.as_inner().epem() * self.as_inner().epem()
+ operand.s() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Scalar<T>>> for Motor<T> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().s() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().s() * self.m() * self.m())
+ -(operand.as_inner().s() * self.s() * self.s())
+ operand.as_inner().s() * self.e1em() * self.e1em()
+ operand.as_inner().s() * self.e2em() * self.e2em()
+ operand.as_inner().s() * self.epem() * self.epem()
+ operand.as_inner().s() * self.ps() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Scalar<T>>> for Unit<Motor<T>> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().s() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().s() * self.as_inner().m() * self.as_inner().m())
+ -(operand.as_inner().s() * self.as_inner().s() * self.as_inner().s())
+ operand.as_inner().s() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().s() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().s() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().s() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[doc = "Antisandwich product: [`PointPair`] x [`Circle`] x antirev([`PointPair`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Circle<T>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-(self.e1em() * operand.e12em() * self.e1ep())
+ self.e1em() * operand.e1epem() * self.m()
+ self.e1em() * operand.w() * self.e1em()
- self.e1ep() * operand.e12em() * self.e1em()
+ self.e1ep() * operand.e2epem() * self.epem()
+ self.e1ep() * operand.w() * self.e1ep()
- self.e2em() * operand.e12em() * self.e2ep()
+ self.e2em() * operand.e2epem() * self.m()
+ self.e2em() * operand.w() * self.e2em()
- self.e2ep() * operand.e12em() * self.e2em()
- self.e2ep() * operand.e1epem() * self.epem()
+ self.e2ep() * operand.w() * self.e2ep()
- self.epem() * operand.e1epem() * self.e2ep()
+ self.epem() * operand.e2epem() * self.e1ep()
+ self.epem() * operand.w() * self.epem()
+ self.m() * operand.e1epem() * self.e1em()
+ self.m() * operand.e2epem() * self.e2em()
+ self.m() * operand.w() * self.m(),
-(self.e1em() * operand.e12em() * self.e1em())
+ self.e1em() * operand.e2epem() * self.epem()
+ self.e1em() * operand.w() * self.e1ep()
- self.e1ep() * operand.e12em() * self.e1ep()
+ self.e1ep() * operand.e1epem() * self.m()
+ self.e1ep() * operand.w() * self.e1em()
- self.e2em() * operand.e12em() * self.e2em()
- self.e2em() * operand.e1epem() * self.epem()
+ self.e2em() * operand.w() * self.e2ep()
- self.e2ep() * operand.e12em() * self.e2ep()
+ self.e2ep() * operand.e2epem() * self.m()
+ self.e2ep() * operand.w() * self.e2em()
+ self.epem() * operand.e12em() * self.epem()
- self.epem() * operand.e1epem() * self.e2em()
+ self.epem() * operand.e2epem() * self.e1em()
+ self.m() * operand.e12em() * self.m()
+ self.m() * operand.e1epem() * self.e1ep()
+ self.m() * operand.e2epem() * self.e2ep(),
-(self.e1em() * operand.e1epem() * self.e1em())
- self.e1em() * operand.e2epem() * self.e2em()
- self.e1em() * operand.w() * self.m()
+ self.e1ep() * operand.e12em() * self.m()
+ self.e1ep() * operand.e1epem() * self.e1ep()
+ self.e1ep() * operand.e2epem() * self.e2ep()
- self.e2em() * operand.e12em() * self.epem()
+ self.e2em() * operand.e1epem() * self.e2em()
- self.e2em() * operand.e2epem() * self.e1em()
- self.e2ep() * operand.e1epem() * self.e2ep()
+ self.e2ep() * operand.e2epem() * self.e1ep()
+ self.e2ep() * operand.w() * self.epem()
- self.epem() * operand.e12em() * self.e2em()
- self.epem() * operand.e1epem() * self.epem()
+ self.epem() * operand.w() * self.e2ep()
+ self.m() * operand.e12em() * self.e1ep()
- self.m() * operand.e1epem() * self.m()
- self.m() * operand.w() * self.e1em(),
self.e1em() * operand.e12em() * self.epem()
- self.e1em() * operand.e1epem() * self.e2em()
+ self.e1em() * operand.e2epem() * self.e1em()
+ self.e1ep() * operand.e1epem() * self.e2ep()
- self.e1ep() * operand.e2epem() * self.e1ep()
- self.e1ep() * operand.w() * self.epem()
- self.e2em() * operand.e1epem() * self.e1em()
- self.e2em() * operand.e2epem() * self.e2em()
- self.e2em() * operand.w() * self.m()
+ self.e2ep() * operand.e12em() * self.m()
+ self.e2ep() * operand.e1epem() * self.e1ep()
+ self.e2ep() * operand.e2epem() * self.e2ep()
+ self.epem() * operand.e12em() * self.e1em()
- self.epem() * operand.e2epem() * self.epem()
- self.epem() * operand.w() * self.e1ep()
+ self.m() * operand.e12em() * self.e2ep()
- self.m() * operand.e2epem() * self.m()
- self.m() * operand.w() * self.e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Circle<T>> for Unit<PointPair<T>> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.e12em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.e12em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.e1epem() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.e1epem() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.e2epem() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.e2epem() * self.as_inner().e2em() * self.as_inner().m()
+ operand.w() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.w() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.w() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.w() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.w() * self.as_inner().epem() * self.as_inner().epem()
+ operand.w() * self.as_inner().m() * self.as_inner().m(),
-(operand.e12em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e12em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e12em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e12em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO * operand.e1epem() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.e1epem() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e2epem() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e2epem() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.w() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.w() * self.as_inner().e2em() * self.as_inner().e2ep()
+ operand.e12em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.e12em() * self.as_inner().m() * self.as_inner().m(),
-(operand.e1epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e1epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e1epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e12em() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.e2epem() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.w() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.e12em() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e2epem() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.w() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.e1epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e1epem() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.e2epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e2epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.e2epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e1epem() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.w() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.w() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.e12em() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e12em() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.e1epem() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ operand.e2epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e2epem() * self.as_inner().e2ep() * self.as_inner().e2ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Circle<T>>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.as_inner().e12em() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().e12em() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().e1epem() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().e1epem() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().e2epem() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().e2epem() * self.e2em() * self.m()
+ operand.as_inner().w() * self.e1em() * self.e1em()
+ operand.as_inner().w() * self.e1ep() * self.e1ep()
+ operand.as_inner().w() * self.e2em() * self.e2em()
+ operand.as_inner().w() * self.e2ep() * self.e2ep()
+ operand.as_inner().w() * self.epem() * self.epem()
+ operand.as_inner().w() * self.m() * self.m(),
-(operand.as_inner().e12em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e12em() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e12em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e12em() * self.e2ep() * self.e2ep())
+ -T::TWO * operand.as_inner().e1epem() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().e1epem() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e2epem() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e2epem() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().w() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().w() * self.e2em() * self.e2ep()
+ operand.as_inner().e12em() * self.epem() * self.epem()
+ operand.as_inner().e12em() * self.m() * self.m(),
-(operand.as_inner().e1epem() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1epem() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e1epem() * self.epem() * self.epem())
+ -(operand.as_inner().e1epem() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e12em() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().e2epem() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().w() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().e12em() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e2epem() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().w() * self.e2ep() * self.epem()
+ operand.as_inner().e1epem() * self.e1ep() * self.e1ep()
+ operand.as_inner().e1epem() * self.e2em() * self.e2em(),
-(operand.as_inner().e2epem() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e2epem() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2epem() * self.epem() * self.epem())
+ -(operand.as_inner().e2epem() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e1epem() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().w() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().w() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().e12em() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e12em() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().e1epem() * self.e1ep() * self.e2ep()
+ operand.as_inner().e2epem() * self.e1em() * self.e1em()
+ operand.as_inner().e2epem() * self.e2ep() * self.e2ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Circle<T>>> for Unit<PointPair<T>> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.as_inner().e12em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1em()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e2em()
* self.as_inner().m()
+ operand.as_inner().w() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().w() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().w() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().w() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().w() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().w() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().e12em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e12em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e12em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e12em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1ep()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e2ep()
* self.as_inner().m()
+ T::TWO * operand.as_inner().w() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.as_inner().w() * self.as_inner().e2em() * self.as_inner().e2ep()
+ operand.as_inner().e12em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().e12em() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().e1epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1epem() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e1epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e1epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO * operand.as_inner().w() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e1ep()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e2epem()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().w() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.as_inner().e1epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e1epem() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().e2epem() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e2epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2epem() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().e2epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().w()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().w() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e12em()
* self.as_inner().e2ep()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e1epem()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ operand.as_inner().e2epem() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e2epem() * self.as_inner().e2ep() * self.as_inner().e2ep(),
)
}
}
#[doc = "Antisandwich product: [`PointPair`] x [`FlatPoint`] x antirev([`PointPair`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<FlatPoint<T>> for PointPair<T> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
self.e1em() * operand.e1em() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.epem() * self.epem()
+ self.e1ep() * operand.e1em() * self.e1ep()
+ self.e1ep() * operand.e2em() * self.e2ep()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1em()
- self.e2ep() * operand.e1em() * self.e2ep()
+ self.e2ep() * operand.e2em() * self.e1ep()
- self.e2ep() * operand.epem() * self.m()
- self.epem() * operand.e1em() * self.epem()
+ self.epem() * operand.epem() * self.e1em()
+ self.m() * operand.e1em() * self.m()
- self.m() * operand.epem() * self.e2ep(),
self.e1em() * operand.e1em() * self.e2em() - self.e1em() * operand.e2em() * self.e1em()
+ self.e1ep() * operand.e1em() * self.e2ep()
- self.e1ep() * operand.e2em() * self.e1ep()
+ self.e1ep() * operand.epem() * self.m()
+ self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.epem() * self.epem()
+ self.e2ep() * operand.e1em() * self.e1ep()
+ self.e2ep() * operand.e2em() * self.e2ep()
- self.epem() * operand.e2em() * self.epem()
+ self.epem() * operand.epem() * self.e2em()
+ self.m() * operand.e2em() * self.m()
+ self.m() * operand.epem() * self.e1ep(),
self.e1em() * operand.e1em() * self.epem() - self.e1em() * operand.epem() * self.e1em()
+ self.e1ep() * operand.e2em() * self.m()
+ self.e1ep() * operand.epem() * self.e1ep()
+ self.e2em() * operand.e2em() * self.epem()
- self.e2em() * operand.epem() * self.e2em()
- self.e2ep() * operand.e1em() * self.m()
+ self.e2ep() * operand.epem() * self.e2ep()
+ self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.epem() * self.epem()
- self.m() * operand.e1em() * self.e2ep()
+ self.m() * operand.e2em() * self.e1ep()
- self.m() * operand.epem() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<FlatPoint<T>> for Unit<PointPair<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e1em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e1em() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e1em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e1em() * self.as_inner().m() * self.as_inner().m(),
-(operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e2em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e2em() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e2em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e2em() * self.as_inner().m() * self.as_inner().m(),
-(operand.epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.epem() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.epem() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<FlatPoint<T>>> for PointPair<T> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e1em() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e1em() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().epem() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ operand.as_inner().e1em() * self.e1em() * self.e1em()
+ operand.as_inner().e1em() * self.e1ep() * self.e1ep()
+ operand.as_inner().e1em() * self.m() * self.m(),
-(operand.as_inner().e2em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e2em() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e2em() * self.epem() * self.epem())
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ operand.as_inner().e2em() * self.e2em() * self.e2em()
+ operand.as_inner().e2em() * self.e2ep() * self.e2ep()
+ operand.as_inner().e2em() * self.m() * self.m(),
-(operand.as_inner().epem() * self.e1em() * self.e1em())
+ -(operand.as_inner().epem() * self.e2em() * self.e2em())
+ -(operand.as_inner().epem() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e1em() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ operand.as_inner().epem() * self.e1ep() * self.e1ep()
+ operand.as_inner().epem() * self.e2ep() * self.e2ep()
+ operand.as_inner().epem() * self.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<FlatPoint<T>>> for Unit<PointPair<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e1em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem())
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e2em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2ep()
* self.as_inner().m()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Antisandwich product: [`PointPair`] x [`Line`] x antirev([`PointPair`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Line<T>> for PointPair<T> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
self.e1em() * operand.d() * self.epem()
- self.e1em() * operand.nx() * self.e1em()
- self.e1ep() * operand.nx() * self.e1ep()
+ self.e1ep() * operand.ny() * self.m()
- self.e2em() * operand.nx() * self.e2em()
- self.e2em() * operand.ny() * self.epem()
+ self.e2ep() * operand.d() * self.m()
- self.e2ep() * operand.nx() * self.e2ep()
+ self.epem() * operand.d() * self.e1em()
+ self.epem() * operand.nx() * self.epem()
- self.epem() * operand.ny() * self.e2em()
+ self.m() * operand.d() * self.e2ep()
+ self.m() * operand.nx() * self.m()
+ self.m() * operand.ny() * self.e1ep(),
-(self.e1em() * operand.d() * self.e2em()) - self.e1em() * operand.ny() * self.e1em()
+ self.e1ep() * operand.d() * self.e2ep()
+ self.e1ep() * operand.nx() * self.m()
+ self.e1ep() * operand.ny() * self.e1ep()
- self.e2em() * operand.d() * self.e1em()
- self.e2em() * operand.nx() * self.epem()
+ self.e2em() * operand.ny() * self.e2em()
+ self.e2ep() * operand.d() * self.e1ep()
- self.e2ep() * operand.ny() * self.e2ep()
- self.epem() * operand.nx() * self.e2em()
- self.epem() * operand.ny() * self.epem()
+ self.m() * operand.nx() * self.e1ep()
- self.m() * operand.ny() * self.m(),
self.e1em() * operand.d() * self.e1em() + self.e1em() * operand.nx() * self.epem()
- self.e1em() * operand.ny() * self.e2em()
- self.e1ep() * operand.d() * self.e1ep()
+ self.e1ep() * operand.ny() * self.e2ep()
- self.e2em() * operand.d() * self.e2em()
- self.e2em() * operand.ny() * self.e1em()
+ self.e2ep() * operand.d() * self.e2ep()
+ self.e2ep() * operand.nx() * self.m()
+ self.e2ep() * operand.ny() * self.e1ep()
- self.epem() * operand.d() * self.epem()
+ self.epem() * operand.nx() * self.e1em()
- self.m() * operand.d() * self.m()
+ self.m() * operand.nx() * self.e2ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Line<T>> for Unit<PointPair<T>> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(operand.nx() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.nx() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.nx() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.nx() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO * operand.ny() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.d() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.d() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.ny() * self.as_inner().e1ep() * self.as_inner().m()
+ operand.nx() * self.as_inner().epem() * self.as_inner().epem()
+ operand.nx() * self.as_inner().m() * self.as_inner().m(),
-(operand.ny() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ny() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.ny() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.ny() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.d() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.nx() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.d() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.nx() * self.as_inner().e1ep() * self.as_inner().m()
+ operand.ny() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.ny() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.d() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.d() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.d() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.d() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.ny() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.nx() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.nx() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.ny() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ operand.d() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.d() * self.as_inner().e2ep() * self.as_inner().e2ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Line<T>>> for PointPair<T> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.e1em() * self.e1em())
+ -(operand.as_inner().nx() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().nx() * self.e2em() * self.e2em())
+ -(operand.as_inner().nx() * self.e2ep() * self.e2ep())
+ -T::TWO * operand.as_inner().ny() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().d() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().d() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().ny() * self.e1ep() * self.m()
+ operand.as_inner().nx() * self.epem() * self.epem()
+ operand.as_inner().nx() * self.m() * self.m(),
-(operand.as_inner().ny() * self.e1em() * self.e1em())
+ -(operand.as_inner().ny() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().ny() * self.epem() * self.epem())
+ -(operand.as_inner().ny() * self.m() * self.m())
+ -T::TWO * operand.as_inner().d() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().nx() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().d() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().nx() * self.e1ep() * self.m()
+ operand.as_inner().ny() * self.e1ep() * self.e1ep()
+ operand.as_inner().ny() * self.e2em() * self.e2em(),
-(operand.as_inner().d() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().d() * self.e2em() * self.e2em())
+ -(operand.as_inner().d() * self.epem() * self.epem())
+ -(operand.as_inner().d() * self.m() * self.m())
+ -T::TWO * operand.as_inner().ny() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().nx() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().nx() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().ny() * self.e1ep() * self.e2ep()
+ operand.as_inner().d() * self.e1em() * self.e1em()
+ operand.as_inner().d() * self.e2ep() * self.e2ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Line<T>>> for Unit<PointPair<T>> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().nx() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().nx() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().nx() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO
* operand.as_inner().ny()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().d() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.as_inner().d() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().ny() * self.as_inner().e1ep() * self.as_inner().m()
+ operand.as_inner().nx() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().nx() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().ny() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ny() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().ny() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().ny() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().d()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().nx()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().d() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.as_inner().nx() * self.as_inner().e1ep() * self.as_inner().m()
+ operand.as_inner().ny() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().ny() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().d() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().d() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().d() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().d() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().ny()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().nx()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().nx() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().ny()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ operand.as_inner().d() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().d() * self.as_inner().e2ep() * self.as_inner().e2ep(),
)
}
}
#[doc = "Antisandwich product: [`PointPair`] x [`Motor`] x antirev([`PointPair`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Motor<T>> for PointPair<T> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(self.e1em() * operand.e1ep() * self.epem())
+ self.e1em() * operand.e2em() * self.m()
+ self.e1em() * operand.epem() * self.e1ep()
- self.e1em() * operand.m() * self.e2em()
- self.e1em() * operand.ps() * self.e2ep()
+ self.e1em() * operand.s() * self.e1em()
+ self.e1ep() * operand.e1em() * self.epem()
- self.e1ep() * operand.e2ep() * self.m()
- self.e1ep() * operand.epem() * self.e1em()
+ self.e1ep() * operand.m() * self.e2ep()
+ self.e1ep() * operand.ps() * self.e2em()
- self.e1ep() * operand.s() * self.e1ep()
- self.e2em() * operand.e1em() * self.m()
- self.e2em() * operand.e2ep() * self.epem()
+ self.e2em() * operand.epem() * self.e2ep()
+ self.e2em() * operand.m() * self.e1em()
+ self.e2em() * operand.ps() * self.e1ep()
+ self.e2em() * operand.s() * self.e2em()
+ self.e2ep() * operand.e1ep() * self.m()
+ self.e2ep() * operand.e2em() * self.epem()
- self.e2ep() * operand.epem() * self.e2em()
- self.e2ep() * operand.m() * self.e1ep()
- self.e2ep() * operand.ps() * self.e1em()
- self.e2ep() * operand.s() * self.e2ep()
- self.epem() * operand.e1em() * self.e1ep()
+ self.epem() * operand.e1ep() * self.e1em()
- self.epem() * operand.e2em() * self.e2ep()
+ self.epem() * operand.e2ep() * self.e2em()
- self.epem() * operand.ps() * self.m()
+ self.epem() * operand.s() * self.epem()
+ self.m() * operand.e1em() * self.e2em()
- self.m() * operand.e1ep() * self.e2ep()
- self.m() * operand.e2em() * self.e1em()
+ self.m() * operand.e2ep() * self.e1ep()
- self.m() * operand.ps() * self.epem()
- self.m() * operand.s() * self.m(),
self.e1em() * operand.e1em() * self.m() + self.e1em() * operand.e2ep() * self.epem()
- self.e1em() * operand.epem() * self.e2ep()
- self.e1em() * operand.m() * self.e1em()
- self.e1em() * operand.ps() * self.e1ep()
- self.e1em() * operand.s() * self.e2em()
- self.e1ep() * operand.e1ep() * self.m()
- self.e1ep() * operand.e2em() * self.epem()
+ self.e1ep() * operand.epem() * self.e2em()
+ self.e1ep() * operand.m() * self.e1ep()
+ self.e1ep() * operand.ps() * self.e1em()
+ self.e1ep() * operand.s() * self.e2ep()
- self.e2em() * operand.e1ep() * self.epem()
+ self.e2em() * operand.e2em() * self.m()
+ self.e2em() * operand.epem() * self.e1ep()
- self.e2em() * operand.m() * self.e2em()
- self.e2em() * operand.ps() * self.e2ep()
+ self.e2em() * operand.s() * self.e1em()
+ self.e2ep() * operand.e1em() * self.epem()
- self.e2ep() * operand.e2ep() * self.m()
- self.e2ep() * operand.epem() * self.e1em()
+ self.e2ep() * operand.m() * self.e2ep()
+ self.e2ep() * operand.ps() * self.e2em()
- self.e2ep() * operand.s() * self.e1ep()
+ self.epem() * operand.e1em() * self.e2ep()
- self.epem() * operand.e1ep() * self.e2em()
- self.epem() * operand.e2em() * self.e1ep()
+ self.epem() * operand.e2ep() * self.e1em()
+ self.epem() * operand.epem() * self.m()
+ self.epem() * operand.m() * self.epem()
+ self.m() * operand.e1em() * self.e1em()
- self.m() * operand.e1ep() * self.e1ep()
+ self.m() * operand.e2em() * self.e2em()
- self.m() * operand.e2ep() * self.e2ep()
+ self.m() * operand.epem() * self.epem()
- self.m() * operand.m() * self.m(),
self.e1em() * operand.e1em() * self.e1ep() - self.e1em() * operand.e1ep() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2ep()
- self.e1em() * operand.e2ep() * self.e2em()
+ self.e1em() * operand.ps() * self.m()
- self.e1em() * operand.s() * self.epem()
+ self.e1ep() * operand.e1em() * self.e1em()
- self.e1ep() * operand.e1ep() * self.e1ep()
+ self.e1ep() * operand.e2em() * self.e2em()
- self.e1ep() * operand.e2ep() * self.e2ep()
+ self.e1ep() * operand.epem() * self.epem()
- self.e1ep() * operand.m() * self.m()
- self.e2em() * operand.e1em() * self.e2ep()
+ self.e2em() * operand.e1ep() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1ep()
- self.e2em() * operand.e2ep() * self.e1em()
- self.e2em() * operand.epem() * self.m()
- self.e2em() * operand.m() * self.epem()
- self.e2ep() * operand.e1em() * self.e2em()
+ self.e2ep() * operand.e1ep() * self.e2ep()
+ self.e2ep() * operand.e2em() * self.e1em()
- self.e2ep() * operand.e2ep() * self.e1ep()
+ self.e2ep() * operand.ps() * self.epem()
+ self.e2ep() * operand.s() * self.m()
- self.epem() * operand.e1ep() * self.epem()
+ self.epem() * operand.e2em() * self.m()
+ self.epem() * operand.epem() * self.e1ep()
- self.epem() * operand.m() * self.e2em()
- self.epem() * operand.ps() * self.e2ep()
+ self.epem() * operand.s() * self.e1em()
+ self.m() * operand.e1ep() * self.m()
+ self.m() * operand.e2em() * self.epem()
- self.m() * operand.epem() * self.e2em()
- self.m() * operand.m() * self.e1ep()
- self.m() * operand.ps() * self.e1em()
- self.m() * operand.s() * self.e2ep(),
self.e1em() * operand.e1em() * self.e2ep()
- self.e1em() * operand.e1ep() * self.e2em()
- self.e1em() * operand.e2em() * self.e1ep()
+ self.e1em() * operand.e2ep() * self.e1em()
+ self.e1em() * operand.epem() * self.m()
+ self.e1em() * operand.m() * self.epem()
+ self.e1ep() * operand.e1em() * self.e2em()
- self.e1ep() * operand.e1ep() * self.e2ep()
- self.e1ep() * operand.e2em() * self.e1em()
+ self.e1ep() * operand.e2ep() * self.e1ep()
- self.e1ep() * operand.ps() * self.epem()
- self.e1ep() * operand.s() * self.m()
+ self.e2em() * operand.e1em() * self.e1ep()
- self.e2em() * operand.e1ep() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2ep()
- self.e2em() * operand.e2ep() * self.e2em()
+ self.e2em() * operand.ps() * self.m()
- self.e2em() * operand.s() * self.epem()
+ self.e2ep() * operand.e1em() * self.e1em()
- self.e2ep() * operand.e1ep() * self.e1ep()
+ self.e2ep() * operand.e2em() * self.e2em()
- self.e2ep() * operand.e2ep() * self.e2ep()
+ self.e2ep() * operand.epem() * self.epem()
- self.e2ep() * operand.m() * self.m()
- self.epem() * operand.e1em() * self.m()
- self.epem() * operand.e2ep() * self.epem()
+ self.epem() * operand.epem() * self.e2ep()
+ self.epem() * operand.m() * self.e1em()
+ self.epem() * operand.ps() * self.e1ep()
+ self.epem() * operand.s() * self.e2em()
- self.m() * operand.e1em() * self.epem()
+ self.m() * operand.e2ep() * self.m()
+ self.m() * operand.epem() * self.e1em()
- self.m() * operand.m() * self.e2ep()
- self.m() * operand.ps() * self.e2em()
+ self.m() * operand.s() * self.e1ep(),
self.e1em() * operand.e1em() * self.e1em() - self.e1em() * operand.e1ep() * self.e1ep()
+ self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.e2ep() * self.e2ep()
+ self.e1em() * operand.epem() * self.epem()
- self.e1em() * operand.m() * self.m()
+ self.e1ep() * operand.e1em() * self.e1ep()
- self.e1ep() * operand.e1ep() * self.e1em()
+ self.e1ep() * operand.e2em() * self.e2ep()
- self.e1ep() * operand.e2ep() * self.e2em()
+ self.e1ep() * operand.ps() * self.m()
- self.e1ep() * operand.s() * self.epem()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e1ep() * self.e2ep()
+ self.e2em() * operand.e2em() * self.e1em()
- self.e2em() * operand.e2ep() * self.e1ep()
+ self.e2em() * operand.ps() * self.epem()
+ self.e2em() * operand.s() * self.m()
- self.e2ep() * operand.e1em() * self.e2ep()
+ self.e2ep() * operand.e1ep() * self.e2em()
+ self.e2ep() * operand.e2em() * self.e1ep()
- self.e2ep() * operand.e2ep() * self.e1em()
- self.e2ep() * operand.epem() * self.m()
- self.e2ep() * operand.m() * self.epem()
- self.epem() * operand.e1em() * self.epem()
+ self.epem() * operand.e2ep() * self.m()
+ self.epem() * operand.epem() * self.e1em()
- self.epem() * operand.m() * self.e2ep()
- self.epem() * operand.ps() * self.e2em()
+ self.epem() * operand.s() * self.e1ep()
+ self.m() * operand.e1em() * self.m()
+ self.m() * operand.e2ep() * self.epem()
- self.m() * operand.epem() * self.e2ep()
- self.m() * operand.m() * self.e1em()
- self.m() * operand.ps() * self.e1ep()
- self.m() * operand.s() * self.e2em(),
self.e1em() * operand.e1em() * self.e2em()
- self.e1em() * operand.e1ep() * self.e2ep()
- self.e1em() * operand.e2em() * self.e1em()
+ self.e1em() * operand.e2ep() * self.e1ep()
- self.e1em() * operand.ps() * self.epem()
- self.e1em() * operand.s() * self.m()
+ self.e1ep() * operand.e1em() * self.e2ep()
- self.e1ep() * operand.e1ep() * self.e2em()
- self.e1ep() * operand.e2em() * self.e1ep()
+ self.e1ep() * operand.e2ep() * self.e1em()
+ self.e1ep() * operand.epem() * self.m()
+ self.e1ep() * operand.m() * self.epem()
+ self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e1ep() * self.e1ep()
+ self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.e2ep() * self.e2ep()
+ self.e2em() * operand.epem() * self.epem()
- self.e2em() * operand.m() * self.m()
+ self.e2ep() * operand.e1em() * self.e1ep()
- self.e2ep() * operand.e1ep() * self.e1em()
+ self.e2ep() * operand.e2em() * self.e2ep()
- self.e2ep() * operand.e2ep() * self.e2em()
+ self.e2ep() * operand.ps() * self.m()
- self.e2ep() * operand.s() * self.epem()
- self.epem() * operand.e1ep() * self.m()
- self.epem() * operand.e2em() * self.epem()
+ self.epem() * operand.epem() * self.e2em()
+ self.epem() * operand.m() * self.e1ep()
+ self.epem() * operand.ps() * self.e1em()
+ self.epem() * operand.s() * self.e2ep()
- self.m() * operand.e1ep() * self.epem()
+ self.m() * operand.e2em() * self.m()
+ self.m() * operand.epem() * self.e1ep()
- self.m() * operand.m() * self.e2em()
- self.m() * operand.ps() * self.e2ep()
+ self.m() * operand.s() * self.e1em(),
self.e1em() * operand.e1em() * self.epem()
- self.e1em() * operand.e2ep() * self.m()
- self.e1em() * operand.epem() * self.e1em()
+ self.e1em() * operand.m() * self.e2ep()
+ self.e1em() * operand.ps() * self.e2em()
- self.e1em() * operand.s() * self.e1ep()
- self.e1ep() * operand.e1ep() * self.epem()
+ self.e1ep() * operand.e2em() * self.m()
+ self.e1ep() * operand.epem() * self.e1ep()
- self.e1ep() * operand.m() * self.e2em()
- self.e1ep() * operand.ps() * self.e2ep()
+ self.e1ep() * operand.s() * self.e1em()
+ self.e2em() * operand.e1ep() * self.m()
+ self.e2em() * operand.e2em() * self.epem()
- self.e2em() * operand.epem() * self.e2em()
- self.e2em() * operand.m() * self.e1ep()
- self.e2em() * operand.ps() * self.e1em()
- self.e2em() * operand.s() * self.e2ep()
- self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.e2ep() * self.epem()
+ self.e2ep() * operand.epem() * self.e2ep()
+ self.e2ep() * operand.m() * self.e1em()
+ self.e2ep() * operand.ps() * self.e1ep()
+ self.e2ep() * operand.s() * self.e2em()
+ self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e1ep() * self.e1ep()
+ self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.e2ep() * self.e2ep()
+ self.epem() * operand.epem() * self.epem()
- self.epem() * operand.m() * self.m()
- self.m() * operand.e1em() * self.e2ep()
+ self.m() * operand.e1ep() * self.e2em()
+ self.m() * operand.e2em() * self.e1ep()
- self.m() * operand.e2ep() * self.e1em()
- self.m() * operand.epem() * self.m()
- self.m() * operand.m() * self.epem(),
-(self.e1em() * operand.e1ep() * self.m()) - self.e1em() * operand.e2em() * self.epem()
+ self.e1em() * operand.epem() * self.e2em()
+ self.e1em() * operand.m() * self.e1ep()
+ self.e1em() * operand.ps() * self.e1em()
+ self.e1em() * operand.s() * self.e2ep()
+ self.e1ep() * operand.e1em() * self.m()
+ self.e1ep() * operand.e2ep() * self.epem()
- self.e1ep() * operand.epem() * self.e2ep()
- self.e1ep() * operand.m() * self.e1em()
- self.e1ep() * operand.ps() * self.e1ep()
- self.e1ep() * operand.s() * self.e2em()
+ self.e2em() * operand.e1em() * self.epem()
- self.e2em() * operand.e2ep() * self.m()
- self.e2em() * operand.epem() * self.e1em()
+ self.e2em() * operand.m() * self.e2ep()
+ self.e2em() * operand.ps() * self.e2em()
- self.e2em() * operand.s() * self.e1ep()
- self.e2ep() * operand.e1ep() * self.epem()
+ self.e2ep() * operand.e2em() * self.m()
+ self.e2ep() * operand.epem() * self.e1ep()
- self.e2ep() * operand.m() * self.e2em()
- self.e2ep() * operand.ps() * self.e2ep()
+ self.e2ep() * operand.s() * self.e1em()
- self.epem() * operand.e1em() * self.e2em()
+ self.epem() * operand.e1ep() * self.e2ep()
+ self.epem() * operand.e2em() * self.e1em()
- self.epem() * operand.e2ep() * self.e1ep()
+ self.epem() * operand.ps() * self.epem()
+ self.epem() * operand.s() * self.m()
- self.m() * operand.e1em() * self.e1ep()
+ self.m() * operand.e1ep() * self.e1em()
- self.m() * operand.e2em() * self.e2ep()
+ self.m() * operand.e2ep() * self.e2em()
- self.m() * operand.ps() * self.m()
+ self.m() * operand.s() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Motor<T>> for Unit<PointPair<T>> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(operand.s() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.s() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.s() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.ps() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.ps() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.ps() * self.as_inner().e1ep() * self.as_inner().e2em()
+ operand.s() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.s() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.s() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.m() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.m() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.m() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.e2ep() * self.as_inner().e2ep() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.epem() * self.as_inner().epem() * self.as_inner().m()
+ operand.m() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.m() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.m() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e1ep() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().epem()
+ operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e1ep() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e1ep() * self.as_inner().m() * self.as_inner().m(),
-(operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e2ep() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().m()
+ -T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e2ep() * self.as_inner().m() * self.as_inner().m(),
-(operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e1em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e1em() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().m()
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e2ep() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e1em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e1em() * self.as_inner().m() * self.as_inner().m(),
-(operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e2em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e2em() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.e1ep() * self.as_inner().epem() * self.as_inner().m()
+ -T::TWO * operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().epem()
+ operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e2em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e2em() * self.as_inner().m() * self.as_inner().m(),
-(operand.epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ -T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.e2ep() * self.as_inner().e2ep() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.m() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().e2ep()
+ operand.epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.epem() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.epem() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.ps() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.ps() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.ps() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.s() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.s() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.s() * self.as_inner().epem() * self.as_inner().m()
+ operand.ps() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.ps() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.ps() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Motor<T>>> for PointPair<T> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().s() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().s() * self.m() * self.m())
+ -T::TWO * operand.as_inner().ps() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().ps() * self.epem() * self.m()
+ T::TWO * operand.as_inner().ps() * self.e1ep() * self.e2em()
+ operand.as_inner().s() * self.e1em() * self.e1em()
+ operand.as_inner().s() * self.e2em() * self.e2em()
+ operand.as_inner().s() * self.epem() * self.epem(),
-(operand.as_inner().m() * self.e1em() * self.e1em())
+ -(operand.as_inner().m() * self.e2em() * self.e2em())
+ -(operand.as_inner().m() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().e1ep() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().e2ep() * self.e2ep() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().e1em() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().e2em() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().epem() * self.epem() * self.m()
+ operand.as_inner().m() * self.e1ep() * self.e1ep()
+ operand.as_inner().m() * self.e2ep() * self.e2ep()
+ operand.as_inner().m() * self.epem() * self.epem(),
-(operand.as_inner().e1ep() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1ep() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e1ep() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1em() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().m() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().e2em() * self.epem() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.epem()
+ operand.as_inner().e1ep() * self.e2em() * self.e2em()
+ operand.as_inner().e1ep() * self.e2ep() * self.e2ep()
+ operand.as_inner().e1ep() * self.m() * self.m(),
-(operand.as_inner().e2ep() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2ep() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e2ep() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1em() * self.epem() * self.m()
+ -T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().m() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().e2em() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.epem()
+ operand.as_inner().e2ep() * self.e1em() * self.e1em()
+ operand.as_inner().e2ep() * self.e1ep() * self.e1ep()
+ operand.as_inner().e2ep() * self.m() * self.m(),
-(operand.as_inner().e1em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e1em() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e1em() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().epem() * self.e2ep() * self.m()
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().m() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.epem() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ operand.as_inner().e1em() * self.e1em() * self.e1em()
+ operand.as_inner().e1em() * self.e1ep() * self.e1ep()
+ operand.as_inner().e1em() * self.m() * self.m(),
-(operand.as_inner().e2em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e2em() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e2em() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().e1ep() * self.epem() * self.m()
+ -T::TWO * operand.as_inner().e2ep() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().m() * self.e1ep() * self.epem()
+ operand.as_inner().e2em() * self.e2em() * self.e2em()
+ operand.as_inner().e2em() * self.e2ep() * self.e2ep()
+ operand.as_inner().e2em() * self.m() * self.m(),
-(operand.as_inner().epem() * self.e1em() * self.e1em())
+ -(operand.as_inner().epem() * self.e2em() * self.e2em())
+ -(operand.as_inner().epem() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e1em() * self.e2ep() * self.m()
+ -T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().e2ep() * self.e2ep() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().m() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.e2ep()
+ operand.as_inner().epem() * self.e1ep() * self.e1ep()
+ operand.as_inner().epem() * self.e2ep() * self.e2ep()
+ operand.as_inner().epem() * self.epem() * self.epem(),
-(operand.as_inner().ps() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().ps() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().ps() * self.m() * self.m())
+ -T::TWO * operand.as_inner().s() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().s() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().s() * self.epem() * self.m()
+ operand.as_inner().ps() * self.e1em() * self.e1em()
+ operand.as_inner().ps() * self.e2em() * self.e2em()
+ operand.as_inner().ps() * self.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Motor<T>>> for Unit<PointPair<T>> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().s() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().s() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().ps()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().ps() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO
* operand.as_inner().ps()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ operand.as_inner().s() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().s() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().s() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().m() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().m()
+ operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().m() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e1ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e1ep() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().m()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ operand.as_inner().e1ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e1ep() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e1ep() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().e2ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e2ep() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().epem()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.as_inner().e2ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e2ep() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e2ep() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().m()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e1em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().epem()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().epem()
+ operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e2em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO * operand.as_inner().m() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().e2ep()
+ operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().ps() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().ps() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().ps() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().s()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().s() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.as_inner().s() * self.as_inner().epem() * self.as_inner().m()
+ operand.as_inner().ps() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().ps() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().ps() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Antisandwich product: [`PointPair`] x [`PointPair`] x antirev([`PointPair`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<PointPair<T>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
self.e1em() * operand.e1em() * self.m() + self.e1em() * operand.e2ep() * self.epem()
- self.e1em() * operand.epem() * self.e2ep()
- self.e1em() * operand.m() * self.e1em()
- self.e1ep() * operand.e1ep() * self.m()
- self.e1ep() * operand.e2em() * self.epem()
+ self.e1ep() * operand.epem() * self.e2em()
+ self.e1ep() * operand.m() * self.e1ep()
- self.e2em() * operand.e1ep() * self.epem()
+ self.e2em() * operand.e2em() * self.m()
+ self.e2em() * operand.epem() * self.e1ep()
- self.e2em() * operand.m() * self.e2em()
+ self.e2ep() * operand.e1em() * self.epem()
- self.e2ep() * operand.e2ep() * self.m()
- self.e2ep() * operand.epem() * self.e1em()
+ self.e2ep() * operand.m() * self.e2ep()
+ self.epem() * operand.e1em() * self.e2ep()
- self.epem() * operand.e1ep() * self.e2em()
- self.epem() * operand.e2em() * self.e1ep()
+ self.epem() * operand.e2ep() * self.e1em()
+ self.epem() * operand.epem() * self.m()
+ self.epem() * operand.m() * self.epem()
+ self.m() * operand.e1em() * self.e1em()
- self.m() * operand.e1ep() * self.e1ep()
+ self.m() * operand.e2em() * self.e2em()
- self.m() * operand.e2ep() * self.e2ep()
+ self.m() * operand.epem() * self.epem()
- self.m() * operand.m() * self.m(),
self.e1em() * operand.e1em() * self.e1ep() - self.e1em() * operand.e1ep() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2ep()
- self.e1em() * operand.e2ep() * self.e2em()
+ self.e1ep() * operand.e1em() * self.e1em()
- self.e1ep() * operand.e1ep() * self.e1ep()
+ self.e1ep() * operand.e2em() * self.e2em()
- self.e1ep() * operand.e2ep() * self.e2ep()
+ self.e1ep() * operand.epem() * self.epem()
- self.e1ep() * operand.m() * self.m()
- self.e2em() * operand.e1em() * self.e2ep()
+ self.e2em() * operand.e1ep() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1ep()
- self.e2em() * operand.e2ep() * self.e1em()
- self.e2em() * operand.epem() * self.m()
- self.e2em() * operand.m() * self.epem()
- self.e2ep() * operand.e1em() * self.e2em()
+ self.e2ep() * operand.e1ep() * self.e2ep()
+ self.e2ep() * operand.e2em() * self.e1em()
- self.e2ep() * operand.e2ep() * self.e1ep()
- self.epem() * operand.e1ep() * self.epem()
+ self.epem() * operand.e2em() * self.m()
+ self.epem() * operand.epem() * self.e1ep()
- self.epem() * operand.m() * self.e2em()
+ self.m() * operand.e1ep() * self.m()
+ self.m() * operand.e2em() * self.epem()
- self.m() * operand.epem() * self.e2em()
- self.m() * operand.m() * self.e1ep(),
self.e1em() * operand.e1em() * self.e2ep()
- self.e1em() * operand.e1ep() * self.e2em()
- self.e1em() * operand.e2em() * self.e1ep()
+ self.e1em() * operand.e2ep() * self.e1em()
+ self.e1em() * operand.epem() * self.m()
+ self.e1em() * operand.m() * self.epem()
+ self.e1ep() * operand.e1em() * self.e2em()
- self.e1ep() * operand.e1ep() * self.e2ep()
- self.e1ep() * operand.e2em() * self.e1em()
+ self.e1ep() * operand.e2ep() * self.e1ep()
+ self.e2em() * operand.e1em() * self.e1ep()
- self.e2em() * operand.e1ep() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2ep()
- self.e2em() * operand.e2ep() * self.e2em()
+ self.e2ep() * operand.e1em() * self.e1em()
- self.e2ep() * operand.e1ep() * self.e1ep()
+ self.e2ep() * operand.e2em() * self.e2em()
- self.e2ep() * operand.e2ep() * self.e2ep()
+ self.e2ep() * operand.epem() * self.epem()
- self.e2ep() * operand.m() * self.m()
- self.epem() * operand.e1em() * self.m()
- self.epem() * operand.e2ep() * self.epem()
+ self.epem() * operand.epem() * self.e2ep()
+ self.epem() * operand.m() * self.e1em()
- self.m() * operand.e1em() * self.epem()
+ self.m() * operand.e2ep() * self.m()
+ self.m() * operand.epem() * self.e1em()
- self.m() * operand.m() * self.e2ep(),
self.e1em() * operand.e1em() * self.e1em() - self.e1em() * operand.e1ep() * self.e1ep()
+ self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.e2ep() * self.e2ep()
+ self.e1em() * operand.epem() * self.epem()
- self.e1em() * operand.m() * self.m()
+ self.e1ep() * operand.e1em() * self.e1ep()
- self.e1ep() * operand.e1ep() * self.e1em()
+ self.e1ep() * operand.e2em() * self.e2ep()
- self.e1ep() * operand.e2ep() * self.e2em()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e1ep() * self.e2ep()
+ self.e2em() * operand.e2em() * self.e1em()
- self.e2em() * operand.e2ep() * self.e1ep()
- self.e2ep() * operand.e1em() * self.e2ep()
+ self.e2ep() * operand.e1ep() * self.e2em()
+ self.e2ep() * operand.e2em() * self.e1ep()
- self.e2ep() * operand.e2ep() * self.e1em()
- self.e2ep() * operand.epem() * self.m()
- self.e2ep() * operand.m() * self.epem()
- self.epem() * operand.e1em() * self.epem()
+ self.epem() * operand.e2ep() * self.m()
+ self.epem() * operand.epem() * self.e1em()
- self.epem() * operand.m() * self.e2ep()
+ self.m() * operand.e1em() * self.m()
+ self.m() * operand.e2ep() * self.epem()
- self.m() * operand.epem() * self.e2ep()
- self.m() * operand.m() * self.e1em(),
self.e1em() * operand.e1em() * self.e2em()
- self.e1em() * operand.e1ep() * self.e2ep()
- self.e1em() * operand.e2em() * self.e1em()
+ self.e1em() * operand.e2ep() * self.e1ep()
+ self.e1ep() * operand.e1em() * self.e2ep()
- self.e1ep() * operand.e1ep() * self.e2em()
- self.e1ep() * operand.e2em() * self.e1ep()
+ self.e1ep() * operand.e2ep() * self.e1em()
+ self.e1ep() * operand.epem() * self.m()
+ self.e1ep() * operand.m() * self.epem()
+ self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e1ep() * self.e1ep()
+ self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.e2ep() * self.e2ep()
+ self.e2em() * operand.epem() * self.epem()
- self.e2em() * operand.m() * self.m()
+ self.e2ep() * operand.e1em() * self.e1ep()
- self.e2ep() * operand.e1ep() * self.e1em()
+ self.e2ep() * operand.e2em() * self.e2ep()
- self.e2ep() * operand.e2ep() * self.e2em()
- self.epem() * operand.e1ep() * self.m()
- self.epem() * operand.e2em() * self.epem()
+ self.epem() * operand.epem() * self.e2em()
+ self.epem() * operand.m() * self.e1ep()
- self.m() * operand.e1ep() * self.epem()
+ self.m() * operand.e2em() * self.m()
+ self.m() * operand.epem() * self.e1ep()
- self.m() * operand.m() * self.e2em(),
self.e1em() * operand.e1em() * self.epem()
- self.e1em() * operand.e2ep() * self.m()
- self.e1em() * operand.epem() * self.e1em()
+ self.e1em() * operand.m() * self.e2ep()
- self.e1ep() * operand.e1ep() * self.epem()
+ self.e1ep() * operand.e2em() * self.m()
+ self.e1ep() * operand.epem() * self.e1ep()
- self.e1ep() * operand.m() * self.e2em()
+ self.e2em() * operand.e1ep() * self.m()
+ self.e2em() * operand.e2em() * self.epem()
- self.e2em() * operand.epem() * self.e2em()
- self.e2em() * operand.m() * self.e1ep()
- self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.e2ep() * self.epem()
+ self.e2ep() * operand.epem() * self.e2ep()
+ self.e2ep() * operand.m() * self.e1em()
+ self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e1ep() * self.e1ep()
+ self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.e2ep() * self.e2ep()
+ self.epem() * operand.epem() * self.epem()
- self.epem() * operand.m() * self.m()
- self.m() * operand.e1em() * self.e2ep()
+ self.m() * operand.e1ep() * self.e2em()
+ self.m() * operand.e2em() * self.e1ep()
- self.m() * operand.e2ep() * self.e1em()
- self.m() * operand.epem() * self.m()
- self.m() * operand.m() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<PointPair<T>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.m() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.m() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.m() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().epem()
+ -T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.e2ep() * self.as_inner().e2ep() * self.as_inner().m()
+ -T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.epem() * self.as_inner().epem() * self.as_inner().m()
+ operand.m() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.m() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.m() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e1ep() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.e2em() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().epem()
+ operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e1ep() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e1ep() * self.as_inner().m() * self.as_inner().m(),
-(operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e2ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e2ep() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1em() * self.as_inner().epem() * self.as_inner().m()
+ -T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2em()
+ -T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ -T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2ep()
+ T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2em()
+ T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e2ep() * self.as_inner().m() * self.as_inner().m(),
-(operand.e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.e1em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.e1em() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.e2ep() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.epem() * self.as_inner().e2ep() * self.as_inner().m()
+ -T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.m() * self.as_inner().e2ep() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.e2em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e2ep() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.e1em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.e1em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.e1em() * self.as_inner().m() * self.as_inner().m(),
-(operand.e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.e2em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.e2em() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO * operand.e1ep() * self.as_inner().e1em() * self.as_inner().e2ep()
+ -T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.e1ep() * self.as_inner().epem() * self.as_inner().m()
+ -T::TWO * operand.e2ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.m() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().e2em()
+ T::TWO * operand.e1em() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.epem() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.epem() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().epem()
+ operand.e2em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.e2em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.e2em() * self.as_inner().m() * self.as_inner().m(),
-(operand.epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.e1em() * self.as_inner().e2ep() * self.as_inner().m()
+ -T::TWO * operand.e1ep() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.e2ep() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO * operand.e2ep() * self.as_inner().e2ep() * self.as_inner().epem()
+ -T::TWO * operand.m() * self.as_inner().e1ep() * self.as_inner().e2em()
+ -T::TWO * operand.m() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO * operand.e1em() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.e1ep() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.e2em() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.m() * self.as_inner().e1em() * self.as_inner().e2ep()
+ operand.epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.epem() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.epem() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<PointPair<T>>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.e1em() * self.e1em())
+ -(operand.as_inner().m() * self.e2em() * self.e2em())
+ -(operand.as_inner().m() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().e1ep() * self.e2em() * self.epem()
+ -T::TWO * operand.as_inner().e2em() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().e2ep() * self.e2ep() * self.m()
+ -T::TWO * operand.as_inner().epem() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().e1em() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().e2em() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().epem() * self.epem() * self.m()
+ operand.as_inner().m() * self.e1ep() * self.e1ep()
+ operand.as_inner().m() * self.e2ep() * self.e2ep()
+ operand.as_inner().m() * self.epem() * self.epem(),
-(operand.as_inner().e1ep() * self.e1em() * self.e1em())
+ -(operand.as_inner().e1ep() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e1ep() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1em() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().epem() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().m() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().e2em() * self.epem() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.epem()
+ operand.as_inner().e1ep() * self.e2em() * self.e2em()
+ operand.as_inner().e1ep() * self.e2ep() * self.e2ep()
+ operand.as_inner().e1ep() * self.m() * self.m(),
-(operand.as_inner().e2ep() * self.e2em() * self.e2em())
+ -(operand.as_inner().e2ep() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e2ep() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1em() * self.epem() * self.m()
+ -T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2em()
+ -T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.e2ep()
+ -T::TWO * operand.as_inner().e2em() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().m() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2ep()
+ T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2em()
+ T::TWO * operand.as_inner().e2em() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.epem()
+ operand.as_inner().e2ep() * self.e1em() * self.e1em()
+ operand.as_inner().e2ep() * self.e1ep() * self.e1ep()
+ operand.as_inner().e2ep() * self.m() * self.m(),
-(operand.as_inner().e1em() * self.e2em() * self.e2em())
+ -(operand.as_inner().e1em() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().e1em() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().e2ep() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().epem() * self.e2ep() * self.m()
+ -T::TWO * operand.as_inner().m() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().m() * self.e2ep() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().e2em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.epem() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e1em() * self.epem()
+ operand.as_inner().e1em() * self.e1em() * self.e1em()
+ operand.as_inner().e1em() * self.e1ep() * self.e1ep()
+ operand.as_inner().e1em() * self.m() * self.m(),
-(operand.as_inner().e2em() * self.e1em() * self.e1em())
+ -(operand.as_inner().e2em() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().e2em() * self.epem() * self.epem())
+ -T::TWO * operand.as_inner().e1ep() * self.e1em() * self.e2ep()
+ -T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().e1ep() * self.epem() * self.m()
+ -T::TWO * operand.as_inner().e2ep() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().m() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.e2em()
+ T::TWO * operand.as_inner().e1em() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().epem() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().epem() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().m() * self.e1ep() * self.epem()
+ operand.as_inner().e2em() * self.e2em() * self.e2em()
+ operand.as_inner().e2em() * self.e2ep() * self.e2ep()
+ operand.as_inner().e2em() * self.m() * self.m(),
-(operand.as_inner().epem() * self.e1em() * self.e1em())
+ -(operand.as_inner().epem() * self.e2em() * self.e2em())
+ -(operand.as_inner().epem() * self.m() * self.m())
+ -T::TWO * operand.as_inner().e1em() * self.e2ep() * self.m()
+ -T::TWO * operand.as_inner().e1ep() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().e2ep() * self.e1em() * self.m()
+ -T::TWO * operand.as_inner().e2ep() * self.e2ep() * self.epem()
+ -T::TWO * operand.as_inner().m() * self.e1ep() * self.e2em()
+ -T::TWO * operand.as_inner().m() * self.epem() * self.m()
+ T::TWO * operand.as_inner().e1em() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().e1ep() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().e2em() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().e2em() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().m() * self.e1em() * self.e2ep()
+ operand.as_inner().epem() * self.e1ep() * self.e1ep()
+ operand.as_inner().epem() * self.e2ep() * self.e2ep()
+ operand.as_inner().epem() * self.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<PointPair<T>>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().m() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().m()
+ operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().m() * self.as_inner().epem() * self.as_inner().epem(),
-(operand.as_inner().e1ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e1ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e1ep() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().m()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ operand.as_inner().e1ep() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e1ep() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e1ep() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().e2ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e2ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e2ep() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().epem()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().epem()
+ operand.as_inner().e2ep() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e2ep() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e2ep() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().e1em() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().e1em() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().e1em() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().epem()
* self.as_inner().e2ep()
* self.as_inner().m()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().m()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e1em()
* self.as_inner().epem()
+ operand.as_inner().e1em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().e1em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().e1em() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().e2em() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().e2em() * self.as_inner().epem() * self.as_inner().epem())
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1em()
* self.as_inner().e2ep()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().epem()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().m() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().e2em()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO * operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().epem()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1ep() * self.as_inner().epem()
+ operand.as_inner().e2em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().e2em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().e2em() * self.as_inner().m() * self.as_inner().m(),
-(operand.as_inner().epem() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().epem() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().epem() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().e1em()
* self.as_inner().e2ep()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e1ep()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e1em()
* self.as_inner().m()
+ -T::TWO
* operand.as_inner().e2ep()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ -T::TWO
* operand.as_inner().m()
* self.as_inner().e1ep()
* self.as_inner().e2em()
+ -T::TWO * operand.as_inner().m() * self.as_inner().epem() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e1em()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().e2em()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().m() * self.as_inner().e1em() * self.as_inner().e2ep()
+ operand.as_inner().epem() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().epem() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().epem() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Antisandwich product: [`PointPair`] x [`Pseudoscalar`] x antirev([`PointPair`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Pseudoscalar<T>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
self.e1em() * operand.ps() * self.e1em() - self.e1ep() * operand.ps() * self.e1ep()
+ self.e2em() * operand.ps() * self.e2em()
- self.e2ep() * operand.ps() * self.e2ep()
+ self.epem() * operand.ps() * self.epem()
- self.m() * operand.ps() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Pseudoscalar<T>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.ps() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.ps() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.ps() * self.as_inner().m() * self.as_inner().m())
+ operand.ps() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.ps() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.ps() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Pseudoscalar<T>>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().ps() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().ps() * self.m() * self.m())
+ operand.as_inner().ps() * self.e1em() * self.e1em()
+ operand.as_inner().ps() * self.e2em() * self.e2em()
+ operand.as_inner().ps() * self.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Pseudoscalar<T>>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().ps() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().ps() * self.as_inner().m() * self.as_inner().m())
+ operand.as_inner().ps() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().ps() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().ps() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Antisandwich product: [`PointPair`] x [`RoundPoint`] x antirev([`PointPair`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<RoundPoint<T>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
self.e1em() * operand.ep() * self.epem()
+ self.e1em() * operand.x() * self.e1em()
+ self.e1em() * operand.y() * self.e2em()
- self.e1ep() * operand.em() * self.epem()
- self.e1ep() * operand.x() * self.e1ep()
- self.e1ep() * operand.y() * self.e2ep()
- self.e2em() * operand.em() * self.m()
- self.e2em() * operand.x() * self.e2em()
+ self.e2em() * operand.y() * self.e1em()
+ self.e2ep() * operand.ep() * self.m()
+ self.e2ep() * operand.x() * self.e2ep()
- self.e2ep() * operand.y() * self.e1ep()
- self.epem() * operand.em() * self.e1ep()
+ self.epem() * operand.ep() * self.e1em()
- self.epem() * operand.x() * self.epem()
- self.m() * operand.em() * self.e2em()
+ self.m() * operand.ep() * self.e2ep()
- self.m() * operand.x() * self.m(),
self.e1em() * operand.em() * self.m() + self.e1em() * operand.x() * self.e2em()
- self.e1em() * operand.y() * self.e1em()
- self.e1ep() * operand.ep() * self.m()
- self.e1ep() * operand.x() * self.e2ep()
+ self.e1ep() * operand.y() * self.e1ep()
+ self.e2em() * operand.ep() * self.epem()
+ self.e2em() * operand.x() * self.e1em()
+ self.e2em() * operand.y() * self.e2em()
- self.e2ep() * operand.em() * self.epem()
- self.e2ep() * operand.x() * self.e1ep()
- self.e2ep() * operand.y() * self.e2ep()
- self.epem() * operand.em() * self.e2ep()
+ self.epem() * operand.ep() * self.e2em()
- self.epem() * operand.y() * self.epem()
+ self.m() * operand.em() * self.e1em()
- self.m() * operand.ep() * self.e1ep()
- self.m() * operand.y() * self.m(),
self.e1em() * operand.em() * self.e1ep() - self.e1em() * operand.ep() * self.e1em()
+ self.e1em() * operand.x() * self.epem()
+ self.e1ep() * operand.em() * self.e1em()
- self.e1ep() * operand.ep() * self.e1ep()
- self.e1ep() * operand.y() * self.m()
+ self.e2em() * operand.em() * self.e2ep()
- self.e2em() * operand.ep() * self.e2em()
+ self.e2em() * operand.y() * self.epem()
+ self.e2ep() * operand.em() * self.e2em()
- self.e2ep() * operand.ep() * self.e2ep()
+ self.e2ep() * operand.x() * self.m()
+ self.epem() * operand.ep() * self.epem()
+ self.epem() * operand.x() * self.e1em()
+ self.epem() * operand.y() * self.e2em()
+ self.m() * operand.ep() * self.m()
+ self.m() * operand.x() * self.e2ep()
- self.m() * operand.y() * self.e1ep(),
self.e1em() * operand.em() * self.e1em()
- self.e1em() * operand.ep() * self.e1ep()
- self.e1em() * operand.y() * self.m()
+ self.e1ep() * operand.em() * self.e1ep()
- self.e1ep() * operand.ep() * self.e1em()
+ self.e1ep() * operand.x() * self.epem()
+ self.e2em() * operand.em() * self.e2em()
- self.e2em() * operand.ep() * self.e2ep()
+ self.e2em() * operand.x() * self.m()
+ self.e2ep() * operand.em() * self.e2ep()
- self.e2ep() * operand.ep() * self.e2em()
+ self.e2ep() * operand.y() * self.epem()
+ self.epem() * operand.em() * self.epem()
+ self.epem() * operand.x() * self.e1ep()
+ self.epem() * operand.y() * self.e2ep()
+ self.m() * operand.em() * self.m()
+ self.m() * operand.x() * self.e2em()
- self.m() * operand.y() * self.e1em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<RoundPoint<T>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.x() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.x() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.x() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.x() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.em() * self.as_inner().e1ep() * self.as_inner().epem()
+ -T::TWO * operand.em() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO * operand.y() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.ep() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.ep() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.y() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.x() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.x() * self.as_inner().e2ep() * self.as_inner().e2ep(),
-(operand.y() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.y() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.y() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.y() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO * operand.em() * self.as_inner().e2ep() * self.as_inner().epem()
+ -T::TWO * operand.ep() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO * operand.x() * self.as_inner().e1ep() * self.as_inner().e2ep()
+ T::TWO * operand.em() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.ep() * self.as_inner().e2em() * self.as_inner().epem()
+ T::TWO * operand.x() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.y() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.y() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO * operand.y() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO * operand.em() * self.as_inner().e1em() * self.as_inner().e1ep()
+ T::TWO * operand.em() * self.as_inner().e2em() * self.as_inner().e2ep()
+ T::TWO * operand.x() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.x() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.y() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.ep() * self.as_inner().epem() * self.as_inner().epem()
+ operand.ep() * self.as_inner().m() * self.as_inner().m(),
-T::TWO * operand.ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO * operand.ep() * self.as_inner().e2em() * self.as_inner().e2ep()
+ -T::TWO * operand.y() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.x() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.x() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.y() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.em() * self.as_inner().m() * self.as_inner().m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<RoundPoint<T>>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().x() * self.e2em() * self.e2em())
+ -(operand.as_inner().x() * self.epem() * self.epem())
+ -(operand.as_inner().x() * self.m() * self.m())
+ -T::TWO * operand.as_inner().em() * self.e1ep() * self.epem()
+ -T::TWO * operand.as_inner().em() * self.e2em() * self.m()
+ -T::TWO * operand.as_inner().y() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().ep() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().ep() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().y() * self.e1em() * self.e2em()
+ operand.as_inner().x() * self.e1em() * self.e1em()
+ operand.as_inner().x() * self.e2ep() * self.e2ep(),
-(operand.as_inner().y() * self.e1em() * self.e1em())
+ -(operand.as_inner().y() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().y() * self.epem() * self.epem())
+ -(operand.as_inner().y() * self.m() * self.m())
+ -T::TWO * operand.as_inner().em() * self.e2ep() * self.epem()
+ -T::TWO * operand.as_inner().ep() * self.e1ep() * self.m()
+ -T::TWO * operand.as_inner().x() * self.e1ep() * self.e2ep()
+ T::TWO * operand.as_inner().em() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().ep() * self.e2em() * self.epem()
+ T::TWO * operand.as_inner().x() * self.e1em() * self.e2em()
+ operand.as_inner().y() * self.e1ep() * self.e1ep()
+ operand.as_inner().y() * self.e2em() * self.e2em(),
-(operand.as_inner().ep() * self.e1em() * self.e1em())
+ -(operand.as_inner().ep() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().ep() * self.e2em() * self.e2em())
+ -(operand.as_inner().ep() * self.e2ep() * self.e2ep())
+ -T::TWO * operand.as_inner().y() * self.e1ep() * self.m()
+ T::TWO * operand.as_inner().em() * self.e1em() * self.e1ep()
+ T::TWO * operand.as_inner().em() * self.e2em() * self.e2ep()
+ T::TWO * operand.as_inner().x() * self.e1em() * self.epem()
+ T::TWO * operand.as_inner().x() * self.e2ep() * self.m()
+ T::TWO * operand.as_inner().y() * self.e2em() * self.epem()
+ operand.as_inner().ep() * self.epem() * self.epem()
+ operand.as_inner().ep() * self.m() * self.m(),
-T::TWO * operand.as_inner().ep() * self.e1em() * self.e1ep()
+ -T::TWO * operand.as_inner().ep() * self.e2em() * self.e2ep()
+ -T::TWO * operand.as_inner().y() * self.e1em() * self.m()
+ T::TWO * operand.as_inner().x() * self.e1ep() * self.epem()
+ T::TWO * operand.as_inner().x() * self.e2em() * self.m()
+ T::TWO * operand.as_inner().y() * self.e2ep() * self.epem()
+ operand.as_inner().em() * self.e1em() * self.e1em()
+ operand.as_inner().em() * self.e1ep() * self.e1ep()
+ operand.as_inner().em() * self.e2em() * self.e2em()
+ operand.as_inner().em() * self.e2ep() * self.e2ep()
+ operand.as_inner().em() * self.epem() * self.epem()
+ operand.as_inner().em() * self.m() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<RoundPoint<T>>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().x() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().x() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().x() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().em()
* self.as_inner().e1ep()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().em() * self.as_inner().e2em() * self.as_inner().m()
+ -T::TWO
* operand.as_inner().y()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO
* operand.as_inner().ep()
* self.as_inner().e1em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().ep() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().x() * self.as_inner().e2ep() * self.as_inner().e2ep(),
-(operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().y() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().y() * self.as_inner().epem() * self.as_inner().epem())
+ -(operand.as_inner().y() * self.as_inner().m() * self.as_inner().m())
+ -T::TWO
* operand.as_inner().em()
* self.as_inner().e2ep()
* self.as_inner().epem()
+ -T::TWO * operand.as_inner().ep() * self.as_inner().e1ep() * self.as_inner().m()
+ -T::TWO
* operand.as_inner().x()
* self.as_inner().e1ep()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().em() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO
* operand.as_inner().ep()
* self.as_inner().e2em()
* self.as_inner().epem()
+ T::TWO * operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().e2em()
+ operand.as_inner().y() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().y() * self.as_inner().e2em() * self.as_inner().e2em(),
-(operand.as_inner().ep() * self.as_inner().e1em() * self.as_inner().e1em())
+ -(operand.as_inner().ep() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().ep() * self.as_inner().e2em() * self.as_inner().e2em())
+ -(operand.as_inner().ep() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -T::TWO * operand.as_inner().y() * self.as_inner().e1ep() * self.as_inner().m()
+ T::TWO
* operand.as_inner().em()
* self.as_inner().e1em()
* self.as_inner().e1ep()
+ T::TWO
* operand.as_inner().em()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ T::TWO * operand.as_inner().x() * self.as_inner().e1em() * self.as_inner().epem()
+ T::TWO * operand.as_inner().x() * self.as_inner().e2ep() * self.as_inner().m()
+ T::TWO * operand.as_inner().y() * self.as_inner().e2em() * self.as_inner().epem()
+ operand.as_inner().ep() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().ep() * self.as_inner().m() * self.as_inner().m(),
-T::TWO * operand.as_inner().ep() * self.as_inner().e1em() * self.as_inner().e1ep()
+ -T::TWO
* operand.as_inner().ep()
* self.as_inner().e2em()
* self.as_inner().e2ep()
+ -T::TWO * operand.as_inner().y() * self.as_inner().e1em() * self.as_inner().m()
+ T::TWO * operand.as_inner().x() * self.as_inner().e1ep() * self.as_inner().epem()
+ T::TWO * operand.as_inner().x() * self.as_inner().e2em() * self.as_inner().m()
+ T::TWO * operand.as_inner().y() * self.as_inner().e2ep() * self.as_inner().epem()
+ operand.as_inner().em() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().em() * self.as_inner().e1ep() * self.as_inner().e1ep()
+ operand.as_inner().em() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().em() * self.as_inner().e2ep() * self.as_inner().e2ep()
+ operand.as_inner().em() * self.as_inner().epem() * self.as_inner().epem()
+ operand.as_inner().em() * self.as_inner().m() * self.as_inner().m(),
)
}
}
#[doc = "Antisandwich product: [`PointPair`] x [`Scalar`] x antirev([`PointPair`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Scalar<T>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
self.e1em() * operand.s() * self.e1em() - self.e1ep() * operand.s() * self.e1ep()
+ self.e2em() * operand.s() * self.e2em()
- self.e2ep() * operand.s() * self.e2ep()
+ self.epem() * operand.s() * self.epem()
- self.m() * operand.s() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Scalar<T>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.s() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.s() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.s() * self.as_inner().m() * self.as_inner().m())
+ operand.s() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.s() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.s() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Scalar<T>>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.e1ep() * self.e1ep())
+ -(operand.as_inner().s() * self.e2ep() * self.e2ep())
+ -(operand.as_inner().s() * self.m() * self.m())
+ operand.as_inner().s() * self.e1em() * self.e1em()
+ operand.as_inner().s() * self.e2em() * self.e2em()
+ operand.as_inner().s() * self.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Scalar<T>>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.as_inner().e1ep() * self.as_inner().e1ep())
+ -(operand.as_inner().s() * self.as_inner().e2ep() * self.as_inner().e2ep())
+ -(operand.as_inner().s() * self.as_inner().m() * self.as_inner().m())
+ operand.as_inner().s() * self.as_inner().e1em() * self.as_inner().e1em()
+ operand.as_inner().s() * self.as_inner().e2em() * self.as_inner().e2em()
+ operand.as_inner().s() * self.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Antisandwich product: [`Pseudoscalar`] x [`Circle`] x antirev([`Pseudoscalar`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Circle<T>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
self.ps() * operand.w() * self.ps(),
self.ps() * operand.e12em() * self.ps(),
self.ps() * operand.e1epem() * self.ps(),
self.ps() * operand.e2epem() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Circle<T>> for Unit<Pseudoscalar<T>> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
operand.w() * self.as_inner().ps() * self.as_inner().ps(),
operand.e12em() * self.as_inner().ps() * self.as_inner().ps(),
operand.e1epem() * self.as_inner().ps() * self.as_inner().ps(),
operand.e2epem() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Circle<T>>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
operand.as_inner().w() * self.ps() * self.ps(),
operand.as_inner().e12em() * self.ps() * self.ps(),
operand.as_inner().e1epem() * self.ps() * self.ps(),
operand.as_inner().e2epem() * self.ps() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Circle<T>>> for Unit<Pseudoscalar<T>> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
operand.as_inner().w() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().e12em() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().e1epem() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().e2epem() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[doc = "Antisandwich product: [`Pseudoscalar`] x [`FlatPoint`] x antirev([`Pseudoscalar`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<FlatPoint<T>> for Pseudoscalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
self.ps() * operand.e1em() * self.ps(),
self.ps() * operand.e2em() * self.ps(),
self.ps() * operand.epem() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<FlatPoint<T>> for Unit<Pseudoscalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
operand.e1em() * self.as_inner().ps() * self.as_inner().ps(),
operand.e2em() * self.as_inner().ps() * self.as_inner().ps(),
operand.epem() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<FlatPoint<T>>> for Pseudoscalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
operand.as_inner().e1em() * self.ps() * self.ps(),
operand.as_inner().e2em() * self.ps() * self.ps(),
operand.as_inner().epem() * self.ps() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<FlatPoint<T>>> for Unit<Pseudoscalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
operand.as_inner().e1em() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().e2em() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().epem() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[doc = "Antisandwich product: [`Pseudoscalar`] x [`Line`] x antirev([`Pseudoscalar`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Line<T>> for Pseudoscalar<T> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
self.ps() * operand.nx() * self.ps(),
self.ps() * operand.ny() * self.ps(),
self.ps() * operand.d() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Line<T>> for Unit<Pseudoscalar<T>> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
operand.nx() * self.as_inner().ps() * self.as_inner().ps(),
operand.ny() * self.as_inner().ps() * self.as_inner().ps(),
operand.d() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Line<T>>> for Pseudoscalar<T> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
operand.as_inner().nx() * self.ps() * self.ps(),
operand.as_inner().ny() * self.ps() * self.ps(),
operand.as_inner().d() * self.ps() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Line<T>>> for Unit<Pseudoscalar<T>> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
operand.as_inner().nx() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().ny() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().d() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[doc = "Antisandwich product: [`Pseudoscalar`] x [`Motor`] x antirev([`Pseudoscalar`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Motor<T>> for Pseudoscalar<T> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
self.ps() * operand.s() * self.ps(),
self.ps() * operand.m() * self.ps(),
self.ps() * operand.e1ep() * self.ps(),
self.ps() * operand.e2ep() * self.ps(),
self.ps() * operand.e1em() * self.ps(),
self.ps() * operand.e2em() * self.ps(),
self.ps() * operand.epem() * self.ps(),
self.ps() * operand.ps() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Motor<T>> for Unit<Pseudoscalar<T>> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
operand.s() * self.as_inner().ps() * self.as_inner().ps(),
operand.m() * self.as_inner().ps() * self.as_inner().ps(),
operand.e1ep() * self.as_inner().ps() * self.as_inner().ps(),
operand.e2ep() * self.as_inner().ps() * self.as_inner().ps(),
operand.e1em() * self.as_inner().ps() * self.as_inner().ps(),
operand.e2em() * self.as_inner().ps() * self.as_inner().ps(),
operand.epem() * self.as_inner().ps() * self.as_inner().ps(),
operand.ps() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Motor<T>>> for Pseudoscalar<T> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
operand.as_inner().s() * self.ps() * self.ps(),
operand.as_inner().m() * self.ps() * self.ps(),
operand.as_inner().e1ep() * self.ps() * self.ps(),
operand.as_inner().e2ep() * self.ps() * self.ps(),
operand.as_inner().e1em() * self.ps() * self.ps(),
operand.as_inner().e2em() * self.ps() * self.ps(),
operand.as_inner().epem() * self.ps() * self.ps(),
operand.as_inner().ps() * self.ps() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Motor<T>>> for Unit<Pseudoscalar<T>> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
operand.as_inner().s() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().m() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().e1ep() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().e2ep() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().e1em() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().e2em() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().epem() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().ps() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[doc = "Antisandwich product: [`Pseudoscalar`] x [`PointPair`] x antirev([`Pseudoscalar`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<PointPair<T>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
self.ps() * operand.m() * self.ps(),
self.ps() * operand.e1ep() * self.ps(),
self.ps() * operand.e2ep() * self.ps(),
self.ps() * operand.e1em() * self.ps(),
self.ps() * operand.e2em() * self.ps(),
self.ps() * operand.epem() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<PointPair<T>> for Unit<Pseudoscalar<T>> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
operand.m() * self.as_inner().ps() * self.as_inner().ps(),
operand.e1ep() * self.as_inner().ps() * self.as_inner().ps(),
operand.e2ep() * self.as_inner().ps() * self.as_inner().ps(),
operand.e1em() * self.as_inner().ps() * self.as_inner().ps(),
operand.e2em() * self.as_inner().ps() * self.as_inner().ps(),
operand.epem() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<PointPair<T>>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
operand.as_inner().m() * self.ps() * self.ps(),
operand.as_inner().e1ep() * self.ps() * self.ps(),
operand.as_inner().e2ep() * self.ps() * self.ps(),
operand.as_inner().e1em() * self.ps() * self.ps(),
operand.as_inner().e2em() * self.ps() * self.ps(),
operand.as_inner().epem() * self.ps() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<PointPair<T>>> for Unit<Pseudoscalar<T>> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
operand.as_inner().m() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().e1ep() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().e2ep() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().e1em() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().e2em() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().epem() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[doc = "Antisandwich product: [`Pseudoscalar`] x [`Pseudoscalar`] x antirev([`Pseudoscalar`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Pseudoscalar<T>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(self.ps() * operand.ps() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Pseudoscalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(operand.ps() * self.as_inner().ps() * self.as_inner().ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Pseudoscalar<T>>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(operand.as_inner().ps() * self.ps() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Pseudoscalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
operand.as_inner().ps() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[doc = "Antisandwich product: [`Pseudoscalar`] x [`RoundPoint`] x antirev([`Pseudoscalar`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<RoundPoint<T>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
self.ps() * operand.x() * self.ps(),
self.ps() * operand.y() * self.ps(),
self.ps() * operand.ep() * self.ps(),
self.ps() * operand.em() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<RoundPoint<T>> for Unit<Pseudoscalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
operand.x() * self.as_inner().ps() * self.as_inner().ps(),
operand.y() * self.as_inner().ps() * self.as_inner().ps(),
operand.ep() * self.as_inner().ps() * self.as_inner().ps(),
operand.em() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<RoundPoint<T>>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
operand.as_inner().x() * self.ps() * self.ps(),
operand.as_inner().y() * self.ps() * self.ps(),
operand.as_inner().ep() * self.ps() * self.ps(),
operand.as_inner().em() * self.ps() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<RoundPoint<T>>> for Unit<Pseudoscalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
operand.as_inner().x() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().y() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().ep() * self.as_inner().ps() * self.as_inner().ps(),
operand.as_inner().em() * self.as_inner().ps() * self.as_inner().ps(),
)
}
}
#[doc = "Antisandwich product: [`Pseudoscalar`] x [`Scalar`] x antirev([`Pseudoscalar`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Scalar<T>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(self.ps() * operand.s() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Scalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(operand.s() * self.as_inner().ps() * self.as_inner().ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Scalar<T>>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(operand.as_inner().s() * self.ps() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Scalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(operand.as_inner().s() * self.as_inner().ps() * self.as_inner().ps())
}
}
#[doc = "Antisandwich product: [`RoundPoint`] x [`Circle`] x antirev([`RoundPoint`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Circle<T>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-(self.em() * operand.e12em() * self.ep()) + self.em() * operand.e1epem() * self.y()
- self.em() * operand.e2epem() * self.x()
+ self.em() * operand.w() * self.em()
- self.ep() * operand.e12em() * self.em()
+ self.ep() * operand.w() * self.ep()
- self.x() * operand.e2epem() * self.em()
+ self.x() * operand.w() * self.x()
+ self.y() * operand.e1epem() * self.em()
+ self.y() * operand.w() * self.y(),
-(self.em() * operand.e12em() * self.em()) + self.em() * operand.w() * self.ep()
- self.ep() * operand.e12em() * self.ep()
+ self.ep() * operand.e1epem() * self.y()
- self.ep() * operand.e2epem() * self.x()
+ self.ep() * operand.w() * self.em()
+ self.x() * operand.e12em() * self.x()
- self.x() * operand.e2epem() * self.ep()
+ self.y() * operand.e12em() * self.y()
+ self.y() * operand.e1epem() * self.ep(),
-(self.em() * operand.e1epem() * self.em()) - self.em() * operand.w() * self.y()
+ self.ep() * operand.e12em() * self.y()
+ self.ep() * operand.e1epem() * self.ep()
+ self.x() * operand.e1epem() * self.x()
+ self.x() * operand.e2epem() * self.y()
+ self.y() * operand.e12em() * self.ep()
- self.y() * operand.e1epem() * self.y()
+ self.y() * operand.e2epem() * self.x()
- self.y() * operand.w() * self.em(),
-(self.em() * operand.e2epem() * self.em()) + self.em() * operand.w() * self.x()
- self.ep() * operand.e12em() * self.x()
+ self.ep() * operand.e2epem() * self.ep()
- self.x() * operand.e12em() * self.ep()
+ self.x() * operand.e1epem() * self.y()
- self.x() * operand.e2epem() * self.x()
+ self.x() * operand.w() * self.em()
+ self.y() * operand.e1epem() * self.x()
+ self.y() * operand.e2epem() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Circle<T>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.e12em() * self.as_inner().em() * self.as_inner().ep()
+ -T::TWO * operand.e2epem() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.e1epem() * self.as_inner().em() * self.as_inner().y()
+ operand.w() * self.as_inner().em() * self.as_inner().em()
+ operand.w() * self.as_inner().ep() * self.as_inner().ep()
+ operand.w() * self.as_inner().x() * self.as_inner().x()
+ operand.w() * self.as_inner().y() * self.as_inner().y(),
-(operand.e12em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.e12em() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO * operand.e2epem() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.e1epem() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.w() * self.as_inner().em() * self.as_inner().ep()
+ operand.e12em() * self.as_inner().x() * self.as_inner().x()
+ operand.e12em() * self.as_inner().y() * self.as_inner().y(),
-(operand.e1epem() * self.as_inner().em() * self.as_inner().em())
+ -(operand.e1epem() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.w() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.e12em() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.e2epem() * self.as_inner().x() * self.as_inner().y()
+ operand.e1epem() * self.as_inner().ep() * self.as_inner().ep()
+ operand.e1epem() * self.as_inner().x() * self.as_inner().x(),
-(operand.e2epem() * self.as_inner().em() * self.as_inner().em())
+ -(operand.e2epem() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.e12em() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.e1epem() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.w() * self.as_inner().em() * self.as_inner().x()
+ operand.e2epem() * self.as_inner().ep() * self.as_inner().ep()
+ operand.e2epem() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Circle<T>>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.as_inner().e12em() * self.em() * self.ep()
+ -T::TWO * operand.as_inner().e2epem() * self.em() * self.x()
+ T::TWO * operand.as_inner().e1epem() * self.em() * self.y()
+ operand.as_inner().w() * self.em() * self.em()
+ operand.as_inner().w() * self.ep() * self.ep()
+ operand.as_inner().w() * self.x() * self.x()
+ operand.as_inner().w() * self.y() * self.y(),
-(operand.as_inner().e12em() * self.em() * self.em())
+ -(operand.as_inner().e12em() * self.ep() * self.ep())
+ -T::TWO * operand.as_inner().e2epem() * self.ep() * self.x()
+ T::TWO * operand.as_inner().e1epem() * self.ep() * self.y()
+ T::TWO * operand.as_inner().w() * self.em() * self.ep()
+ operand.as_inner().e12em() * self.x() * self.x()
+ operand.as_inner().e12em() * self.y() * self.y(),
-(operand.as_inner().e1epem() * self.em() * self.em())
+ -(operand.as_inner().e1epem() * self.y() * self.y())
+ -T::TWO * operand.as_inner().w() * self.em() * self.y()
+ T::TWO * operand.as_inner().e12em() * self.ep() * self.y()
+ T::TWO * operand.as_inner().e2epem() * self.x() * self.y()
+ operand.as_inner().e1epem() * self.ep() * self.ep()
+ operand.as_inner().e1epem() * self.x() * self.x(),
-(operand.as_inner().e2epem() * self.em() * self.em())
+ -(operand.as_inner().e2epem() * self.x() * self.x())
+ -T::TWO * operand.as_inner().e12em() * self.ep() * self.x()
+ T::TWO * operand.as_inner().e1epem() * self.x() * self.y()
+ T::TWO * operand.as_inner().w() * self.em() * self.x()
+ operand.as_inner().e2epem() * self.ep() * self.ep()
+ operand.as_inner().e2epem() * self.y() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Circle<T>>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-T::TWO * operand.as_inner().e12em() * self.as_inner().em() * self.as_inner().ep()
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().em()
* self.as_inner().x()
+ T::TWO * operand.as_inner().e1epem() * self.as_inner().em() * self.as_inner().y()
+ operand.as_inner().w() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().w() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().w() * self.as_inner().x() * self.as_inner().x()
+ operand.as_inner().w() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().e12em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().e12em() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO
* operand.as_inner().e2epem()
* self.as_inner().ep()
* self.as_inner().x()
+ T::TWO * operand.as_inner().e1epem() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.as_inner().w() * self.as_inner().em() * self.as_inner().ep()
+ operand.as_inner().e12em() * self.as_inner().x() * self.as_inner().x()
+ operand.as_inner().e12em() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().e1epem() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().e1epem() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.as_inner().w() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.as_inner().e12em() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.as_inner().e2epem() * self.as_inner().x() * self.as_inner().y()
+ operand.as_inner().e1epem() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().e1epem() * self.as_inner().x() * self.as_inner().x(),
-(operand.as_inner().e2epem() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().e2epem() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.as_inner().e12em() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().e1epem() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.as_inner().w() * self.as_inner().em() * self.as_inner().x()
+ operand.as_inner().e2epem() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().e2epem() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[doc = "Antisandwich product: [`RoundPoint`] x [`FlatPoint`] x antirev([`RoundPoint`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<FlatPoint<T>> for RoundPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(self.em() * operand.e1em() * self.em()) - self.ep() * operand.e1em() * self.ep()
+ self.ep() * operand.epem() * self.x()
+ self.x() * operand.e1em() * self.x()
+ self.x() * operand.e2em() * self.y()
+ self.x() * operand.epem() * self.ep()
- self.y() * operand.e1em() * self.y()
+ self.y() * operand.e2em() * self.x(),
-(self.em() * operand.e2em() * self.em()) - self.ep() * operand.e2em() * self.ep()
+ self.ep() * operand.epem() * self.y()
+ self.x() * operand.e1em() * self.y()
- self.x() * operand.e2em() * self.x()
+ self.y() * operand.e1em() * self.x()
+ self.y() * operand.e2em() * self.y()
+ self.y() * operand.epem() * self.ep(),
-(self.em() * operand.epem() * self.em())
+ self.ep() * operand.e1em() * self.x()
+ self.ep() * operand.e2em() * self.y()
+ self.ep() * operand.epem() * self.ep()
+ self.x() * operand.e1em() * self.ep()
- self.x() * operand.epem() * self.x()
+ self.y() * operand.e2em() * self.ep()
- self.y() * operand.epem() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<FlatPoint<T>> for Unit<RoundPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.e1em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.e1em() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.e1em() * self.as_inner().y() * self.as_inner().y())
+ T::TWO * operand.e2em() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.epem() * self.as_inner().ep() * self.as_inner().x()
+ operand.e1em() * self.as_inner().x() * self.as_inner().x(),
-(operand.e2em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.e2em() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.e2em() * self.as_inner().x() * self.as_inner().x())
+ T::TWO * operand.e1em() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.epem() * self.as_inner().ep() * self.as_inner().y()
+ operand.e2em() * self.as_inner().y() * self.as_inner().y(),
-(operand.epem() * self.as_inner().em() * self.as_inner().em())
+ -(operand.epem() * self.as_inner().x() * self.as_inner().x())
+ -(operand.epem() * self.as_inner().y() * self.as_inner().y())
+ T::TWO * operand.e1em() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.e2em() * self.as_inner().ep() * self.as_inner().y()
+ operand.epem() * self.as_inner().ep() * self.as_inner().ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<FlatPoint<T>>> for RoundPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.em() * self.em())
+ -(operand.as_inner().e1em() * self.ep() * self.ep())
+ -(operand.as_inner().e1em() * self.y() * self.y())
+ T::TWO * operand.as_inner().e2em() * self.x() * self.y()
+ T::TWO * operand.as_inner().epem() * self.ep() * self.x()
+ operand.as_inner().e1em() * self.x() * self.x(),
-(operand.as_inner().e2em() * self.em() * self.em())
+ -(operand.as_inner().e2em() * self.ep() * self.ep())
+ -(operand.as_inner().e2em() * self.x() * self.x())
+ T::TWO * operand.as_inner().e1em() * self.x() * self.y()
+ T::TWO * operand.as_inner().epem() * self.ep() * self.y()
+ operand.as_inner().e2em() * self.y() * self.y(),
-(operand.as_inner().epem() * self.em() * self.em())
+ -(operand.as_inner().epem() * self.x() * self.x())
+ -(operand.as_inner().epem() * self.y() * self.y())
+ T::TWO * operand.as_inner().e1em() * self.ep() * self.x()
+ T::TWO * operand.as_inner().e2em() * self.ep() * self.y()
+ operand.as_inner().epem() * self.ep() * self.ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<FlatPoint<T>>> for Unit<RoundPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().e1em() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().e1em() * self.as_inner().y() * self.as_inner().y())
+ T::TWO * operand.as_inner().e2em() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().x()
+ operand.as_inner().e1em() * self.as_inner().x() * self.as_inner().x(),
-(operand.as_inner().e2em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().e2em() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().e2em() * self.as_inner().x() * self.as_inner().x())
+ T::TWO * operand.as_inner().e1em() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().y()
+ operand.as_inner().e2em() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().epem() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().epem() * self.as_inner().x() * self.as_inner().x())
+ -(operand.as_inner().epem() * self.as_inner().y() * self.as_inner().y())
+ T::TWO * operand.as_inner().e1em() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().ep() * self.as_inner().y()
+ operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().ep(),
)
}
}
#[doc = "Antisandwich product: [`RoundPoint`] x [`Line`] x antirev([`RoundPoint`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Line<T>> for RoundPoint<T> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(self.em() * operand.nx() * self.em())
- self.ep() * operand.d() * self.x()
- self.ep() * operand.nx() * self.ep()
+ self.ep() * operand.ny() * self.y()
- self.x() * operand.d() * self.ep()
+ self.x() * operand.nx() * self.x()
+ self.y() * operand.nx() * self.y()
+ self.y() * operand.ny() * self.ep(),
-(self.em() * operand.ny() * self.em())
+ self.ep() * operand.nx() * self.y()
+ self.ep() * operand.ny() * self.ep()
+ self.x() * operand.d() * self.y()
+ self.x() * operand.ny() * self.x()
+ self.y() * operand.d() * self.x()
+ self.y() * operand.nx() * self.ep()
- self.y() * operand.ny() * self.y(),
-(self.em() * operand.d() * self.em()) + self.ep() * operand.d() * self.ep()
- self.ep() * operand.nx() * self.x()
- self.x() * operand.d() * self.x()
- self.x() * operand.nx() * self.ep()
+ self.x() * operand.ny() * self.y()
+ self.y() * operand.d() * self.y()
+ self.y() * operand.ny() * self.x(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Line<T>> for Unit<RoundPoint<T>> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(operand.nx() * self.as_inner().em() * self.as_inner().em())
+ -(operand.nx() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO * operand.d() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.ny() * self.as_inner().ep() * self.as_inner().y()
+ operand.nx() * self.as_inner().x() * self.as_inner().x()
+ operand.nx() * self.as_inner().y() * self.as_inner().y(),
-(operand.ny() * self.as_inner().em() * self.as_inner().em())
+ -(operand.ny() * self.as_inner().y() * self.as_inner().y())
+ T::TWO * operand.d() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.nx() * self.as_inner().ep() * self.as_inner().y()
+ operand.ny() * self.as_inner().ep() * self.as_inner().ep()
+ operand.ny() * self.as_inner().x() * self.as_inner().x(),
-(operand.d() * self.as_inner().em() * self.as_inner().em())
+ -(operand.d() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.nx() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.ny() * self.as_inner().x() * self.as_inner().y()
+ operand.d() * self.as_inner().ep() * self.as_inner().ep()
+ operand.d() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Line<T>>> for RoundPoint<T> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.em() * self.em())
+ -(operand.as_inner().nx() * self.ep() * self.ep())
+ -T::TWO * operand.as_inner().d() * self.ep() * self.x()
+ T::TWO * operand.as_inner().ny() * self.ep() * self.y()
+ operand.as_inner().nx() * self.x() * self.x()
+ operand.as_inner().nx() * self.y() * self.y(),
-(operand.as_inner().ny() * self.em() * self.em())
+ -(operand.as_inner().ny() * self.y() * self.y())
+ T::TWO * operand.as_inner().d() * self.x() * self.y()
+ T::TWO * operand.as_inner().nx() * self.ep() * self.y()
+ operand.as_inner().ny() * self.ep() * self.ep()
+ operand.as_inner().ny() * self.x() * self.x(),
-(operand.as_inner().d() * self.em() * self.em())
+ -(operand.as_inner().d() * self.x() * self.x())
+ -T::TWO * operand.as_inner().nx() * self.ep() * self.x()
+ T::TWO * operand.as_inner().ny() * self.x() * self.y()
+ operand.as_inner().d() * self.ep() * self.ep()
+ operand.as_inner().d() * self.y() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Line<T>>> for Unit<RoundPoint<T>> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(operand.as_inner().nx() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().nx() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO * operand.as_inner().d() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().ny() * self.as_inner().ep() * self.as_inner().y()
+ operand.as_inner().nx() * self.as_inner().x() * self.as_inner().x()
+ operand.as_inner().nx() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().ny() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().ny() * self.as_inner().y() * self.as_inner().y())
+ T::TWO * operand.as_inner().d() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.as_inner().nx() * self.as_inner().ep() * self.as_inner().y()
+ operand.as_inner().ny() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().ny() * self.as_inner().x() * self.as_inner().x(),
-(operand.as_inner().d() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().d() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.as_inner().nx() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().ny() * self.as_inner().x() * self.as_inner().y()
+ operand.as_inner().d() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().d() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[doc = "Antisandwich product: [`RoundPoint`] x [`Motor`] x antirev([`RoundPoint`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Motor<T>> for RoundPoint<T> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
self.em() * operand.e1em() * self.x()
+ self.em() * operand.e2em() * self.y()
+ self.em() * operand.epem() * self.ep()
+ self.em() * operand.s() * self.em()
- self.ep() * operand.e1ep() * self.x()
- self.ep() * operand.e2ep() * self.y()
- self.ep() * operand.epem() * self.em()
- self.ep() * operand.s() * self.ep()
- self.x() * operand.e1em() * self.em()
+ self.x() * operand.e1ep() * self.ep()
+ self.x() * operand.m() * self.y()
- self.x() * operand.s() * self.x()
- self.y() * operand.e2em() * self.em()
+ self.y() * operand.e2ep() * self.ep()
- self.y() * operand.m() * self.x()
- self.y() * operand.s() * self.y(),
-(self.em() * operand.e1em() * self.y())
+ self.em() * operand.e2em() * self.x()
+ self.em() * operand.m() * self.em()
+ self.em() * operand.ps() * self.ep()
+ self.ep() * operand.e1ep() * self.y()
- self.ep() * operand.e2ep() * self.x()
- self.ep() * operand.m() * self.ep()
- self.ep() * operand.ps() * self.em()
+ self.x() * operand.e2em() * self.em()
- self.x() * operand.e2ep() * self.ep()
+ self.x() * operand.m() * self.x()
+ self.x() * operand.s() * self.y()
- self.y() * operand.e1em() * self.em()
+ self.y() * operand.e1ep() * self.ep()
+ self.y() * operand.m() * self.y()
- self.y() * operand.s() * self.x(),
-(self.em() * operand.e1em() * self.ep())
+ self.em() * operand.e1ep() * self.em()
+ self.em() * operand.epem() * self.x()
- self.em() * operand.ps() * self.y()
- self.ep() * operand.e1em() * self.em()
+ self.ep() * operand.e1ep() * self.ep()
+ self.ep() * operand.m() * self.y()
- self.ep() * operand.s() * self.x()
+ self.x() * operand.e1ep() * self.x()
+ self.x() * operand.e2ep() * self.y()
+ self.x() * operand.epem() * self.em()
+ self.x() * operand.s() * self.ep()
- self.y() * operand.e1ep() * self.y()
+ self.y() * operand.e2ep() * self.x()
+ self.y() * operand.m() * self.ep()
+ self.y() * operand.ps() * self.em(),
-(self.em() * operand.e2em() * self.ep())
+ self.em() * operand.e2ep() * self.em()
+ self.em() * operand.epem() * self.y()
+ self.em() * operand.ps() * self.x()
- self.ep() * operand.e2em() * self.em()
+ self.ep() * operand.e2ep() * self.ep()
- self.ep() * operand.m() * self.x()
- self.ep() * operand.s() * self.y()
+ self.x() * operand.e1ep() * self.y()
- self.x() * operand.e2ep() * self.x()
- self.x() * operand.m() * self.ep()
- self.x() * operand.ps() * self.em()
+ self.y() * operand.e1ep() * self.x()
+ self.y() * operand.e2ep() * self.y()
+ self.y() * operand.epem() * self.em()
+ self.y() * operand.s() * self.ep(),
-(self.em() * operand.e1em() * self.em())
+ self.em() * operand.e1ep() * self.ep()
+ self.em() * operand.m() * self.y()
- self.em() * operand.s() * self.x()
- self.ep() * operand.e1em() * self.ep()
+ self.ep() * operand.e1ep() * self.em()
+ self.ep() * operand.epem() * self.x()
- self.ep() * operand.ps() * self.y()
+ self.x() * operand.e1em() * self.x()
+ self.x() * operand.e2em() * self.y()
+ self.x() * operand.epem() * self.ep()
+ self.x() * operand.s() * self.em()
- self.y() * operand.e1em() * self.y()
+ self.y() * operand.e2em() * self.x()
+ self.y() * operand.m() * self.em()
+ self.y() * operand.ps() * self.ep(),
-(self.em() * operand.e2em() * self.em()) + self.em() * operand.e2ep() * self.ep()
- self.em() * operand.m() * self.x()
- self.em() * operand.s() * self.y()
- self.ep() * operand.e2em() * self.ep()
+ self.ep() * operand.e2ep() * self.em()
+ self.ep() * operand.epem() * self.y()
+ self.ep() * operand.ps() * self.x()
+ self.x() * operand.e1em() * self.y()
- self.x() * operand.e2em() * self.x()
- self.x() * operand.m() * self.em()
- self.x() * operand.ps() * self.ep()
+ self.y() * operand.e1em() * self.x()
+ self.y() * operand.e2em() * self.y()
+ self.y() * operand.epem() * self.ep()
+ self.y() * operand.s() * self.em(),
-(self.em() * operand.e1ep() * self.x())
- self.em() * operand.e2ep() * self.y()
- self.em() * operand.epem() * self.em()
- self.em() * operand.s() * self.ep()
+ self.ep() * operand.e1em() * self.x()
+ self.ep() * operand.e2em() * self.y()
+ self.ep() * operand.epem() * self.ep()
+ self.ep() * operand.s() * self.em()
+ self.x() * operand.e1em() * self.ep()
- self.x() * operand.e1ep() * self.em()
- self.x() * operand.epem() * self.x()
+ self.x() * operand.ps() * self.y()
+ self.y() * operand.e2em() * self.ep()
- self.y() * operand.e2ep() * self.em()
- self.y() * operand.epem() * self.y()
- self.y() * operand.ps() * self.x(),
self.em() * operand.e1ep() * self.y()
- self.em() * operand.e2ep() * self.x()
- self.em() * operand.m() * self.ep()
- self.em() * operand.ps() * self.em()
- self.ep() * operand.e1em() * self.y()
+ self.ep() * operand.e2em() * self.x()
+ self.ep() * operand.m() * self.em()
+ self.ep() * operand.ps() * self.ep()
- self.x() * operand.e2em() * self.ep()
+ self.x() * operand.e2ep() * self.em()
+ self.x() * operand.epem() * self.y()
+ self.x() * operand.ps() * self.x()
+ self.y() * operand.e1em() * self.ep()
- self.y() * operand.e1ep() * self.em()
- self.y() * operand.epem() * self.x()
+ self.y() * operand.ps() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Motor<T>> for Unit<RoundPoint<T>> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(operand.s() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.s() * self.as_inner().x() * self.as_inner().x())
+ -(operand.s() * self.as_inner().y() * self.as_inner().y())
+ operand.s() * self.as_inner().em() * self.as_inner().em(),
-(operand.m() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO * operand.e1em() * self.as_inner().em() * self.as_inner().y()
+ -T::TWO * operand.e2ep() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.e1ep() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.e2em() * self.as_inner().em() * self.as_inner().x()
+ operand.m() * self.as_inner().em() * self.as_inner().em()
+ operand.m() * self.as_inner().x() * self.as_inner().x()
+ operand.m() * self.as_inner().y() * self.as_inner().y(),
-(operand.e1ep() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.e1em() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.e2ep() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.epem() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.m() * self.as_inner().ep() * self.as_inner().y()
+ operand.e1ep() * self.as_inner().em() * self.as_inner().em()
+ operand.e1ep() * self.as_inner().ep() * self.as_inner().ep()
+ operand.e1ep() * self.as_inner().x() * self.as_inner().x(),
-(operand.e2ep() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.e2em() * self.as_inner().em() * self.as_inner().ep()
+ -T::TWO * operand.m() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.e1ep() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.epem() * self.as_inner().em() * self.as_inner().y()
+ operand.e2ep() * self.as_inner().em() * self.as_inner().em()
+ operand.e2ep() * self.as_inner().ep() * self.as_inner().ep()
+ operand.e2ep() * self.as_inner().y() * self.as_inner().y(),
-(operand.e1em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.e1em() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.e1em() * self.as_inner().y() * self.as_inner().y())
+ T::TWO * operand.e1ep() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.e2em() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.epem() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.m() * self.as_inner().em() * self.as_inner().y()
+ operand.e1em() * self.as_inner().x() * self.as_inner().x(),
-(operand.e2em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.e2em() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.e2em() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.m() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.e1em() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.e2ep() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.epem() * self.as_inner().ep() * self.as_inner().y()
+ operand.e2em() * self.as_inner().y() * self.as_inner().y(),
-(operand.epem() * self.as_inner().em() * self.as_inner().em())
+ -(operand.epem() * self.as_inner().x() * self.as_inner().x())
+ -(operand.epem() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.e1ep() * self.as_inner().em() * self.as_inner().x()
+ -T::TWO * operand.e2ep() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.e1em() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.e2em() * self.as_inner().ep() * self.as_inner().y()
+ operand.epem() * self.as_inner().ep() * self.as_inner().ep(),
-(operand.ps() * self.as_inner().em() * self.as_inner().em())
+ operand.ps() * self.as_inner().ep() * self.as_inner().ep()
+ operand.ps() * self.as_inner().x() * self.as_inner().x()
+ operand.ps() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Motor<T>>> for RoundPoint<T> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.ep() * self.ep())
+ -(operand.as_inner().s() * self.x() * self.x())
+ -(operand.as_inner().s() * self.y() * self.y())
+ operand.as_inner().s() * self.em() * self.em(),
-(operand.as_inner().m() * self.ep() * self.ep())
+ -T::TWO * operand.as_inner().e1em() * self.em() * self.y()
+ -T::TWO * operand.as_inner().e2ep() * self.ep() * self.x()
+ T::TWO * operand.as_inner().e1ep() * self.ep() * self.y()
+ T::TWO * operand.as_inner().e2em() * self.em() * self.x()
+ operand.as_inner().m() * self.em() * self.em()
+ operand.as_inner().m() * self.x() * self.x()
+ operand.as_inner().m() * self.y() * self.y(),
-(operand.as_inner().e1ep() * self.y() * self.y())
+ -T::TWO * operand.as_inner().e1em() * self.em() * self.ep()
+ T::TWO * operand.as_inner().e2ep() * self.x() * self.y()
+ T::TWO * operand.as_inner().epem() * self.em() * self.x()
+ T::TWO * operand.as_inner().m() * self.ep() * self.y()
+ operand.as_inner().e1ep() * self.em() * self.em()
+ operand.as_inner().e1ep() * self.ep() * self.ep()
+ operand.as_inner().e1ep() * self.x() * self.x(),
-(operand.as_inner().e2ep() * self.x() * self.x())
+ -T::TWO * operand.as_inner().e2em() * self.em() * self.ep()
+ -T::TWO * operand.as_inner().m() * self.ep() * self.x()
+ T::TWO * operand.as_inner().e1ep() * self.x() * self.y()
+ T::TWO * operand.as_inner().epem() * self.em() * self.y()
+ operand.as_inner().e2ep() * self.em() * self.em()
+ operand.as_inner().e2ep() * self.ep() * self.ep()
+ operand.as_inner().e2ep() * self.y() * self.y(),
-(operand.as_inner().e1em() * self.em() * self.em())
+ -(operand.as_inner().e1em() * self.ep() * self.ep())
+ -(operand.as_inner().e1em() * self.y() * self.y())
+ T::TWO * operand.as_inner().e1ep() * self.em() * self.ep()
+ T::TWO * operand.as_inner().e2em() * self.x() * self.y()
+ T::TWO * operand.as_inner().epem() * self.ep() * self.x()
+ T::TWO * operand.as_inner().m() * self.em() * self.y()
+ operand.as_inner().e1em() * self.x() * self.x(),
-(operand.as_inner().e2em() * self.em() * self.em())
+ -(operand.as_inner().e2em() * self.ep() * self.ep())
+ -(operand.as_inner().e2em() * self.x() * self.x())
+ -T::TWO * operand.as_inner().m() * self.em() * self.x()
+ T::TWO * operand.as_inner().e1em() * self.x() * self.y()
+ T::TWO * operand.as_inner().e2ep() * self.em() * self.ep()
+ T::TWO * operand.as_inner().epem() * self.ep() * self.y()
+ operand.as_inner().e2em() * self.y() * self.y(),
-(operand.as_inner().epem() * self.em() * self.em())
+ -(operand.as_inner().epem() * self.x() * self.x())
+ -(operand.as_inner().epem() * self.y() * self.y())
+ -T::TWO * operand.as_inner().e1ep() * self.em() * self.x()
+ -T::TWO * operand.as_inner().e2ep() * self.em() * self.y()
+ T::TWO * operand.as_inner().e1em() * self.ep() * self.x()
+ T::TWO * operand.as_inner().e2em() * self.ep() * self.y()
+ operand.as_inner().epem() * self.ep() * self.ep(),
-(operand.as_inner().ps() * self.em() * self.em())
+ operand.as_inner().ps() * self.ep() * self.ep()
+ operand.as_inner().ps() * self.x() * self.x()
+ operand.as_inner().ps() * self.y() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Motor<T>>> for Unit<RoundPoint<T>> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().s() * self.as_inner().x() * self.as_inner().x())
+ -(operand.as_inner().s() * self.as_inner().y() * self.as_inner().y())
+ operand.as_inner().s() * self.as_inner().em() * self.as_inner().em(),
-(operand.as_inner().m() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().em() * self.as_inner().y()
+ -T::TWO * operand.as_inner().e2ep() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().em() * self.as_inner().x()
+ operand.as_inner().m() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().m() * self.as_inner().x() * self.as_inner().x()
+ operand.as_inner().m() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().e1ep() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.as_inner().epem() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.as_inner().m() * self.as_inner().ep() * self.as_inner().y()
+ operand.as_inner().e1ep() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().e1ep() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().e1ep() * self.as_inner().x() * self.as_inner().x(),
-(operand.as_inner().e2ep() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().em() * self.as_inner().ep()
+ -T::TWO * operand.as_inner().m() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.as_inner().epem() * self.as_inner().em() * self.as_inner().y()
+ operand.as_inner().e2ep() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().e2ep() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().e2ep() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().e1em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().e1em() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().e1em() * self.as_inner().y() * self.as_inner().y())
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().m() * self.as_inner().em() * self.as_inner().y()
+ operand.as_inner().e1em() * self.as_inner().x() * self.as_inner().x(),
-(operand.as_inner().e2em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().e2em() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().e2em() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.as_inner().m() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().y()
+ operand.as_inner().e2em() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().epem() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().epem() * self.as_inner().x() * self.as_inner().x())
+ -(operand.as_inner().epem() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().em() * self.as_inner().x()
+ -T::TWO * operand.as_inner().e2ep() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().ep() * self.as_inner().y()
+ operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().ep(),
-(operand.as_inner().ps() * self.as_inner().em() * self.as_inner().em())
+ operand.as_inner().ps() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().ps() * self.as_inner().x() * self.as_inner().x()
+ operand.as_inner().ps() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[doc = "Antisandwich product: [`RoundPoint`] x [`PointPair`] x antirev([`RoundPoint`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<PointPair<T>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(self.em() * operand.e1em() * self.y())
+ self.em() * operand.e2em() * self.x()
+ self.em() * operand.m() * self.em()
+ self.ep() * operand.e1ep() * self.y()
- self.ep() * operand.e2ep() * self.x()
- self.ep() * operand.m() * self.ep()
+ self.x() * operand.e2em() * self.em()
- self.x() * operand.e2ep() * self.ep()
+ self.x() * operand.m() * self.x()
- self.y() * operand.e1em() * self.em()
+ self.y() * operand.e1ep() * self.ep()
+ self.y() * operand.m() * self.y(),
-(self.em() * operand.e1em() * self.ep())
+ self.em() * operand.e1ep() * self.em()
+ self.em() * operand.epem() * self.x()
- self.ep() * operand.e1em() * self.em()
+ self.ep() * operand.e1ep() * self.ep()
+ self.ep() * operand.m() * self.y()
+ self.x() * operand.e1ep() * self.x()
+ self.x() * operand.e2ep() * self.y()
+ self.x() * operand.epem() * self.em()
- self.y() * operand.e1ep() * self.y()
+ self.y() * operand.e2ep() * self.x()
+ self.y() * operand.m() * self.ep(),
-(self.em() * operand.e2em() * self.ep())
+ self.em() * operand.e2ep() * self.em()
+ self.em() * operand.epem() * self.y()
- self.ep() * operand.e2em() * self.em()
+ self.ep() * operand.e2ep() * self.ep()
- self.ep() * operand.m() * self.x()
+ self.x() * operand.e1ep() * self.y()
- self.x() * operand.e2ep() * self.x()
- self.x() * operand.m() * self.ep()
+ self.y() * operand.e1ep() * self.x()
+ self.y() * operand.e2ep() * self.y()
+ self.y() * operand.epem() * self.em(),
-(self.em() * operand.e1em() * self.em())
+ self.em() * operand.e1ep() * self.ep()
+ self.em() * operand.m() * self.y()
- self.ep() * operand.e1em() * self.ep()
+ self.ep() * operand.e1ep() * self.em()
+ self.ep() * operand.epem() * self.x()
+ self.x() * operand.e1em() * self.x()
+ self.x() * operand.e2em() * self.y()
+ self.x() * operand.epem() * self.ep()
- self.y() * operand.e1em() * self.y()
+ self.y() * operand.e2em() * self.x()
+ self.y() * operand.m() * self.em(),
-(self.em() * operand.e2em() * self.em()) + self.em() * operand.e2ep() * self.ep()
- self.em() * operand.m() * self.x()
- self.ep() * operand.e2em() * self.ep()
+ self.ep() * operand.e2ep() * self.em()
+ self.ep() * operand.epem() * self.y()
+ self.x() * operand.e1em() * self.y()
- self.x() * operand.e2em() * self.x()
- self.x() * operand.m() * self.em()
+ self.y() * operand.e1em() * self.x()
+ self.y() * operand.e2em() * self.y()
+ self.y() * operand.epem() * self.ep(),
-(self.em() * operand.e1ep() * self.x())
- self.em() * operand.e2ep() * self.y()
- self.em() * operand.epem() * self.em()
+ self.ep() * operand.e1em() * self.x()
+ self.ep() * operand.e2em() * self.y()
+ self.ep() * operand.epem() * self.ep()
+ self.x() * operand.e1em() * self.ep()
- self.x() * operand.e1ep() * self.em()
- self.x() * operand.epem() * self.x()
+ self.y() * operand.e2em() * self.ep()
- self.y() * operand.e2ep() * self.em()
- self.y() * operand.epem() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<PointPair<T>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.m() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO * operand.e1em() * self.as_inner().em() * self.as_inner().y()
+ -T::TWO * operand.e2ep() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.e1ep() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.e2em() * self.as_inner().em() * self.as_inner().x()
+ operand.m() * self.as_inner().em() * self.as_inner().em()
+ operand.m() * self.as_inner().x() * self.as_inner().x()
+ operand.m() * self.as_inner().y() * self.as_inner().y(),
-(operand.e1ep() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.e1em() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.e2ep() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.epem() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.m() * self.as_inner().ep() * self.as_inner().y()
+ operand.e1ep() * self.as_inner().em() * self.as_inner().em()
+ operand.e1ep() * self.as_inner().ep() * self.as_inner().ep()
+ operand.e1ep() * self.as_inner().x() * self.as_inner().x(),
-(operand.e2ep() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.e2em() * self.as_inner().em() * self.as_inner().ep()
+ -T::TWO * operand.m() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.e1ep() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.epem() * self.as_inner().em() * self.as_inner().y()
+ operand.e2ep() * self.as_inner().em() * self.as_inner().em()
+ operand.e2ep() * self.as_inner().ep() * self.as_inner().ep()
+ operand.e2ep() * self.as_inner().y() * self.as_inner().y(),
-(operand.e1em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.e1em() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.e1em() * self.as_inner().y() * self.as_inner().y())
+ T::TWO * operand.e1ep() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.e2em() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.epem() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.m() * self.as_inner().em() * self.as_inner().y()
+ operand.e1em() * self.as_inner().x() * self.as_inner().x(),
-(operand.e2em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.e2em() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.e2em() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.m() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.e1em() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.e2ep() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.epem() * self.as_inner().ep() * self.as_inner().y()
+ operand.e2em() * self.as_inner().y() * self.as_inner().y(),
-(operand.epem() * self.as_inner().em() * self.as_inner().em())
+ -(operand.epem() * self.as_inner().x() * self.as_inner().x())
+ -(operand.epem() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.e1ep() * self.as_inner().em() * self.as_inner().x()
+ -T::TWO * operand.e2ep() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.e1em() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.e2em() * self.as_inner().ep() * self.as_inner().y()
+ operand.epem() * self.as_inner().ep() * self.as_inner().ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<PointPair<T>>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.ep() * self.ep())
+ -T::TWO * operand.as_inner().e1em() * self.em() * self.y()
+ -T::TWO * operand.as_inner().e2ep() * self.ep() * self.x()
+ T::TWO * operand.as_inner().e1ep() * self.ep() * self.y()
+ T::TWO * operand.as_inner().e2em() * self.em() * self.x()
+ operand.as_inner().m() * self.em() * self.em()
+ operand.as_inner().m() * self.x() * self.x()
+ operand.as_inner().m() * self.y() * self.y(),
-(operand.as_inner().e1ep() * self.y() * self.y())
+ -T::TWO * operand.as_inner().e1em() * self.em() * self.ep()
+ T::TWO * operand.as_inner().e2ep() * self.x() * self.y()
+ T::TWO * operand.as_inner().epem() * self.em() * self.x()
+ T::TWO * operand.as_inner().m() * self.ep() * self.y()
+ operand.as_inner().e1ep() * self.em() * self.em()
+ operand.as_inner().e1ep() * self.ep() * self.ep()
+ operand.as_inner().e1ep() * self.x() * self.x(),
-(operand.as_inner().e2ep() * self.x() * self.x())
+ -T::TWO * operand.as_inner().e2em() * self.em() * self.ep()
+ -T::TWO * operand.as_inner().m() * self.ep() * self.x()
+ T::TWO * operand.as_inner().e1ep() * self.x() * self.y()
+ T::TWO * operand.as_inner().epem() * self.em() * self.y()
+ operand.as_inner().e2ep() * self.em() * self.em()
+ operand.as_inner().e2ep() * self.ep() * self.ep()
+ operand.as_inner().e2ep() * self.y() * self.y(),
-(operand.as_inner().e1em() * self.em() * self.em())
+ -(operand.as_inner().e1em() * self.ep() * self.ep())
+ -(operand.as_inner().e1em() * self.y() * self.y())
+ T::TWO * operand.as_inner().e1ep() * self.em() * self.ep()
+ T::TWO * operand.as_inner().e2em() * self.x() * self.y()
+ T::TWO * operand.as_inner().epem() * self.ep() * self.x()
+ T::TWO * operand.as_inner().m() * self.em() * self.y()
+ operand.as_inner().e1em() * self.x() * self.x(),
-(operand.as_inner().e2em() * self.em() * self.em())
+ -(operand.as_inner().e2em() * self.ep() * self.ep())
+ -(operand.as_inner().e2em() * self.x() * self.x())
+ -T::TWO * operand.as_inner().m() * self.em() * self.x()
+ T::TWO * operand.as_inner().e1em() * self.x() * self.y()
+ T::TWO * operand.as_inner().e2ep() * self.em() * self.ep()
+ T::TWO * operand.as_inner().epem() * self.ep() * self.y()
+ operand.as_inner().e2em() * self.y() * self.y(),
-(operand.as_inner().epem() * self.em() * self.em())
+ -(operand.as_inner().epem() * self.x() * self.x())
+ -(operand.as_inner().epem() * self.y() * self.y())
+ -T::TWO * operand.as_inner().e1ep() * self.em() * self.x()
+ -T::TWO * operand.as_inner().e2ep() * self.em() * self.y()
+ T::TWO * operand.as_inner().e1em() * self.ep() * self.x()
+ T::TWO * operand.as_inner().e2em() * self.ep() * self.y()
+ operand.as_inner().epem() * self.ep() * self.ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<PointPair<T>>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.as_inner().ep() * self.as_inner().ep())
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().em() * self.as_inner().y()
+ -T::TWO * operand.as_inner().e2ep() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().em() * self.as_inner().x()
+ operand.as_inner().m() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().m() * self.as_inner().x() * self.as_inner().x()
+ operand.as_inner().m() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().e1ep() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.as_inner().e1em() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.as_inner().epem() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.as_inner().m() * self.as_inner().ep() * self.as_inner().y()
+ operand.as_inner().e1ep() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().e1ep() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().e1ep() * self.as_inner().x() * self.as_inner().x(),
-(operand.as_inner().e2ep() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.as_inner().e2em() * self.as_inner().em() * self.as_inner().ep()
+ -T::TWO * operand.as_inner().m() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.as_inner().epem() * self.as_inner().em() * self.as_inner().y()
+ operand.as_inner().e2ep() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().e2ep() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().e2ep() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().e1em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().e1em() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().e1em() * self.as_inner().y() * self.as_inner().y())
+ T::TWO * operand.as_inner().e1ep() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().m() * self.as_inner().em() * self.as_inner().y()
+ operand.as_inner().e1em() * self.as_inner().x() * self.as_inner().x(),
-(operand.as_inner().e2em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().e2em() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().e2em() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.as_inner().m() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().x() * self.as_inner().y()
+ T::TWO * operand.as_inner().e2ep() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().y()
+ operand.as_inner().e2em() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().epem() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().epem() * self.as_inner().x() * self.as_inner().x())
+ -(operand.as_inner().epem() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.as_inner().e1ep() * self.as_inner().em() * self.as_inner().x()
+ -T::TWO * operand.as_inner().e2ep() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.as_inner().e1em() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().e2em() * self.as_inner().ep() * self.as_inner().y()
+ operand.as_inner().epem() * self.as_inner().ep() * self.as_inner().ep(),
)
}
}
#[doc = "Antisandwich product: [`RoundPoint`] x [`Pseudoscalar`] x antirev([`RoundPoint`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Pseudoscalar<T>> for RoundPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(self.em() * operand.ps() * self.em())
+ self.ep() * operand.ps() * self.ep()
+ self.x() * operand.ps() * self.x()
+ self.y() * operand.ps() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Pseudoscalar<T>> for Unit<RoundPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.ps() * self.as_inner().em() * self.as_inner().em())
+ operand.ps() * self.as_inner().ep() * self.as_inner().ep()
+ operand.ps() * self.as_inner().x() * self.as_inner().x()
+ operand.ps() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Pseudoscalar<T>>> for RoundPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.em() * self.em())
+ operand.as_inner().ps() * self.ep() * self.ep()
+ operand.as_inner().ps() * self.x() * self.x()
+ operand.as_inner().ps() * self.y() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Pseudoscalar<T>>> for Unit<RoundPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.as_inner().em() * self.as_inner().em())
+ operand.as_inner().ps() * self.as_inner().ep() * self.as_inner().ep()
+ operand.as_inner().ps() * self.as_inner().x() * self.as_inner().x()
+ operand.as_inner().ps() * self.as_inner().y() * self.as_inner().y(),
)
}
}
#[doc = "Antisandwich product: [`RoundPoint`] x [`RoundPoint`] x antirev([`RoundPoint`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<RoundPoint<T>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(self.em() * operand.em() * self.x())
+ self.em() * operand.x() * self.em()
+ self.ep() * operand.ep() * self.x()
- self.ep() * operand.x() * self.ep()
- self.x() * operand.em() * self.em()
+ self.x() * operand.ep() * self.ep()
+ self.x() * operand.x() * self.x()
+ self.x() * operand.y() * self.y()
- self.y() * operand.x() * self.y()
+ self.y() * operand.y() * self.x(),
-(self.em() * operand.em() * self.y())
+ self.em() * operand.y() * self.em()
+ self.ep() * operand.ep() * self.y()
- self.ep() * operand.y() * self.ep()
+ self.x() * operand.x() * self.y()
- self.x() * operand.y() * self.x()
- self.y() * operand.em() * self.em()
+ self.y() * operand.ep() * self.ep()
+ self.y() * operand.x() * self.x()
+ self.y() * operand.y() * self.y(),
-(self.em() * operand.em() * self.ep()) + self.em() * operand.ep() * self.em()
- self.ep() * operand.em() * self.em()
+ self.ep() * operand.ep() * self.ep()
+ self.ep() * operand.x() * self.x()
+ self.ep() * operand.y() * self.y()
- self.x() * operand.ep() * self.x()
+ self.x() * operand.x() * self.ep()
- self.y() * operand.ep() * self.y()
+ self.y() * operand.y() * self.ep(),
-(self.em() * operand.em() * self.em())
+ self.em() * operand.ep() * self.ep()
+ self.em() * operand.x() * self.x()
+ self.em() * operand.y() * self.y()
- self.ep() * operand.em() * self.ep()
+ self.ep() * operand.ep() * self.em()
- self.x() * operand.em() * self.x()
+ self.x() * operand.x() * self.em()
- self.y() * operand.em() * self.y()
+ self.y() * operand.y() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<RoundPoint<T>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.x() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.x() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.em() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.ep() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.y() * self.as_inner().x() * self.as_inner().y()
+ operand.x() * self.as_inner().em() * self.as_inner().em()
+ operand.x() * self.as_inner().x() * self.as_inner().x(),
-(operand.y() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.y() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.em() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.ep() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.x() * self.as_inner().x() * self.as_inner().y()
+ operand.y() * self.as_inner().em() * self.as_inner().em()
+ operand.y() * self.as_inner().y() * self.as_inner().y(),
-(operand.ep() * self.as_inner().x() * self.as_inner().x())
+ -(operand.ep() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.em() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.x() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.y() * self.as_inner().ep() * self.as_inner().y()
+ operand.ep() * self.as_inner().em() * self.as_inner().em()
+ operand.ep() * self.as_inner().ep() * self.as_inner().ep(),
-(operand.em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.em() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.em() * self.as_inner().x() * self.as_inner().x())
+ -(operand.em() * self.as_inner().y() * self.as_inner().y())
+ T::TWO * operand.ep() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.x() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.y() * self.as_inner().em() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<RoundPoint<T>>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.ep() * self.ep())
+ -(operand.as_inner().x() * self.y() * self.y())
+ -T::TWO * operand.as_inner().em() * self.em() * self.x()
+ T::TWO * operand.as_inner().ep() * self.ep() * self.x()
+ T::TWO * operand.as_inner().y() * self.x() * self.y()
+ operand.as_inner().x() * self.em() * self.em()
+ operand.as_inner().x() * self.x() * self.x(),
-(operand.as_inner().y() * self.ep() * self.ep())
+ -(operand.as_inner().y() * self.x() * self.x())
+ -T::TWO * operand.as_inner().em() * self.em() * self.y()
+ T::TWO * operand.as_inner().ep() * self.ep() * self.y()
+ T::TWO * operand.as_inner().x() * self.x() * self.y()
+ operand.as_inner().y() * self.em() * self.em()
+ operand.as_inner().y() * self.y() * self.y(),
-(operand.as_inner().ep() * self.x() * self.x())
+ -(operand.as_inner().ep() * self.y() * self.y())
+ -T::TWO * operand.as_inner().em() * self.em() * self.ep()
+ T::TWO * operand.as_inner().x() * self.ep() * self.x()
+ T::TWO * operand.as_inner().y() * self.ep() * self.y()
+ operand.as_inner().ep() * self.em() * self.em()
+ operand.as_inner().ep() * self.ep() * self.ep(),
-(operand.as_inner().em() * self.em() * self.em())
+ -(operand.as_inner().em() * self.ep() * self.ep())
+ -(operand.as_inner().em() * self.x() * self.x())
+ -(operand.as_inner().em() * self.y() * self.y())
+ T::TWO * operand.as_inner().ep() * self.em() * self.ep()
+ T::TWO * operand.as_inner().x() * self.em() * self.x()
+ T::TWO * operand.as_inner().y() * self.em() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<RoundPoint<T>>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(operand.as_inner().x() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().x() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.as_inner().em() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.as_inner().ep() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().y() * self.as_inner().x() * self.as_inner().y()
+ operand.as_inner().x() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().x() * self.as_inner().x() * self.as_inner().x(),
-(operand.as_inner().y() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().y() * self.as_inner().x() * self.as_inner().x())
+ -T::TWO * operand.as_inner().em() * self.as_inner().em() * self.as_inner().y()
+ T::TWO * operand.as_inner().ep() * self.as_inner().ep() * self.as_inner().y()
+ T::TWO * operand.as_inner().x() * self.as_inner().x() * self.as_inner().y()
+ operand.as_inner().y() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().y() * self.as_inner().y() * self.as_inner().y(),
-(operand.as_inner().ep() * self.as_inner().x() * self.as_inner().x())
+ -(operand.as_inner().ep() * self.as_inner().y() * self.as_inner().y())
+ -T::TWO * operand.as_inner().em() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.as_inner().x() * self.as_inner().ep() * self.as_inner().x()
+ T::TWO * operand.as_inner().y() * self.as_inner().ep() * self.as_inner().y()
+ operand.as_inner().ep() * self.as_inner().em() * self.as_inner().em()
+ operand.as_inner().ep() * self.as_inner().ep() * self.as_inner().ep(),
-(operand.as_inner().em() * self.as_inner().em() * self.as_inner().em())
+ -(operand.as_inner().em() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().em() * self.as_inner().x() * self.as_inner().x())
+ -(operand.as_inner().em() * self.as_inner().y() * self.as_inner().y())
+ T::TWO * operand.as_inner().ep() * self.as_inner().em() * self.as_inner().ep()
+ T::TWO * operand.as_inner().x() * self.as_inner().em() * self.as_inner().x()
+ T::TWO * operand.as_inner().y() * self.as_inner().em() * self.as_inner().y(),
)
}
}
#[doc = "Antisandwich product: [`RoundPoint`] x [`Scalar`] x antirev([`RoundPoint`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Scalar<T>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
self.em() * operand.s() * self.em()
- self.ep() * operand.s() * self.ep()
- self.x() * operand.s() * self.x()
- self.y() * operand.s() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Scalar<T>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.s() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.s() * self.as_inner().x() * self.as_inner().x())
+ -(operand.s() * self.as_inner().y() * self.as_inner().y())
+ operand.s() * self.as_inner().em() * self.as_inner().em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Scalar<T>>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.ep() * self.ep())
+ -(operand.as_inner().s() * self.x() * self.x())
+ -(operand.as_inner().s() * self.y() * self.y())
+ operand.as_inner().s() * self.em() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Scalar<T>>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(operand.as_inner().s() * self.as_inner().ep() * self.as_inner().ep())
+ -(operand.as_inner().s() * self.as_inner().x() * self.as_inner().x())
+ -(operand.as_inner().s() * self.as_inner().y() * self.as_inner().y())
+ operand.as_inner().s() * self.as_inner().em() * self.as_inner().em(),
)
}
}
#[doc = "Antisandwich product: [`Scalar`] x [`Circle`] x antirev([`Scalar`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Circle<T>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
self.s() * operand.w() * self.s(),
self.s() * operand.e12em() * self.s(),
self.s() * operand.e1epem() * self.s(),
self.s() * operand.e2epem() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Circle<T>> for Unit<Scalar<T>> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
operand.w() * self.as_inner().s() * self.as_inner().s(),
operand.e12em() * self.as_inner().s() * self.as_inner().s(),
operand.e1epem() * self.as_inner().s() * self.as_inner().s(),
operand.e2epem() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Circle<T>>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
operand.as_inner().w() * self.s() * self.s(),
operand.as_inner().e12em() * self.s() * self.s(),
operand.as_inner().e1epem() * self.s() * self.s(),
operand.as_inner().e2epem() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Circle<T>>> for Unit<Scalar<T>> {
type Output = Circle<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
operand.as_inner().w() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().e12em() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().e1epem() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().e2epem() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Antisandwich product: [`Scalar`] x [`FlatPoint`] x antirev([`Scalar`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<FlatPoint<T>> for Scalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(self.s() * operand.e1em() * self.s()),
-(self.s() * operand.e2em() * self.s()),
-(self.s() * operand.epem() * self.s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<FlatPoint<T>> for Unit<Scalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.e1em() * self.as_inner().s() * self.as_inner().s()),
-(operand.e2em() * self.as_inner().s() * self.as_inner().s()),
-(operand.epem() * self.as_inner().s() * self.as_inner().s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<FlatPoint<T>>> for Scalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.s() * self.s()),
-(operand.as_inner().e2em() * self.s() * self.s()),
-(operand.as_inner().epem() * self.s() * self.s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<FlatPoint<T>>> for Unit<Scalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(operand.as_inner().e1em() * self.as_inner().s() * self.as_inner().s()),
-(operand.as_inner().e2em() * self.as_inner().s() * self.as_inner().s()),
-(operand.as_inner().epem() * self.as_inner().s() * self.as_inner().s()),
)
}
}
#[doc = "Antisandwich product: [`Scalar`] x [`Line`] x antirev([`Scalar`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Line<T>> for Scalar<T> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
self.s() * operand.nx() * self.s(),
self.s() * operand.ny() * self.s(),
self.s() * operand.d() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Line<T>> for Unit<Scalar<T>> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Line<T>) -> Line<T> {
Line::new_unchecked(
operand.nx() * self.as_inner().s() * self.as_inner().s(),
operand.ny() * self.as_inner().s() * self.as_inner().s(),
operand.d() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Line<T>>> for Scalar<T> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
operand.as_inner().nx() * self.s() * self.s(),
operand.as_inner().ny() * self.s() * self.s(),
operand.as_inner().d() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Line<T>>> for Unit<Scalar<T>> {
type Output = Line<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
operand.as_inner().nx() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().ny() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().d() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Antisandwich product: [`Scalar`] x [`Motor`] x antirev([`Scalar`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Motor<T>> for Scalar<T> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(self.s() * operand.s() * self.s()),
-(self.s() * operand.m() * self.s()),
-(self.s() * operand.e1ep() * self.s()),
-(self.s() * operand.e2ep() * self.s()),
-(self.s() * operand.e1em() * self.s()),
-(self.s() * operand.e2em() * self.s()),
-(self.s() * operand.epem() * self.s()),
-(self.s() * operand.ps() * self.s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Motor<T>> for Unit<Scalar<T>> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Motor<T>) -> Motor<T> {
Motor::new_unchecked(
-(operand.s() * self.as_inner().s() * self.as_inner().s()),
-(operand.m() * self.as_inner().s() * self.as_inner().s()),
-(operand.e1ep() * self.as_inner().s() * self.as_inner().s()),
-(operand.e2ep() * self.as_inner().s() * self.as_inner().s()),
-(operand.e1em() * self.as_inner().s() * self.as_inner().s()),
-(operand.e2em() * self.as_inner().s() * self.as_inner().s()),
-(operand.epem() * self.as_inner().s() * self.as_inner().s()),
-(operand.ps() * self.as_inner().s() * self.as_inner().s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Motor<T>>> for Scalar<T> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.s() * self.s()),
-(operand.as_inner().m() * self.s() * self.s()),
-(operand.as_inner().e1ep() * self.s() * self.s()),
-(operand.as_inner().e2ep() * self.s() * self.s()),
-(operand.as_inner().e1em() * self.s() * self.s()),
-(operand.as_inner().e2em() * self.s() * self.s()),
-(operand.as_inner().epem() * self.s() * self.s()),
-(operand.as_inner().ps() * self.s() * self.s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Motor<T>>> for Unit<Scalar<T>> {
type Output = Motor<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
Motor::new_unchecked(
-(operand.as_inner().s() * self.as_inner().s() * self.as_inner().s()),
-(operand.as_inner().m() * self.as_inner().s() * self.as_inner().s()),
-(operand.as_inner().e1ep() * self.as_inner().s() * self.as_inner().s()),
-(operand.as_inner().e2ep() * self.as_inner().s() * self.as_inner().s()),
-(operand.as_inner().e1em() * self.as_inner().s() * self.as_inner().s()),
-(operand.as_inner().e2em() * self.as_inner().s() * self.as_inner().s()),
-(operand.as_inner().epem() * self.as_inner().s() * self.as_inner().s()),
-(operand.as_inner().ps() * self.as_inner().s() * self.as_inner().s()),
)
}
}
#[doc = "Antisandwich product: [`Scalar`] x [`PointPair`] x antirev([`Scalar`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<PointPair<T>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(self.s() * operand.m() * self.s()),
-(self.s() * operand.e1ep() * self.s()),
-(self.s() * operand.e2ep() * self.s()),
-(self.s() * operand.e1em() * self.s()),
-(self.s() * operand.e2em() * self.s()),
-(self.s() * operand.epem() * self.s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<PointPair<T>> for Unit<Scalar<T>> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.m() * self.as_inner().s() * self.as_inner().s()),
-(operand.e1ep() * self.as_inner().s() * self.as_inner().s()),
-(operand.e2ep() * self.as_inner().s() * self.as_inner().s()),
-(operand.e1em() * self.as_inner().s() * self.as_inner().s()),
-(operand.e2em() * self.as_inner().s() * self.as_inner().s()),
-(operand.epem() * self.as_inner().s() * self.as_inner().s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<PointPair<T>>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.s() * self.s()),
-(operand.as_inner().e1ep() * self.s() * self.s()),
-(operand.as_inner().e2ep() * self.s() * self.s()),
-(operand.as_inner().e1em() * self.s() * self.s()),
-(operand.as_inner().e2em() * self.s() * self.s()),
-(operand.as_inner().epem() * self.s() * self.s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<PointPair<T>>> for Unit<Scalar<T>> {
type Output = PointPair<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(operand.as_inner().m() * self.as_inner().s() * self.as_inner().s()),
-(operand.as_inner().e1ep() * self.as_inner().s() * self.as_inner().s()),
-(operand.as_inner().e2ep() * self.as_inner().s() * self.as_inner().s()),
-(operand.as_inner().e1em() * self.as_inner().s() * self.as_inner().s()),
-(operand.as_inner().e2em() * self.as_inner().s() * self.as_inner().s()),
-(operand.as_inner().epem() * self.as_inner().s() * self.as_inner().s()),
)
}
}
#[doc = "Antisandwich product: [`Scalar`] x [`Pseudoscalar`] x antirev([`Scalar`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Pseudoscalar<T>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(self.s() * operand.ps() * self.s()))
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Pseudoscalar<T>> for Unit<Scalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(operand.ps() * self.as_inner().s() * self.as_inner().s()))
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Pseudoscalar<T>>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(operand.as_inner().ps() * self.s() * self.s()))
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Pseudoscalar<T>>> for Unit<Scalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(operand.as_inner().ps() * self.as_inner().s() * self.as_inner().s()),
)
}
}
#[doc = "Antisandwich product: [`Scalar`] x [`RoundPoint`] x antirev([`Scalar`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<RoundPoint<T>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
self.s() * operand.x() * self.s(),
self.s() * operand.y() * self.s(),
self.s() * operand.ep() * self.s(),
self.s() * operand.em() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<RoundPoint<T>> for Unit<Scalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
operand.x() * self.as_inner().s() * self.as_inner().s(),
operand.y() * self.as_inner().s() * self.as_inner().s(),
operand.ep() * self.as_inner().s() * self.as_inner().s(),
operand.em() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<RoundPoint<T>>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
operand.as_inner().x() * self.s() * self.s(),
operand.as_inner().y() * self.s() * self.s(),
operand.as_inner().ep() * self.s() * self.s(),
operand.as_inner().em() * self.s() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<RoundPoint<T>>> for Unit<Scalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
operand.as_inner().x() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().y() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().ep() * self.as_inner().s() * self.as_inner().s(),
operand.as_inner().em() * self.as_inner().s() * self.as_inner().s(),
)
}
}
#[doc = "Antisandwich product: [`Scalar`] x [`Scalar`] x antirev([`Scalar`]).\n\nThe antisandwich product `v x a x antirev(v)` is the dual of the\nsandwich product, used in Projective GA for transforming dual objects\n(planes, ideal points). Motors use antisandwich for plane transforms."]
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Scalar<T>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(-(self.s() * operand.s() * self.s()))
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Scalar<T>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(-(operand.s() * self.as_inner().s() * self.as_inner().s()))
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Scalar<T>>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(-(operand.as_inner().s() * self.s() * self.s()))
}
}
#[allow(unused_variables)]
impl<T: Float> Antisandwich<Unit<Scalar<T>>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn antisandwich(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(-(operand.as_inner().s() * self.as_inner().s() * self.as_inner().s()))
}
}
#[doc = "Transform a [`Circle`] using this [`Circle`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Circle<T>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Circle<T>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Circle<T>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Circle<T>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Circle<T>>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Circle<T>>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`FlatPoint`] using this [`Circle`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<FlatPoint<T>> for Circle<T> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<FlatPoint<T>> for Unit<Circle<T>> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<FlatPoint<T>>> for Circle<T> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<FlatPoint<T>>> for Unit<Circle<T>> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Line`] using this [`Circle`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Line<T>> for Circle<T> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Line<T>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Line<T>> for Unit<Circle<T>> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Line<T>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Line<T>>> for Circle<T> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Unit<Line<T>>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Line<T>>> for Unit<Circle<T>> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Unit<Line<T>>) -> Line<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Motor`] using this [`Circle`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Motor<T>> for Circle<T> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Motor<T>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Motor<T>> for Unit<Circle<T>> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Motor<T>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Motor<T>>> for Circle<T> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Motor<T>>> for Unit<Circle<T>> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`PointPair`] using this [`Circle`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<PointPair<T>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &PointPair<T>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<PointPair<T>> for Unit<Circle<T>> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &PointPair<T>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<PointPair<T>>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<PointPair<T>>> for Unit<Circle<T>> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Pseudoscalar`] using this [`Circle`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Pseudoscalar<T>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Pseudoscalar<T>> for Unit<Circle<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Pseudoscalar<T>>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Pseudoscalar<T>>> for Unit<Circle<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`RoundPoint`] using this [`Circle`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<RoundPoint<T>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<RoundPoint<T>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<RoundPoint<T>>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<RoundPoint<T>>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Scalar`] using this [`Circle`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Scalar<T>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Scalar<T>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Scalar<T>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Scalar<T>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Scalar<T>>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Scalar<T>>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Circle`] using this [`FlatPoint`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Circle<T>> for FlatPoint<T> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Circle<T>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Circle<T>> for Unit<FlatPoint<T>> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Circle<T>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Circle<T>>> for FlatPoint<T> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Circle<T>>> for Unit<FlatPoint<T>> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`FlatPoint`] using this [`FlatPoint`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<FlatPoint<T>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<FlatPoint<T>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<FlatPoint<T>>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<FlatPoint<T>>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Line`] using this [`FlatPoint`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Line<T>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Line<T>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Line<T>> for Unit<FlatPoint<T>> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Line<T>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Line<T>>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Unit<Line<T>>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Line<T>>> for Unit<FlatPoint<T>> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Unit<Line<T>>) -> Line<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Motor`] using this [`FlatPoint`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Motor<T>> for FlatPoint<T> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Motor<T>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Motor<T>> for Unit<FlatPoint<T>> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Motor<T>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Motor<T>>> for FlatPoint<T> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Motor<T>>> for Unit<FlatPoint<T>> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`PointPair`] using this [`FlatPoint`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<PointPair<T>> for FlatPoint<T> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &PointPair<T>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<PointPair<T>> for Unit<FlatPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &PointPair<T>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<PointPair<T>>> for FlatPoint<T> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<PointPair<T>>> for Unit<FlatPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Pseudoscalar`] using this [`FlatPoint`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Pseudoscalar<T>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Pseudoscalar<T>> for Unit<FlatPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Pseudoscalar<T>>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Pseudoscalar<T>>> for Unit<FlatPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`RoundPoint`] using this [`FlatPoint`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<RoundPoint<T>> for FlatPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<RoundPoint<T>> for Unit<FlatPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<RoundPoint<T>>> for FlatPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<RoundPoint<T>>> for Unit<FlatPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Scalar`] using this [`FlatPoint`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Scalar<T>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Scalar<T>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Scalar<T>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Scalar<T>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Scalar<T>>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Scalar<T>>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Circle`] using this [`Line`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Circle<T>> for Line<T> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Circle<T>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Circle<T>> for Unit<Line<T>> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Circle<T>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Circle<T>>> for Line<T> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Circle<T>>> for Unit<Line<T>> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`FlatPoint`] using this [`Line`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<FlatPoint<T>> for Line<T> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<FlatPoint<T>> for Unit<Line<T>> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<FlatPoint<T>>> for Line<T> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<FlatPoint<T>>> for Unit<Line<T>> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Line`] using this [`Line`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Line<T>> for Line<T> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Line<T>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Line<T>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Line<T>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Line<T>>> for Line<T> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Unit<Line<T>>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Line<T>>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Unit<Line<T>>) -> Line<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Motor`] using this [`Line`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Motor<T>> for Line<T> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Motor<T>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Motor<T>> for Unit<Line<T>> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Motor<T>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Motor<T>>> for Line<T> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Motor<T>>> for Unit<Line<T>> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`PointPair`] using this [`Line`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<PointPair<T>> for Line<T> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &PointPair<T>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<PointPair<T>> for Unit<Line<T>> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &PointPair<T>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<PointPair<T>>> for Line<T> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<PointPair<T>>> for Unit<Line<T>> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Pseudoscalar`] using this [`Line`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Pseudoscalar<T>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Pseudoscalar<T>> for Unit<Line<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Pseudoscalar<T>>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Pseudoscalar<T>>> for Unit<Line<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`RoundPoint`] using this [`Line`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<RoundPoint<T>> for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<RoundPoint<T>> for Unit<Line<T>> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<RoundPoint<T>>> for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<RoundPoint<T>>> for Unit<Line<T>> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Scalar`] using this [`Line`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Scalar<T>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Scalar<T>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Scalar<T>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Scalar<T>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Scalar<T>>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Scalar<T>>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Circle`] using this [`Motor`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Circle<T>> for Motor<T> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Circle<T>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Circle<T>> for Unit<Motor<T>> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Circle<T>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Circle<T>>> for Motor<T> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Circle<T>>> for Unit<Motor<T>> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`FlatPoint`] using this [`Motor`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<FlatPoint<T>> for Motor<T> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<FlatPoint<T>> for Unit<Motor<T>> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<FlatPoint<T>>> for Motor<T> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<FlatPoint<T>>> for Unit<Motor<T>> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Line`] using this [`Motor`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Line<T>> for Motor<T> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Line<T>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Line<T>> for Unit<Motor<T>> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Line<T>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Line<T>>> for Motor<T> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Unit<Line<T>>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Line<T>>> for Unit<Motor<T>> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Unit<Line<T>>) -> Line<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Motor`] using this [`Motor`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Motor<T>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Motor<T>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Motor<T>> for Unit<Motor<T>> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Motor<T>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Motor<T>>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Motor<T>>> for Unit<Motor<T>> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`PointPair`] using this [`Motor`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<PointPair<T>> for Motor<T> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &PointPair<T>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<PointPair<T>> for Unit<Motor<T>> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &PointPair<T>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<PointPair<T>>> for Motor<T> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<PointPair<T>>> for Unit<Motor<T>> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Pseudoscalar`] using this [`Motor`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Pseudoscalar<T>> for Motor<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Pseudoscalar<T>> for Unit<Motor<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Pseudoscalar<T>>> for Motor<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Pseudoscalar<T>>> for Unit<Motor<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`RoundPoint`] using this [`Motor`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<RoundPoint<T>> for Motor<T> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<RoundPoint<T>> for Unit<Motor<T>> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<RoundPoint<T>>> for Motor<T> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<RoundPoint<T>>> for Unit<Motor<T>> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Scalar`] using this [`Motor`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Scalar<T>> for Motor<T> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Scalar<T>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Scalar<T>> for Unit<Motor<T>> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Scalar<T>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Scalar<T>>> for Motor<T> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Scalar<T>>> for Unit<Motor<T>> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Circle`] using this [`PointPair`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Circle<T>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Circle<T>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Circle<T>> for Unit<PointPair<T>> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Circle<T>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Circle<T>>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Circle<T>>> for Unit<PointPair<T>> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`FlatPoint`] using this [`PointPair`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<FlatPoint<T>> for PointPair<T> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<FlatPoint<T>> for Unit<PointPair<T>> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<FlatPoint<T>>> for PointPair<T> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<FlatPoint<T>>> for Unit<PointPair<T>> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Line`] using this [`PointPair`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Line<T>> for PointPair<T> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Line<T>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Line<T>> for Unit<PointPair<T>> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Line<T>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Line<T>>> for PointPair<T> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Unit<Line<T>>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Line<T>>> for Unit<PointPair<T>> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Unit<Line<T>>) -> Line<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Motor`] using this [`PointPair`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Motor<T>> for PointPair<T> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Motor<T>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Motor<T>> for Unit<PointPair<T>> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Motor<T>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Motor<T>>> for PointPair<T> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Motor<T>>> for Unit<PointPair<T>> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`PointPair`] using this [`PointPair`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<PointPair<T>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &PointPair<T>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<PointPair<T>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &PointPair<T>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<PointPair<T>>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<PointPair<T>>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Pseudoscalar`] using this [`PointPair`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Pseudoscalar<T>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Pseudoscalar<T>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Pseudoscalar<T>>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Pseudoscalar<T>>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`RoundPoint`] using this [`PointPair`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<RoundPoint<T>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<RoundPoint<T>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<RoundPoint<T>>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<RoundPoint<T>>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Scalar`] using this [`PointPair`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Scalar<T>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Scalar<T>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Scalar<T>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Scalar<T>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Scalar<T>>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Scalar<T>>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Circle`] using this [`Pseudoscalar`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Circle<T>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Circle<T>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Circle<T>> for Unit<Pseudoscalar<T>> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Circle<T>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Circle<T>>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Circle<T>>> for Unit<Pseudoscalar<T>> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`FlatPoint`] using this [`Pseudoscalar`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<FlatPoint<T>> for Pseudoscalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<FlatPoint<T>> for Unit<Pseudoscalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<FlatPoint<T>>> for Pseudoscalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<FlatPoint<T>>> for Unit<Pseudoscalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Line`] using this [`Pseudoscalar`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Line<T>> for Pseudoscalar<T> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Line<T>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Line<T>> for Unit<Pseudoscalar<T>> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Line<T>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Line<T>>> for Pseudoscalar<T> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Unit<Line<T>>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Line<T>>> for Unit<Pseudoscalar<T>> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Unit<Line<T>>) -> Line<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Motor`] using this [`Pseudoscalar`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Motor<T>> for Pseudoscalar<T> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Motor<T>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Motor<T>> for Unit<Pseudoscalar<T>> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Motor<T>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Motor<T>>> for Pseudoscalar<T> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Motor<T>>> for Unit<Pseudoscalar<T>> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`PointPair`] using this [`Pseudoscalar`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<PointPair<T>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &PointPair<T>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<PointPair<T>> for Unit<Pseudoscalar<T>> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &PointPair<T>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<PointPair<T>>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<PointPair<T>>> for Unit<Pseudoscalar<T>> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Pseudoscalar`] using this [`Pseudoscalar`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Pseudoscalar<T>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Pseudoscalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Pseudoscalar<T>>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Pseudoscalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`RoundPoint`] using this [`Pseudoscalar`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<RoundPoint<T>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<RoundPoint<T>> for Unit<Pseudoscalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<RoundPoint<T>>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<RoundPoint<T>>> for Unit<Pseudoscalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Scalar`] using this [`Pseudoscalar`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Scalar<T>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Scalar<T>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Scalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Scalar<T>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Scalar<T>>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Scalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Circle`] using this [`RoundPoint`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Circle<T>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Circle<T>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Circle<T>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Circle<T>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Circle<T>>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Circle<T>>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`FlatPoint`] using this [`RoundPoint`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<FlatPoint<T>> for RoundPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<FlatPoint<T>> for Unit<RoundPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<FlatPoint<T>>> for RoundPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<FlatPoint<T>>> for Unit<RoundPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Line`] using this [`RoundPoint`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Line<T>> for RoundPoint<T> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Line<T>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Line<T>> for Unit<RoundPoint<T>> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Line<T>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Line<T>>> for RoundPoint<T> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Unit<Line<T>>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Line<T>>> for Unit<RoundPoint<T>> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Unit<Line<T>>) -> Line<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Motor`] using this [`RoundPoint`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Motor<T>> for RoundPoint<T> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Motor<T>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Motor<T>> for Unit<RoundPoint<T>> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Motor<T>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Motor<T>>> for RoundPoint<T> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Motor<T>>> for Unit<RoundPoint<T>> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`PointPair`] using this [`RoundPoint`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<PointPair<T>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &PointPair<T>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<PointPair<T>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &PointPair<T>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<PointPair<T>>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<PointPair<T>>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Pseudoscalar`] using this [`RoundPoint`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Pseudoscalar<T>> for RoundPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Pseudoscalar<T>> for Unit<RoundPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Pseudoscalar<T>>> for RoundPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Pseudoscalar<T>>> for Unit<RoundPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`RoundPoint`] using this [`RoundPoint`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<RoundPoint<T>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<RoundPoint<T>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<RoundPoint<T>>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<RoundPoint<T>>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Scalar`] using this [`RoundPoint`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Scalar<T>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Scalar<T>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Scalar<T>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Scalar<T>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Scalar<T>>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Scalar<T>>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Circle`] using this [`Scalar`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Circle<T>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Circle<T>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Circle<T>> for Unit<Scalar<T>> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Circle<T>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Circle<T>>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Circle<T>>> for Unit<Scalar<T>> {
type Output = Circle<T>;
#[inline]
fn transform(&self, operand: &Unit<Circle<T>>) -> Circle<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`FlatPoint`] using this [`Scalar`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<FlatPoint<T>> for Scalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<FlatPoint<T>> for Unit<Scalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &FlatPoint<T>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<FlatPoint<T>>> for Scalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<FlatPoint<T>>> for Unit<Scalar<T>> {
type Output = FlatPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<FlatPoint<T>>) -> FlatPoint<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Line`] using this [`Scalar`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Line<T>> for Scalar<T> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Line<T>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Line<T>> for Unit<Scalar<T>> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Line<T>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Line<T>>> for Scalar<T> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Unit<Line<T>>) -> Line<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Line<T>>> for Unit<Scalar<T>> {
type Output = Line<T>;
#[inline]
fn transform(&self, operand: &Unit<Line<T>>) -> Line<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Motor`] using this [`Scalar`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Motor<T>> for Scalar<T> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Motor<T>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Motor<T>> for Unit<Scalar<T>> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Motor<T>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Motor<T>>> for Scalar<T> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Motor<T>>> for Unit<Scalar<T>> {
type Output = Motor<T>;
#[inline]
fn transform(&self, operand: &Unit<Motor<T>>) -> Motor<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`PointPair`] using this [`Scalar`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<PointPair<T>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &PointPair<T>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<PointPair<T>> for Unit<Scalar<T>> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &PointPair<T>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<PointPair<T>>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<PointPair<T>>> for Unit<Scalar<T>> {
type Output = PointPair<T>;
#[inline]
fn transform(&self, operand: &Unit<PointPair<T>>) -> PointPair<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Pseudoscalar`] using this [`Scalar`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Pseudoscalar<T>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Pseudoscalar<T>> for Unit<Scalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Pseudoscalar<T>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Pseudoscalar<T>>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Pseudoscalar<T>>> for Unit<Scalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`RoundPoint`] using this [`Scalar`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<RoundPoint<T>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<RoundPoint<T>> for Unit<Scalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &RoundPoint<T>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<RoundPoint<T>>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<RoundPoint<T>>> for Unit<Scalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn transform(&self, operand: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
self.sandwich(operand)
}
}
#[doc = "Transform a [`Scalar`] using this [`Scalar`].\n\nApplies the geometric transformation represented by this versor.\nFor rotors, this performs rotation. For motors, this performs rigid\nbody transformation (rotation + translation). Internally uses the\nsandwich product."]
impl<T: Float> Transform<Scalar<T>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Scalar<T>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Scalar<T>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Scalar<T>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Scalar<T>>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
self.sandwich(operand)
}
}
impl<T: Float> Transform<Unit<Scalar<T>>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn transform(&self, operand: &Unit<Scalar<T>>) -> Scalar<T> {
self.sandwich(operand)
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Circle<T>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Circle<T>) -> Option<Circle<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Circle::new_unchecked(
(-(self.e12em() * operand.e12em() * self.w())
+ self.e12em() * operand.w() * self.e12em()
- self.e1epem() * operand.e1epem() * self.w()
+ self.e1epem() * operand.w() * self.e1epem()
- self.e2epem() * operand.e2epem() * self.w()
+ self.e2epem() * operand.w() * self.e2epem()
- self.w() * operand.e12em() * self.e12em()
- self.w() * operand.e1epem() * self.e1epem()
- self.w() * operand.e2epem() * self.e2epem()
+ self.w() * operand.w() * self.w())
* inv_norm_sq,
(-(self.e12em() * operand.e12em() * self.e12em())
- self.e12em() * operand.e1epem() * self.e1epem()
- self.e12em() * operand.e2epem() * self.e2epem()
+ self.e12em() * operand.w() * self.w()
+ self.e1epem() * operand.e12em() * self.e1epem()
- self.e1epem() * operand.e1epem() * self.e12em()
+ self.e2epem() * operand.e12em() * self.e2epem()
- self.e2epem() * operand.e2epem() * self.e12em()
- self.w() * operand.e12em() * self.w()
+ self.w() * operand.w() * self.e12em())
* inv_norm_sq,
(-(self.e12em() * operand.e12em() * self.e1epem())
+ self.e12em() * operand.e1epem() * self.e12em()
- self.e1epem() * operand.e12em() * self.e12em()
- self.e1epem() * operand.e1epem() * self.e1epem()
- self.e1epem() * operand.e2epem() * self.e2epem()
+ self.e1epem() * operand.w() * self.w()
+ self.e2epem() * operand.e1epem() * self.e2epem()
- self.e2epem() * operand.e2epem() * self.e1epem()
- self.w() * operand.e1epem() * self.w()
+ self.w() * operand.w() * self.e1epem())
* inv_norm_sq,
(-(self.e12em() * operand.e12em() * self.e2epem())
+ self.e12em() * operand.e2epem() * self.e12em()
- self.e1epem() * operand.e1epem() * self.e2epem()
+ self.e1epem() * operand.e2epem() * self.e1epem()
- self.e2epem() * operand.e12em() * self.e12em()
- self.e2epem() * operand.e1epem() * self.e1epem()
- self.e2epem() * operand.e2epem() * self.e2epem()
+ self.e2epem() * operand.w() * self.w()
- self.w() * operand.e2epem() * self.w()
+ self.w() * operand.w() * self.e2epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<FlatPoint<T>> for Circle<T> {
type Output = FlatPoint<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &FlatPoint<T>) -> Option<FlatPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(FlatPoint::new_unchecked(
(-(self.e12em() * operand.e1em() * self.e12em())
+ self.e12em() * operand.epem() * self.e2epem()
- self.e1epem() * operand.e1em() * self.e1epem()
- self.e1epem() * operand.e2em() * self.e2epem()
+ self.e2epem() * operand.e1em() * self.e2epem()
- self.e2epem() * operand.e2em() * self.e1epem()
+ self.e2epem() * operand.epem() * self.e12em()
- self.w() * operand.e1em() * self.w())
* inv_norm_sq,
(-(self.e12em() * operand.e2em() * self.e12em())
- self.e12em() * operand.epem() * self.e1epem()
- self.e1epem() * operand.e1em() * self.e2epem()
+ self.e1epem() * operand.e2em() * self.e1epem()
- self.e1epem() * operand.epem() * self.e12em()
- self.e2epem() * operand.e1em() * self.e1epem()
- self.e2epem() * operand.e2em() * self.e2epem()
- self.w() * operand.e2em() * self.w())
* inv_norm_sq,
(self.e12em() * operand.e1em() * self.e2epem()
- self.e12em() * operand.e2em() * self.e1epem()
+ self.e12em() * operand.epem() * self.e12em()
- self.e1epem() * operand.e2em() * self.e12em()
- self.e1epem() * operand.epem() * self.e1epem()
+ self.e2epem() * operand.e1em() * self.e12em()
- self.e2epem() * operand.epem() * self.e2epem()
- self.w() * operand.epem() * self.w())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Line<T>> for Circle<T> {
type Output = Line<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Line<T>) -> Option<Line<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Line::new_unchecked(
(-(self.e12em() * operand.d() * self.e2epem())
- self.e12em() * operand.nx() * self.e12em()
- self.e12em() * operand.ny() * self.e1epem()
+ self.e1epem() * operand.nx() * self.e1epem()
- self.e1epem() * operand.ny() * self.e12em()
- self.e2epem() * operand.d() * self.e12em()
+ self.e2epem() * operand.nx() * self.e2epem()
- self.w() * operand.nx() * self.w())
* inv_norm_sq,
(-(self.e12em() * operand.nx() * self.e1epem())
+ self.e12em() * operand.ny() * self.e12em()
- self.e1epem() * operand.d() * self.e2epem()
- self.e1epem() * operand.nx() * self.e12em()
- self.e1epem() * operand.ny() * self.e1epem()
- self.e2epem() * operand.d() * self.e1epem()
+ self.e2epem() * operand.ny() * self.e2epem()
- self.w() * operand.ny() * self.w())
* inv_norm_sq,
(self.e12em() * operand.d() * self.e12em()
- self.e12em() * operand.nx() * self.e2epem()
+ self.e1epem() * operand.d() * self.e1epem()
- self.e1epem() * operand.ny() * self.e2epem()
- self.e2epem() * operand.d() * self.e2epem()
- self.e2epem() * operand.nx() * self.e12em()
- self.e2epem() * operand.ny() * self.e1epem()
- self.w() * operand.d() * self.w())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Motor<T>> for Circle<T> {
type Output = Motor<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Motor<T>) -> Option<Motor<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Motor::new_unchecked(
(self.e12em() * operand.e1ep() * self.e2epem()
- self.e12em() * operand.e2ep() * self.e1epem()
+ self.e12em() * operand.epem() * self.w()
- self.e12em() * operand.s() * self.e12em()
- self.e1epem() * operand.e2em() * self.w()
+ self.e1epem() * operand.e2ep() * self.e12em()
- self.e1epem() * operand.m() * self.e2epem()
- self.e1epem() * operand.s() * self.e1epem()
+ self.e2epem() * operand.e1em() * self.w()
- self.e2epem() * operand.e1ep() * self.e12em()
+ self.e2epem() * operand.m() * self.e1epem()
- self.e2epem() * operand.s() * self.e2epem()
- self.w() * operand.e1em() * self.e2epem()
+ self.w() * operand.e2em() * self.e1epem()
- self.w() * operand.epem() * self.e12em()
+ self.w() * operand.s() * self.w())
* inv_norm_sq,
(-(self.e12em() * operand.e1ep() * self.e1epem())
- self.e12em() * operand.e2ep() * self.e2epem()
- self.e12em() * operand.m() * self.e12em()
+ self.e12em() * operand.ps() * self.w()
+ self.e1epem() * operand.e1em() * self.w()
- self.e1epem() * operand.e1ep() * self.e12em()
+ self.e1epem() * operand.m() * self.e1epem()
- self.e1epem() * operand.s() * self.e2epem()
+ self.e2epem() * operand.e2em() * self.w()
- self.e2epem() * operand.e2ep() * self.e12em()
+ self.e2epem() * operand.m() * self.e2epem()
+ self.e2epem() * operand.s() * self.e1epem()
+ self.w() * operand.e1em() * self.e1epem()
+ self.w() * operand.e2em() * self.e2epem()
+ self.w() * operand.m() * self.w()
- self.w() * operand.ps() * self.e12em())
* inv_norm_sq,
(-(self.e12em() * operand.e1em() * self.w())
+ self.e12em() * operand.e1ep() * self.e12em()
- self.e12em() * operand.m() * self.e1epem()
+ self.e12em() * operand.s() * self.e2epem()
- self.e1epem() * operand.e1ep() * self.e1epem()
- self.e1epem() * operand.e2ep() * self.e2epem()
- self.e1epem() * operand.m() * self.e12em()
+ self.e1epem() * operand.ps() * self.w()
+ self.e2epem() * operand.e1ep() * self.e2epem()
- self.e2epem() * operand.e2ep() * self.e1epem()
+ self.e2epem() * operand.epem() * self.w()
- self.e2epem() * operand.s() * self.e12em()
- self.w() * operand.e1em() * self.e12em()
+ self.w() * operand.e1ep() * self.w()
+ self.w() * operand.epem() * self.e2epem()
- self.w() * operand.ps() * self.e1epem())
* inv_norm_sq,
(-(self.e12em() * operand.e2em() * self.w())
+ self.e12em() * operand.e2ep() * self.e12em()
- self.e12em() * operand.m() * self.e2epem()
- self.e12em() * operand.s() * self.e1epem()
- self.e1epem() * operand.e1ep() * self.e2epem()
+ self.e1epem() * operand.e2ep() * self.e1epem()
- self.e1epem() * operand.epem() * self.w()
+ self.e1epem() * operand.s() * self.e12em()
- self.e2epem() * operand.e1ep() * self.e1epem()
- self.e2epem() * operand.e2ep() * self.e2epem()
- self.e2epem() * operand.m() * self.e12em()
+ self.e2epem() * operand.ps() * self.w()
- self.w() * operand.e2em() * self.e12em()
+ self.w() * operand.e2ep() * self.w()
- self.w() * operand.epem() * self.e1epem()
- self.w() * operand.ps() * self.e2epem())
* inv_norm_sq,
(-(self.e12em() * operand.e1em() * self.e12em())
+ self.e12em() * operand.e1ep() * self.w()
+ self.e12em() * operand.epem() * self.e2epem()
- self.e12em() * operand.ps() * self.e1epem()
- self.e1epem() * operand.e1em() * self.e1epem()
- self.e1epem() * operand.e2em() * self.e2epem()
- self.e1epem() * operand.m() * self.w()
+ self.e1epem() * operand.ps() * self.e12em()
+ self.e2epem() * operand.e1em() * self.e2epem()
- self.e2epem() * operand.e2em() * self.e1epem()
+ self.e2epem() * operand.epem() * self.e12em()
- self.e2epem() * operand.s() * self.w()
- self.w() * operand.e1em() * self.w()
+ self.w() * operand.e1ep() * self.e12em()
- self.w() * operand.m() * self.e1epem()
+ self.w() * operand.s() * self.e2epem())
* inv_norm_sq,
(-(self.e12em() * operand.e2em() * self.e12em())
+ self.e12em() * operand.e2ep() * self.w()
- self.e12em() * operand.epem() * self.e1epem()
- self.e12em() * operand.ps() * self.e2epem()
- self.e1epem() * operand.e1em() * self.e2epem()
+ self.e1epem() * operand.e2em() * self.e1epem()
- self.e1epem() * operand.epem() * self.e12em()
+ self.e1epem() * operand.s() * self.w()
- self.e2epem() * operand.e1em() * self.e1epem()
- self.e2epem() * operand.e2em() * self.e2epem()
- self.e2epem() * operand.m() * self.w()
+ self.e2epem() * operand.ps() * self.e12em()
- self.w() * operand.e2em() * self.w()
+ self.w() * operand.e2ep() * self.e12em()
- self.w() * operand.m() * self.e2epem()
- self.w() * operand.s() * self.e1epem())
* inv_norm_sq,
(self.e12em() * operand.e1em() * self.e2epem()
- self.e12em() * operand.e2em() * self.e1epem()
+ self.e12em() * operand.epem() * self.e12em()
- self.e12em() * operand.s() * self.w()
- self.e1epem() * operand.e2em() * self.e12em()
+ self.e1epem() * operand.e2ep() * self.w()
- self.e1epem() * operand.epem() * self.e1epem()
- self.e1epem() * operand.ps() * self.e2epem()
+ self.e2epem() * operand.e1em() * self.e12em()
- self.e2epem() * operand.e1ep() * self.w()
- self.e2epem() * operand.epem() * self.e2epem()
+ self.e2epem() * operand.ps() * self.e1epem()
- self.w() * operand.e1ep() * self.e2epem()
+ self.w() * operand.e2ep() * self.e1epem()
- self.w() * operand.epem() * self.w()
+ self.w() * operand.s() * self.e12em())
* inv_norm_sq,
(-(self.e12em() * operand.e1em() * self.e1epem())
- self.e12em() * operand.e2em() * self.e2epem()
- self.e12em() * operand.m() * self.w()
+ self.e12em() * operand.ps() * self.e12em()
+ self.e1epem() * operand.e1em() * self.e12em()
- self.e1epem() * operand.e1ep() * self.w()
- self.e1epem() * operand.epem() * self.e2epem()
+ self.e1epem() * operand.ps() * self.e1epem()
+ self.e2epem() * operand.e2em() * self.e12em()
- self.e2epem() * operand.e2ep() * self.w()
+ self.e2epem() * operand.epem() * self.e1epem()
+ self.e2epem() * operand.ps() * self.e2epem()
+ self.w() * operand.e1ep() * self.e1epem()
+ self.w() * operand.e2ep() * self.e2epem()
+ self.w() * operand.m() * self.e12em()
- self.w() * operand.ps() * self.w())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<PointPair<T>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &PointPair<T>) -> Option<PointPair<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(PointPair::new_unchecked(
(-(self.e12em() * operand.e1ep() * self.e1epem())
- self.e12em() * operand.e2ep() * self.e2epem()
- self.e12em() * operand.m() * self.e12em()
+ self.e1epem() * operand.e1em() * self.w()
- self.e1epem() * operand.e1ep() * self.e12em()
+ self.e1epem() * operand.m() * self.e1epem()
+ self.e2epem() * operand.e2em() * self.w()
- self.e2epem() * operand.e2ep() * self.e12em()
+ self.e2epem() * operand.m() * self.e2epem()
+ self.w() * operand.e1em() * self.e1epem()
+ self.w() * operand.e2em() * self.e2epem()
+ self.w() * operand.m() * self.w())
* inv_norm_sq,
(-(self.e12em() * operand.e1em() * self.w())
+ self.e12em() * operand.e1ep() * self.e12em()
- self.e12em() * operand.m() * self.e1epem()
- self.e1epem() * operand.e1ep() * self.e1epem()
- self.e1epem() * operand.e2ep() * self.e2epem()
- self.e1epem() * operand.m() * self.e12em()
+ self.e2epem() * operand.e1ep() * self.e2epem()
- self.e2epem() * operand.e2ep() * self.e1epem()
+ self.e2epem() * operand.epem() * self.w()
- self.w() * operand.e1em() * self.e12em()
+ self.w() * operand.e1ep() * self.w()
+ self.w() * operand.epem() * self.e2epem())
* inv_norm_sq,
(-(self.e12em() * operand.e2em() * self.w())
+ self.e12em() * operand.e2ep() * self.e12em()
- self.e12em() * operand.m() * self.e2epem()
- self.e1epem() * operand.e1ep() * self.e2epem()
+ self.e1epem() * operand.e2ep() * self.e1epem()
- self.e1epem() * operand.epem() * self.w()
- self.e2epem() * operand.e1ep() * self.e1epem()
- self.e2epem() * operand.e2ep() * self.e2epem()
- self.e2epem() * operand.m() * self.e12em()
- self.w() * operand.e2em() * self.e12em()
+ self.w() * operand.e2ep() * self.w()
- self.w() * operand.epem() * self.e1epem())
* inv_norm_sq,
(-(self.e12em() * operand.e1em() * self.e12em())
+ self.e12em() * operand.e1ep() * self.w()
+ self.e12em() * operand.epem() * self.e2epem()
- self.e1epem() * operand.e1em() * self.e1epem()
- self.e1epem() * operand.e2em() * self.e2epem()
- self.e1epem() * operand.m() * self.w()
+ self.e2epem() * operand.e1em() * self.e2epem()
- self.e2epem() * operand.e2em() * self.e1epem()
+ self.e2epem() * operand.epem() * self.e12em()
- self.w() * operand.e1em() * self.w()
+ self.w() * operand.e1ep() * self.e12em()
- self.w() * operand.m() * self.e1epem())
* inv_norm_sq,
(-(self.e12em() * operand.e2em() * self.e12em())
+ self.e12em() * operand.e2ep() * self.w()
- self.e12em() * operand.epem() * self.e1epem()
- self.e1epem() * operand.e1em() * self.e2epem()
+ self.e1epem() * operand.e2em() * self.e1epem()
- self.e1epem() * operand.epem() * self.e12em()
- self.e2epem() * operand.e1em() * self.e1epem()
- self.e2epem() * operand.e2em() * self.e2epem()
- self.e2epem() * operand.m() * self.w()
- self.w() * operand.e2em() * self.w()
+ self.w() * operand.e2ep() * self.e12em()
- self.w() * operand.m() * self.e2epem())
* inv_norm_sq,
(self.e12em() * operand.e1em() * self.e2epem()
- self.e12em() * operand.e2em() * self.e1epem()
+ self.e12em() * operand.epem() * self.e12em()
- self.e1epem() * operand.e2em() * self.e12em()
+ self.e1epem() * operand.e2ep() * self.w()
- self.e1epem() * operand.epem() * self.e1epem()
+ self.e2epem() * operand.e1em() * self.e12em()
- self.e2epem() * operand.e1ep() * self.w()
- self.e2epem() * operand.epem() * self.e2epem()
- self.w() * operand.e1ep() * self.e2epem()
+ self.w() * operand.e2ep() * self.e1epem()
- self.w() * operand.epem() * self.w())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Pseudoscalar<T>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Pseudoscalar<T>) -> Option<Pseudoscalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Pseudoscalar::new_unchecked(
(self.e12em() * operand.ps() * self.e12em()
+ self.e1epem() * operand.ps() * self.e1epem()
+ self.e2epem() * operand.ps() * self.e2epem()
- self.w() * operand.ps() * self.w())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<RoundPoint<T>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &RoundPoint<T>) -> Option<RoundPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(RoundPoint::new_unchecked(
(self.e12em() * operand.ep() * self.e2epem()
- self.e12em() * operand.x() * self.e12em()
- self.e1epem() * operand.x() * self.e1epem()
- self.e1epem() * operand.y() * self.e2epem()
- self.e2epem() * operand.em() * self.w()
+ self.e2epem() * operand.ep() * self.e12em()
+ self.e2epem() * operand.x() * self.e2epem()
- self.e2epem() * operand.y() * self.e1epem()
- self.w() * operand.em() * self.e2epem()
+ self.w() * operand.x() * self.w())
* inv_norm_sq,
(-(self.e12em() * operand.ep() * self.e1epem())
- self.e12em() * operand.y() * self.e12em()
+ self.e1epem() * operand.em() * self.w()
- self.e1epem() * operand.ep() * self.e12em()
- self.e1epem() * operand.x() * self.e2epem()
+ self.e1epem() * operand.y() * self.e1epem()
- self.e2epem() * operand.x() * self.e1epem()
- self.e2epem() * operand.y() * self.e2epem()
+ self.w() * operand.em() * self.e1epem()
+ self.w() * operand.y() * self.w())
* inv_norm_sq,
(-(self.e12em() * operand.em() * self.w())
+ self.e12em() * operand.ep() * self.e12em()
+ self.e12em() * operand.x() * self.e2epem()
- self.e12em() * operand.y() * self.e1epem()
- self.e1epem() * operand.ep() * self.e1epem()
- self.e1epem() * operand.y() * self.e12em()
- self.e2epem() * operand.ep() * self.e2epem()
+ self.e2epem() * operand.x() * self.e12em()
- self.w() * operand.em() * self.e12em()
+ self.w() * operand.ep() * self.w())
* inv_norm_sq,
(-(self.e12em() * operand.em() * self.e12em())
+ self.e12em() * operand.ep() * self.w()
- self.e1epem() * operand.em() * self.e1epem()
- self.e1epem() * operand.y() * self.w()
- self.e2epem() * operand.em() * self.e2epem()
+ self.e2epem() * operand.x() * self.w()
- self.w() * operand.em() * self.w()
+ self.w() * operand.ep() * self.e12em()
+ self.w() * operand.x() * self.e2epem()
- self.w() * operand.y() * self.e1epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Scalar<T>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Scalar<T>) -> Option<Scalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Scalar::new_unchecked(
(-(self.e12em() * operand.s() * self.e12em())
- self.e1epem() * operand.s() * self.e1epem()
- self.e2epem() * operand.s() * self.e2epem()
+ self.w() * operand.s() * self.w())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Circle<T>> for FlatPoint<T> {
type Output = Circle<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Circle<T>) -> Option<Circle<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Circle::new_unchecked(
(self.e1em() * operand.w() * self.e1em()
+ self.e2em() * operand.w() * self.e2em()
+ self.epem() * operand.w() * self.epem())
* inv_norm_sq,
(-(self.e1em() * operand.e12em() * self.e1em())
+ self.e1em() * operand.e2epem() * self.epem()
- self.e2em() * operand.e12em() * self.e2em()
- self.e2em() * operand.e1epem() * self.epem()
+ self.epem() * operand.e12em() * self.epem()
- self.epem() * operand.e1epem() * self.e2em()
+ self.epem() * operand.e2epem() * self.e1em())
* inv_norm_sq,
(-(self.e1em() * operand.e1epem() * self.e1em())
- self.e1em() * operand.e2epem() * self.e2em()
- self.e2em() * operand.e12em() * self.epem()
+ self.e2em() * operand.e1epem() * self.e2em()
- self.e2em() * operand.e2epem() * self.e1em()
- self.epem() * operand.e12em() * self.e2em()
- self.epem() * operand.e1epem() * self.epem())
* inv_norm_sq,
(self.e1em() * operand.e12em() * self.epem()
- self.e1em() * operand.e1epem() * self.e2em()
+ self.e1em() * operand.e2epem() * self.e1em()
- self.e2em() * operand.e1epem() * self.e1em()
- self.e2em() * operand.e2epem() * self.e2em()
+ self.epem() * operand.e12em() * self.e1em()
- self.epem() * operand.e2epem() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<FlatPoint<T>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &FlatPoint<T>) -> Option<FlatPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(FlatPoint::new_unchecked(
(-(self.e1em() * operand.e1em() * self.e1em())
- self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.epem() * self.epem()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e2em() * self.e1em()
+ self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.epem() * self.e1em())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e2em() * self.e1em()
- self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.epem() * self.epem()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.epem() * self.e2em())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.epem())
+ self.e1em() * operand.epem() * self.e1em()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.epem() * self.e2em()
- self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.epem() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Line<T>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Line<T>) -> Option<Line<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Line::new_unchecked(
(self.e1em() * operand.d() * self.epem()
- self.e1em() * operand.nx() * self.e1em()
- self.e2em() * operand.nx() * self.e2em()
- self.e2em() * operand.ny() * self.epem()
+ self.epem() * operand.d() * self.e1em()
+ self.epem() * operand.nx() * self.epem()
- self.epem() * operand.ny() * self.e2em())
* inv_norm_sq,
(-(self.e1em() * operand.d() * self.e2em())
- self.e1em() * operand.ny() * self.e1em()
- self.e2em() * operand.d() * self.e1em()
- self.e2em() * operand.nx() * self.epem()
+ self.e2em() * operand.ny() * self.e2em()
- self.epem() * operand.nx() * self.e2em()
- self.epem() * operand.ny() * self.epem())
* inv_norm_sq,
(self.e1em() * operand.d() * self.e1em() + self.e1em() * operand.nx() * self.epem()
- self.e1em() * operand.ny() * self.e2em()
- self.e2em() * operand.d() * self.e2em()
- self.e2em() * operand.ny() * self.e1em()
- self.epem() * operand.d() * self.epem()
+ self.epem() * operand.nx() * self.e1em())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Motor<T>> for FlatPoint<T> {
type Output = Motor<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Motor<T>) -> Option<Motor<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Motor::new_unchecked(
(-(self.e1em() * operand.e1ep() * self.epem())
- self.e1em() * operand.m() * self.e2em()
- self.e1em() * operand.s() * self.e1em()
- self.e2em() * operand.e2ep() * self.epem()
+ self.e2em() * operand.m() * self.e1em()
- self.e2em() * operand.s() * self.e2em()
+ self.epem() * operand.e1ep() * self.e1em()
+ self.epem() * operand.e2ep() * self.e2em()
- self.epem() * operand.s() * self.epem())
* inv_norm_sq,
(-(self.e1em() * operand.e2ep() * self.epem())
+ self.e1em() * operand.m() * self.e1em()
- self.e1em() * operand.s() * self.e2em()
+ self.e2em() * operand.e1ep() * self.epem()
+ self.e2em() * operand.m() * self.e2em()
+ self.e2em() * operand.s() * self.e1em()
+ self.epem() * operand.e1ep() * self.e2em()
- self.epem() * operand.e2ep() * self.e1em()
- self.epem() * operand.m() * self.epem())
* inv_norm_sq,
(self.e1em() * operand.e1ep() * self.e1em()
+ self.e1em() * operand.e2ep() * self.e2em()
- self.e1em() * operand.s() * self.epem()
- self.e2em() * operand.e1ep() * self.e2em()
+ self.e2em() * operand.e2ep() * self.e1em()
+ self.e2em() * operand.m() * self.epem()
+ self.epem() * operand.e1ep() * self.epem()
+ self.epem() * operand.m() * self.e2em()
+ self.epem() * operand.s() * self.e1em())
* inv_norm_sq,
(self.e1em() * operand.e1ep() * self.e2em()
- self.e1em() * operand.e2ep() * self.e1em()
- self.e1em() * operand.m() * self.epem()
+ self.e2em() * operand.e1ep() * self.e1em()
+ self.e2em() * operand.e2ep() * self.e2em()
- self.e2em() * operand.s() * self.epem()
+ self.epem() * operand.e2ep() * self.epem()
- self.epem() * operand.m() * self.e1em()
+ self.epem() * operand.s() * self.e2em())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e1em())
- self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.epem() * self.epem()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e2em() * self.e1em()
+ self.e2em() * operand.ps() * self.epem()
+ self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.epem() * self.e1em()
- self.epem() * operand.ps() * self.e2em())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e2em() * self.e1em()
- self.e1em() * operand.ps() * self.epem()
- self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.epem() * self.epem()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.epem() * self.e2em()
+ self.epem() * operand.ps() * self.e1em())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.epem())
+ self.e1em() * operand.epem() * self.e1em()
+ self.e1em() * operand.ps() * self.e2em()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.epem() * self.e2em()
- self.e2em() * operand.ps() * self.e1em()
- self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.epem() * self.epem())
* inv_norm_sq,
(-(self.e1em() * operand.e2em() * self.epem())
+ self.e1em() * operand.epem() * self.e2em()
- self.e1em() * operand.ps() * self.e1em()
+ self.e2em() * operand.e1em() * self.epem()
- self.e2em() * operand.epem() * self.e1em()
- self.e2em() * operand.ps() * self.e2em()
- self.epem() * operand.e1em() * self.e2em()
+ self.epem() * operand.e2em() * self.e1em()
- self.epem() * operand.ps() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<PointPair<T>> for FlatPoint<T> {
type Output = PointPair<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &PointPair<T>) -> Option<PointPair<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(PointPair::new_unchecked(
(-(self.e1em() * operand.e2ep() * self.epem())
+ self.e1em() * operand.m() * self.e1em()
+ self.e2em() * operand.e1ep() * self.epem()
+ self.e2em() * operand.m() * self.e2em()
+ self.epem() * operand.e1ep() * self.e2em()
- self.epem() * operand.e2ep() * self.e1em()
- self.epem() * operand.m() * self.epem())
* inv_norm_sq,
(self.e1em() * operand.e1ep() * self.e1em()
+ self.e1em() * operand.e2ep() * self.e2em()
- self.e2em() * operand.e1ep() * self.e2em()
+ self.e2em() * operand.e2ep() * self.e1em()
+ self.e2em() * operand.m() * self.epem()
+ self.epem() * operand.e1ep() * self.epem()
+ self.epem() * operand.m() * self.e2em())
* inv_norm_sq,
(self.e1em() * operand.e1ep() * self.e2em()
- self.e1em() * operand.e2ep() * self.e1em()
- self.e1em() * operand.m() * self.epem()
+ self.e2em() * operand.e1ep() * self.e1em()
+ self.e2em() * operand.e2ep() * self.e2em()
+ self.epem() * operand.e2ep() * self.epem()
- self.epem() * operand.m() * self.e1em())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e1em())
- self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.epem() * self.epem()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e2em() * self.e1em()
+ self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.epem() * self.e1em())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e2em() * self.e1em()
- self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.epem() * self.epem()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.epem() * self.e2em())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.epem())
+ self.e1em() * operand.epem() * self.e1em()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.epem() * self.e2em()
- self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.epem() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Pseudoscalar<T>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Pseudoscalar<T>) -> Option<Pseudoscalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Pseudoscalar::new_unchecked(
(-(self.e1em() * operand.ps() * self.e1em())
- self.e2em() * operand.ps() * self.e2em()
- self.epem() * operand.ps() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<RoundPoint<T>> for FlatPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &RoundPoint<T>) -> Option<RoundPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(RoundPoint::new_unchecked(
(self.e1em() * operand.ep() * self.epem()
+ self.e1em() * operand.x() * self.e1em()
+ self.e1em() * operand.y() * self.e2em()
- self.e2em() * operand.x() * self.e2em()
+ self.e2em() * operand.y() * self.e1em()
+ self.epem() * operand.ep() * self.e1em()
- self.epem() * operand.x() * self.epem())
* inv_norm_sq,
(self.e1em() * operand.x() * self.e2em() - self.e1em() * operand.y() * self.e1em()
+ self.e2em() * operand.ep() * self.epem()
+ self.e2em() * operand.x() * self.e1em()
+ self.e2em() * operand.y() * self.e2em()
+ self.epem() * operand.ep() * self.e2em()
- self.epem() * operand.y() * self.epem())
* inv_norm_sq,
(-(self.e1em() * operand.ep() * self.e1em()) + self.e1em() * operand.x() * self.epem()
- self.e2em() * operand.ep() * self.e2em()
+ self.e2em() * operand.y() * self.epem()
+ self.epem() * operand.ep() * self.epem()
+ self.epem() * operand.x() * self.e1em()
+ self.epem() * operand.y() * self.e2em())
* inv_norm_sq,
(self.e1em() * operand.em() * self.e1em()
+ self.e2em() * operand.em() * self.e2em()
+ self.epem() * operand.em() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Scalar<T>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Scalar<T>) -> Option<Scalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Scalar::new_unchecked(
(-(self.e1em() * operand.s() * self.e1em())
- self.e2em() * operand.s() * self.e2em()
- self.epem() * operand.s() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Circle<T>> for Line<T> {
type Output = Circle<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Circle<T>) -> Option<Circle<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Circle::new_unchecked(
(self.d() * operand.w() * self.d()
+ self.nx() * operand.w() * self.nx()
+ self.ny() * operand.w() * self.ny())
* inv_norm_sq,
(self.d() * operand.e12em() * self.d()
- self.d() * operand.e2epem() * self.nx()
- self.nx() * operand.e12em() * self.nx()
- self.nx() * operand.e1epem() * self.ny()
- self.nx() * operand.e2epem() * self.d()
+ self.ny() * operand.e12em() * self.ny()
- self.ny() * operand.e1epem() * self.nx())
* inv_norm_sq,
(self.d() * operand.e1epem() * self.d()
- self.d() * operand.e2epem() * self.ny()
- self.nx() * operand.e12em() * self.ny()
+ self.nx() * operand.e1epem() * self.nx()
- self.ny() * operand.e12em() * self.nx()
- self.ny() * operand.e1epem() * self.ny()
- self.ny() * operand.e2epem() * self.d())
* inv_norm_sq,
(-(self.d() * operand.e12em() * self.nx())
- self.d() * operand.e1epem() * self.ny()
- self.d() * operand.e2epem() * self.d()
- self.nx() * operand.e12em() * self.d()
+ self.nx() * operand.e2epem() * self.nx()
- self.ny() * operand.e1epem() * self.d()
+ self.ny() * operand.e2epem() * self.ny())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<FlatPoint<T>> for Line<T> {
type Output = FlatPoint<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &FlatPoint<T>) -> Option<FlatPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(FlatPoint::new_unchecked(
(self.d() * operand.e1em() * self.d() - self.d() * operand.e2em() * self.ny()
+ self.d() * operand.epem() * self.nx()
- self.nx() * operand.e1em() * self.nx()
+ self.nx() * operand.epem() * self.d()
- self.ny() * operand.e1em() * self.ny()
- self.ny() * operand.e2em() * self.d())
* inv_norm_sq,
(-(self.d() * operand.e1em() * self.ny())
- self.d() * operand.e2em() * self.d()
- self.nx() * operand.e2em() * self.nx()
- self.nx() * operand.epem() * self.ny()
- self.ny() * operand.e1em() * self.d()
+ self.ny() * operand.e2em() * self.ny()
- self.ny() * operand.epem() * self.nx())
* inv_norm_sq,
(self.d() * operand.e1em() * self.nx() - self.d() * operand.epem() * self.d()
+ self.nx() * operand.e1em() * self.d()
- self.nx() * operand.e2em() * self.ny()
+ self.nx() * operand.epem() * self.nx()
- self.ny() * operand.e2em() * self.nx()
- self.ny() * operand.epem() * self.ny())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Line<T>> for Line<T> {
type Output = Line<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Line<T>) -> Option<Line<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Line::new_unchecked(
(-(self.d() * operand.d() * self.nx()) + self.d() * operand.nx() * self.d()
- self.nx() * operand.d() * self.d()
- self.nx() * operand.nx() * self.nx()
- self.nx() * operand.ny() * self.ny()
+ self.ny() * operand.nx() * self.ny()
- self.ny() * operand.ny() * self.nx())
* inv_norm_sq,
(-(self.d() * operand.d() * self.ny()) + self.d() * operand.ny() * self.d()
- self.nx() * operand.nx() * self.ny()
+ self.nx() * operand.ny() * self.nx()
- self.ny() * operand.d() * self.d()
- self.ny() * operand.nx() * self.nx()
- self.ny() * operand.ny() * self.ny())
* inv_norm_sq,
(-(self.d() * operand.d() * self.d())
- self.d() * operand.nx() * self.nx()
- self.d() * operand.ny() * self.ny()
+ self.nx() * operand.d() * self.nx()
- self.nx() * operand.nx() * self.d()
+ self.ny() * operand.d() * self.ny()
- self.ny() * operand.ny() * self.d())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Motor<T>> for Line<T> {
type Output = Motor<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Motor<T>) -> Option<Motor<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Motor::new_unchecked(
(-(self.d() * operand.e1ep() * self.nx()) + self.d() * operand.m() * self.ny()
- self.d() * operand.s() * self.d()
+ self.nx() * operand.e1ep() * self.d()
- self.nx() * operand.e2ep() * self.ny()
- self.nx() * operand.s() * self.nx()
+ self.ny() * operand.e2ep() * self.nx()
- self.ny() * operand.m() * self.d()
- self.ny() * operand.s() * self.ny())
* inv_norm_sq,
(-(self.d() * operand.e2ep() * self.nx())
+ self.d() * operand.m() * self.d()
+ self.d() * operand.s() * self.ny()
- self.nx() * operand.e1ep() * self.ny()
- self.nx() * operand.e2ep() * self.d()
- self.nx() * operand.m() * self.nx()
- self.ny() * operand.e1ep() * self.nx()
+ self.ny() * operand.m() * self.ny()
- self.ny() * operand.s() * self.d())
* inv_norm_sq,
(self.d() * operand.e1ep() * self.d()
- self.d() * operand.e2ep() * self.ny()
- self.d() * operand.s() * self.nx()
+ self.nx() * operand.e1ep() * self.nx()
- self.nx() * operand.m() * self.ny()
+ self.nx() * operand.s() * self.d()
- self.ny() * operand.e1ep() * self.ny()
- self.ny() * operand.e2ep() * self.d()
- self.ny() * operand.m() * self.nx())
* inv_norm_sq,
(-(self.d() * operand.e1ep() * self.ny())
- self.d() * operand.e2ep() * self.d()
- self.d() * operand.m() * self.nx()
+ self.nx() * operand.e2ep() * self.nx()
- self.nx() * operand.m() * self.d()
- self.nx() * operand.s() * self.ny()
- self.ny() * operand.e1ep() * self.d()
+ self.ny() * operand.e2ep() * self.ny()
+ self.ny() * operand.s() * self.nx())
* inv_norm_sq,
(self.d() * operand.e1em() * self.d() - self.d() * operand.e2em() * self.ny()
+ self.d() * operand.epem() * self.nx()
- self.nx() * operand.e1em() * self.nx()
+ self.nx() * operand.epem() * self.d()
- self.nx() * operand.ps() * self.ny()
- self.ny() * operand.e1em() * self.ny()
- self.ny() * operand.e2em() * self.d()
+ self.ny() * operand.ps() * self.nx())
* inv_norm_sq,
(-(self.d() * operand.e1em() * self.ny()) - self.d() * operand.e2em() * self.d()
+ self.d() * operand.ps() * self.nx()
- self.nx() * operand.e2em() * self.nx()
- self.nx() * operand.epem() * self.ny()
- self.nx() * operand.ps() * self.d()
- self.ny() * operand.e1em() * self.d()
+ self.ny() * operand.e2em() * self.ny()
- self.ny() * operand.epem() * self.nx())
* inv_norm_sq,
(self.d() * operand.e1em() * self.nx() - self.d() * operand.epem() * self.d()
+ self.d() * operand.ps() * self.ny()
+ self.nx() * operand.e1em() * self.d()
- self.nx() * operand.e2em() * self.ny()
+ self.nx() * operand.epem() * self.nx()
- self.ny() * operand.e2em() * self.nx()
- self.ny() * operand.epem() * self.ny()
- self.ny() * operand.ps() * self.d())
* inv_norm_sq,
(self.d() * operand.e2em() * self.nx()
+ self.d() * operand.epem() * self.ny()
+ self.d() * operand.ps() * self.d()
- self.nx() * operand.e1em() * self.ny()
- self.nx() * operand.e2em() * self.d()
+ self.nx() * operand.ps() * self.nx()
+ self.ny() * operand.e1em() * self.nx()
- self.ny() * operand.epem() * self.d()
+ self.ny() * operand.ps() * self.ny())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<PointPair<T>> for Line<T> {
type Output = PointPair<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &PointPair<T>) -> Option<PointPair<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(PointPair::new_unchecked(
(-(self.d() * operand.e2ep() * self.nx()) + self.d() * operand.m() * self.d()
- self.nx() * operand.e1ep() * self.ny()
- self.nx() * operand.e2ep() * self.d()
- self.nx() * operand.m() * self.nx()
- self.ny() * operand.e1ep() * self.nx()
+ self.ny() * operand.m() * self.ny())
* inv_norm_sq,
(self.d() * operand.e1ep() * self.d() - self.d() * operand.e2ep() * self.ny()
+ self.nx() * operand.e1ep() * self.nx()
- self.nx() * operand.m() * self.ny()
- self.ny() * operand.e1ep() * self.ny()
- self.ny() * operand.e2ep() * self.d()
- self.ny() * operand.m() * self.nx())
* inv_norm_sq,
(-(self.d() * operand.e1ep() * self.ny())
- self.d() * operand.e2ep() * self.d()
- self.d() * operand.m() * self.nx()
+ self.nx() * operand.e2ep() * self.nx()
- self.nx() * operand.m() * self.d()
- self.ny() * operand.e1ep() * self.d()
+ self.ny() * operand.e2ep() * self.ny())
* inv_norm_sq,
(self.d() * operand.e1em() * self.d() - self.d() * operand.e2em() * self.ny()
+ self.d() * operand.epem() * self.nx()
- self.nx() * operand.e1em() * self.nx()
+ self.nx() * operand.epem() * self.d()
- self.ny() * operand.e1em() * self.ny()
- self.ny() * operand.e2em() * self.d())
* inv_norm_sq,
(-(self.d() * operand.e1em() * self.ny())
- self.d() * operand.e2em() * self.d()
- self.nx() * operand.e2em() * self.nx()
- self.nx() * operand.epem() * self.ny()
- self.ny() * operand.e1em() * self.d()
+ self.ny() * operand.e2em() * self.ny()
- self.ny() * operand.epem() * self.nx())
* inv_norm_sq,
(self.d() * operand.e1em() * self.nx() - self.d() * operand.epem() * self.d()
+ self.nx() * operand.e1em() * self.d()
- self.nx() * operand.e2em() * self.ny()
+ self.nx() * operand.epem() * self.nx()
- self.ny() * operand.e2em() * self.nx()
- self.ny() * operand.epem() * self.ny())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Pseudoscalar<T>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Pseudoscalar<T>) -> Option<Pseudoscalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Pseudoscalar::new_unchecked(
(self.d() * operand.ps() * self.d()
+ self.nx() * operand.ps() * self.nx()
+ self.ny() * operand.ps() * self.ny())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<RoundPoint<T>> for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &RoundPoint<T>) -> Option<RoundPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(RoundPoint::new_unchecked(
(self.d() * operand.ep() * self.nx() + self.d() * operand.x() * self.d()
- self.d() * operand.y() * self.ny()
+ self.nx() * operand.ep() * self.d()
- self.nx() * operand.x() * self.nx()
- self.ny() * operand.x() * self.ny()
- self.ny() * operand.y() * self.d())
* inv_norm_sq,
(-(self.d() * operand.x() * self.ny())
- self.d() * operand.y() * self.d()
- self.nx() * operand.ep() * self.ny()
- self.nx() * operand.y() * self.nx()
- self.ny() * operand.ep() * self.nx()
- self.ny() * operand.x() * self.d()
+ self.ny() * operand.y() * self.ny())
* inv_norm_sq,
(-(self.d() * operand.ep() * self.d())
+ self.d() * operand.x() * self.nx()
+ self.nx() * operand.ep() * self.nx()
+ self.nx() * operand.x() * self.d()
- self.nx() * operand.y() * self.ny()
- self.ny() * operand.ep() * self.ny()
- self.ny() * operand.y() * self.nx())
* inv_norm_sq,
(-(self.d() * operand.em() * self.d())
- self.nx() * operand.em() * self.nx()
- self.ny() * operand.em() * self.ny())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Scalar<T>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Scalar<T>) -> Option<Scalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Scalar::new_unchecked(
(-(self.d() * operand.s() * self.d())
- self.nx() * operand.s() * self.nx()
- self.ny() * operand.s() * self.ny())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Circle<T>> for Motor<T> {
type Output = Circle<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Circle<T>) -> Option<Circle<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Circle::new_unchecked(
(-(self.e1em() * operand.e12em() * self.e1ep())
+ self.e1em() * operand.e1epem() * self.m()
- self.e1em() * operand.e2epem() * self.s()
+ self.e1em() * operand.w() * self.e1em()
- self.e1ep() * operand.e12em() * self.e1em()
- self.e1ep() * operand.e1epem() * self.ps()
+ self.e1ep() * operand.e2epem() * self.epem()
+ self.e1ep() * operand.w() * self.e1ep()
- self.e2em() * operand.e12em() * self.e2ep()
+ self.e2em() * operand.e1epem() * self.s()
+ self.e2em() * operand.e2epem() * self.m()
+ self.e2em() * operand.w() * self.e2em()
- self.e2ep() * operand.e12em() * self.e2em()
- self.e2ep() * operand.e1epem() * self.epem()
- self.e2ep() * operand.e2epem() * self.ps()
+ self.e2ep() * operand.w() * self.e2ep()
- self.epem() * operand.e12em() * self.s()
- self.epem() * operand.e1epem() * self.e2ep()
+ self.epem() * operand.e2epem() * self.e1ep()
+ self.epem() * operand.w() * self.epem()
- self.m() * operand.e12em() * self.ps()
+ self.m() * operand.e1epem() * self.e1em()
+ self.m() * operand.e2epem() * self.e2em()
+ self.m() * operand.w() * self.m()
- self.ps() * operand.e12em() * self.m()
- self.ps() * operand.e1epem() * self.e1ep()
- self.ps() * operand.e2epem() * self.e2ep()
+ self.ps() * operand.w() * self.ps()
- self.s() * operand.e12em() * self.epem()
+ self.s() * operand.e1epem() * self.e2em()
- self.s() * operand.e2epem() * self.e1em()
+ self.s() * operand.w() * self.s())
* inv_norm_sq,
(-(self.e1em() * operand.e12em() * self.e1em())
- self.e1em() * operand.e1epem() * self.ps()
+ self.e1em() * operand.e2epem() * self.epem()
+ self.e1em() * operand.w() * self.e1ep()
- self.e1ep() * operand.e12em() * self.e1ep()
+ self.e1ep() * operand.e1epem() * self.m()
- self.e1ep() * operand.e2epem() * self.s()
+ self.e1ep() * operand.w() * self.e1em()
- self.e2em() * operand.e12em() * self.e2em()
- self.e2em() * operand.e1epem() * self.epem()
- self.e2em() * operand.e2epem() * self.ps()
+ self.e2em() * operand.w() * self.e2ep()
- self.e2ep() * operand.e12em() * self.e2ep()
+ self.e2ep() * operand.e1epem() * self.s()
+ self.e2ep() * operand.e2epem() * self.m()
+ self.e2ep() * operand.w() * self.e2em()
+ self.epem() * operand.e12em() * self.epem()
- self.epem() * operand.e1epem() * self.e2em()
+ self.epem() * operand.e2epem() * self.e1em()
- self.epem() * operand.w() * self.s()
+ self.m() * operand.e12em() * self.m()
+ self.m() * operand.e1epem() * self.e1ep()
+ self.m() * operand.e2epem() * self.e2ep()
- self.m() * operand.w() * self.ps()
+ self.ps() * operand.e12em() * self.ps()
- self.ps() * operand.e1epem() * self.e1em()
- self.ps() * operand.e2epem() * self.e2em()
- self.ps() * operand.w() * self.m()
+ self.s() * operand.e12em() * self.s()
+ self.s() * operand.e1epem() * self.e2ep()
- self.s() * operand.e2epem() * self.e1ep()
- self.s() * operand.w() * self.epem())
* inv_norm_sq,
(self.e1em() * operand.e12em() * self.ps()
- self.e1em() * operand.e1epem() * self.e1em()
- self.e1em() * operand.e2epem() * self.e2em()
- self.e1em() * operand.w() * self.m()
+ self.e1ep() * operand.e12em() * self.m()
+ self.e1ep() * operand.e1epem() * self.e1ep()
+ self.e1ep() * operand.e2epem() * self.e2ep()
- self.e1ep() * operand.w() * self.ps()
- self.e2em() * operand.e12em() * self.epem()
+ self.e2em() * operand.e1epem() * self.e2em()
- self.e2em() * operand.e2epem() * self.e1em()
+ self.e2em() * operand.w() * self.s()
- self.e2ep() * operand.e12em() * self.s()
- self.e2ep() * operand.e1epem() * self.e2ep()
+ self.e2ep() * operand.e2epem() * self.e1ep()
+ self.e2ep() * operand.w() * self.epem()
- self.epem() * operand.e12em() * self.e2em()
- self.epem() * operand.e1epem() * self.epem()
- self.epem() * operand.e2epem() * self.ps()
+ self.epem() * operand.w() * self.e2ep()
+ self.m() * operand.e12em() * self.e1ep()
- self.m() * operand.e1epem() * self.m()
+ self.m() * operand.e2epem() * self.s()
- self.m() * operand.w() * self.e1em()
+ self.ps() * operand.e12em() * self.e1em()
+ self.ps() * operand.e1epem() * self.ps()
- self.ps() * operand.e2epem() * self.epem()
- self.ps() * operand.w() * self.e1ep()
- self.s() * operand.e12em() * self.e2ep()
+ self.s() * operand.e1epem() * self.s()
+ self.s() * operand.e2epem() * self.m()
+ self.s() * operand.w() * self.e2em())
* inv_norm_sq,
(self.e1em() * operand.e12em() * self.epem()
- self.e1em() * operand.e1epem() * self.e2em()
+ self.e1em() * operand.e2epem() * self.e1em()
- self.e1em() * operand.w() * self.s()
+ self.e1ep() * operand.e12em() * self.s()
+ self.e1ep() * operand.e1epem() * self.e2ep()
- self.e1ep() * operand.e2epem() * self.e1ep()
- self.e1ep() * operand.w() * self.epem()
+ self.e2em() * operand.e12em() * self.ps()
- self.e2em() * operand.e1epem() * self.e1em()
- self.e2em() * operand.e2epem() * self.e2em()
- self.e2em() * operand.w() * self.m()
+ self.e2ep() * operand.e12em() * self.m()
+ self.e2ep() * operand.e1epem() * self.e1ep()
+ self.e2ep() * operand.e2epem() * self.e2ep()
- self.e2ep() * operand.w() * self.ps()
+ self.epem() * operand.e12em() * self.e1em()
+ self.epem() * operand.e1epem() * self.ps()
- self.epem() * operand.e2epem() * self.epem()
- self.epem() * operand.w() * self.e1ep()
+ self.m() * operand.e12em() * self.e2ep()
- self.m() * operand.e1epem() * self.s()
- self.m() * operand.e2epem() * self.m()
- self.m() * operand.w() * self.e2em()
+ self.ps() * operand.e12em() * self.e2em()
+ self.ps() * operand.e1epem() * self.epem()
+ self.ps() * operand.e2epem() * self.ps()
- self.ps() * operand.w() * self.e2ep()
+ self.s() * operand.e12em() * self.e1ep()
- self.s() * operand.e1epem() * self.m()
+ self.s() * operand.e2epem() * self.s()
- self.s() * operand.w() * self.e1em())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<FlatPoint<T>> for Motor<T> {
type Output = FlatPoint<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &FlatPoint<T>) -> Option<FlatPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(FlatPoint::new_unchecked(
(-(self.e1em() * operand.e1em() * self.e1em())
- self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.epem() * self.epem()
- self.e1ep() * operand.e1em() * self.e1ep()
- self.e1ep() * operand.e2em() * self.e2ep()
+ self.e1ep() * operand.epem() * self.s()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e2em() * self.e1em()
- self.e2em() * operand.epem() * self.ps()
+ self.e2ep() * operand.e1em() * self.e2ep()
- self.e2ep() * operand.e2em() * self.e1ep()
+ self.e2ep() * operand.epem() * self.m()
+ self.epem() * operand.e1em() * self.epem()
+ self.epem() * operand.e2em() * self.ps()
- self.epem() * operand.epem() * self.e1em()
- self.m() * operand.e1em() * self.m()
+ self.m() * operand.e2em() * self.s()
+ self.m() * operand.epem() * self.e2ep()
- self.ps() * operand.e1em() * self.ps()
+ self.ps() * operand.e2em() * self.epem()
- self.ps() * operand.epem() * self.e2em()
+ self.s() * operand.e1em() * self.s()
+ self.s() * operand.e2em() * self.m()
+ self.s() * operand.epem() * self.e1ep())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e2em() * self.e1em()
+ self.e1em() * operand.epem() * self.ps()
- self.e1ep() * operand.e1em() * self.e2ep()
+ self.e1ep() * operand.e2em() * self.e1ep()
- self.e1ep() * operand.epem() * self.m()
- self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.epem() * self.epem()
- self.e2ep() * operand.e1em() * self.e1ep()
- self.e2ep() * operand.e2em() * self.e2ep()
+ self.e2ep() * operand.epem() * self.s()
- self.epem() * operand.e1em() * self.ps()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.epem() * self.e2em()
- self.m() * operand.e1em() * self.s()
- self.m() * operand.e2em() * self.m()
- self.m() * operand.epem() * self.e1ep()
- self.ps() * operand.e1em() * self.epem()
- self.ps() * operand.e2em() * self.ps()
+ self.ps() * operand.epem() * self.e1em()
- self.s() * operand.e1em() * self.m()
+ self.s() * operand.e2em() * self.s()
+ self.s() * operand.epem() * self.e2ep())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.epem())
- self.e1em() * operand.e2em() * self.ps()
+ self.e1em() * operand.epem() * self.e1em()
- self.e1ep() * operand.e1em() * self.s()
- self.e1ep() * operand.e2em() * self.m()
- self.e1ep() * operand.epem() * self.e1ep()
+ self.e2em() * operand.e1em() * self.ps()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.epem() * self.e2em()
+ self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.e2em() * self.s()
- self.e2ep() * operand.epem() * self.e2ep()
- self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.epem() * self.epem()
+ self.m() * operand.e1em() * self.e2ep()
- self.m() * operand.e2em() * self.e1ep()
+ self.m() * operand.epem() * self.m()
+ self.ps() * operand.e1em() * self.e2em()
- self.ps() * operand.e2em() * self.e1em()
- self.ps() * operand.epem() * self.ps()
- self.s() * operand.e1em() * self.e1ep()
- self.s() * operand.e2em() * self.e2ep()
+ self.s() * operand.epem() * self.s())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Line<T>> for Motor<T> {
type Output = Line<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Line<T>) -> Option<Line<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Line::new_unchecked(
(self.e1em() * operand.d() * self.epem()
- self.e1em() * operand.nx() * self.e1em()
- self.e1em() * operand.ny() * self.ps()
- self.e1ep() * operand.d() * self.s()
- self.e1ep() * operand.nx() * self.e1ep()
+ self.e1ep() * operand.ny() * self.m()
- self.e2em() * operand.d() * self.ps()
- self.e2em() * operand.nx() * self.e2em()
- self.e2em() * operand.ny() * self.epem()
+ self.e2ep() * operand.d() * self.m()
- self.e2ep() * operand.nx() * self.e2ep()
+ self.e2ep() * operand.ny() * self.s()
+ self.epem() * operand.d() * self.e1em()
+ self.epem() * operand.nx() * self.epem()
- self.epem() * operand.ny() * self.e2em()
+ self.m() * operand.d() * self.e2ep()
+ self.m() * operand.nx() * self.m()
+ self.m() * operand.ny() * self.e1ep()
- self.ps() * operand.d() * self.e2em()
+ self.ps() * operand.nx() * self.ps()
- self.ps() * operand.ny() * self.e1em()
- self.s() * operand.d() * self.e1ep()
+ self.s() * operand.nx() * self.s()
+ self.s() * operand.ny() * self.e2ep())
* inv_norm_sq,
(-(self.e1em() * operand.d() * self.e2em()) + self.e1em() * operand.nx() * self.ps()
- self.e1em() * operand.ny() * self.e1em()
+ self.e1ep() * operand.d() * self.e2ep()
+ self.e1ep() * operand.nx() * self.m()
+ self.e1ep() * operand.ny() * self.e1ep()
- self.e2em() * operand.d() * self.e1em()
- self.e2em() * operand.nx() * self.epem()
+ self.e2em() * operand.ny() * self.e2em()
+ self.e2ep() * operand.d() * self.e1ep()
- self.e2ep() * operand.nx() * self.s()
- self.e2ep() * operand.ny() * self.e2ep()
- self.epem() * operand.d() * self.ps()
- self.epem() * operand.nx() * self.e2em()
- self.epem() * operand.ny() * self.epem()
+ self.m() * operand.d() * self.s()
+ self.m() * operand.nx() * self.e1ep()
- self.m() * operand.ny() * self.m()
- self.ps() * operand.d() * self.epem()
+ self.ps() * operand.nx() * self.e1em()
+ self.ps() * operand.ny() * self.ps()
+ self.s() * operand.d() * self.m()
- self.s() * operand.nx() * self.e2ep()
+ self.s() * operand.ny() * self.s())
* inv_norm_sq,
(self.e1em() * operand.d() * self.e1em() + self.e1em() * operand.nx() * self.epem()
- self.e1em() * operand.ny() * self.e2em()
- self.e1ep() * operand.d() * self.e1ep()
+ self.e1ep() * operand.nx() * self.s()
+ self.e1ep() * operand.ny() * self.e2ep()
- self.e2em() * operand.d() * self.e2em()
+ self.e2em() * operand.nx() * self.ps()
- self.e2em() * operand.ny() * self.e1em()
+ self.e2ep() * operand.d() * self.e2ep()
+ self.e2ep() * operand.nx() * self.m()
+ self.e2ep() * operand.ny() * self.e1ep()
- self.epem() * operand.d() * self.epem()
+ self.epem() * operand.nx() * self.e1em()
+ self.epem() * operand.ny() * self.ps()
- self.m() * operand.d() * self.m()
+ self.m() * operand.nx() * self.e2ep()
- self.m() * operand.ny() * self.s()
+ self.ps() * operand.d() * self.ps()
+ self.ps() * operand.nx() * self.e2em()
+ self.ps() * operand.ny() * self.epem()
+ self.s() * operand.d() * self.s()
+ self.s() * operand.nx() * self.e1ep()
- self.s() * operand.ny() * self.m())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Motor<T>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Motor<T>) -> Option<Motor<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Motor::new_unchecked(
(self.e1em() * operand.e1em() * self.s() - self.e1em() * operand.e1ep() * self.epem()
+ self.e1em() * operand.e2em() * self.m()
- self.e1em() * operand.e2ep() * self.ps()
+ self.e1em() * operand.epem() * self.e1ep()
- self.e1em() * operand.m() * self.e2em()
+ self.e1em() * operand.ps() * self.e2ep()
- self.e1em() * operand.s() * self.e1em()
+ self.e1ep() * operand.e1em() * self.epem()
- self.e1ep() * operand.e1ep() * self.s()
+ self.e1ep() * operand.e2em() * self.ps()
- self.e1ep() * operand.e2ep() * self.m()
- self.e1ep() * operand.epem() * self.e1em()
+ self.e1ep() * operand.m() * self.e2ep()
- self.e1ep() * operand.ps() * self.e2em()
+ self.e1ep() * operand.s() * self.e1ep()
- self.e2em() * operand.e1em() * self.m()
+ self.e2em() * operand.e1ep() * self.ps()
+ self.e2em() * operand.e2em() * self.s()
- self.e2em() * operand.e2ep() * self.epem()
+ self.e2em() * operand.epem() * self.e2ep()
+ self.e2em() * operand.m() * self.e1em()
- self.e2em() * operand.ps() * self.e1ep()
- self.e2em() * operand.s() * self.e2em()
- self.e2ep() * operand.e1em() * self.ps()
+ self.e2ep() * operand.e1ep() * self.m()
+ self.e2ep() * operand.e2em() * self.epem()
- self.e2ep() * operand.e2ep() * self.s()
- self.e2ep() * operand.epem() * self.e2em()
- self.e2ep() * operand.m() * self.e1ep()
+ self.e2ep() * operand.ps() * self.e1em()
+ self.e2ep() * operand.s() * self.e2ep()
- self.epem() * operand.e1em() * self.e1ep()
+ self.epem() * operand.e1ep() * self.e1em()
- self.epem() * operand.e2em() * self.e2ep()
+ self.epem() * operand.e2ep() * self.e2em()
+ self.epem() * operand.epem() * self.s()
- self.epem() * operand.m() * self.ps()
+ self.epem() * operand.ps() * self.m()
- self.epem() * operand.s() * self.epem()
+ self.m() * operand.e1em() * self.e2em()
- self.m() * operand.e1ep() * self.e2ep()
- self.m() * operand.e2em() * self.e1em()
+ self.m() * operand.e2ep() * self.e1ep()
- self.m() * operand.epem() * self.ps()
- self.m() * operand.m() * self.s()
+ self.m() * operand.ps() * self.epem()
+ self.m() * operand.s() * self.m()
+ self.ps() * operand.e1em() * self.e2ep()
- self.ps() * operand.e1ep() * self.e2em()
- self.ps() * operand.e2em() * self.e1ep()
+ self.ps() * operand.e2ep() * self.e1em()
+ self.ps() * operand.epem() * self.m()
+ self.ps() * operand.m() * self.epem()
- self.ps() * operand.ps() * self.s()
- self.ps() * operand.s() * self.ps()
- self.s() * operand.e1em() * self.e1em()
+ self.s() * operand.e1ep() * self.e1ep()
- self.s() * operand.e2em() * self.e2em()
+ self.s() * operand.e2ep() * self.e2ep()
- self.s() * operand.epem() * self.epem()
+ self.s() * operand.m() * self.m()
- self.s() * operand.ps() * self.ps()
+ self.s() * operand.s() * self.s())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.m())
+ self.e1em() * operand.e1ep() * self.ps()
+ self.e1em() * operand.e2em() * self.s()
- self.e1em() * operand.e2ep() * self.epem()
+ self.e1em() * operand.epem() * self.e2ep()
+ self.e1em() * operand.m() * self.e1em()
- self.e1em() * operand.ps() * self.e1ep()
- self.e1em() * operand.s() * self.e2em()
- self.e1ep() * operand.e1em() * self.ps()
+ self.e1ep() * operand.e1ep() * self.m()
+ self.e1ep() * operand.e2em() * self.epem()
- self.e1ep() * operand.e2ep() * self.s()
- self.e1ep() * operand.epem() * self.e2em()
- self.e1ep() * operand.m() * self.e1ep()
+ self.e1ep() * operand.ps() * self.e1em()
+ self.e1ep() * operand.s() * self.e2ep()
- self.e2em() * operand.e1em() * self.s()
+ self.e2em() * operand.e1ep() * self.epem()
- self.e2em() * operand.e2em() * self.m()
+ self.e2em() * operand.e2ep() * self.ps()
- self.e2em() * operand.epem() * self.e1ep()
+ self.e2em() * operand.m() * self.e2em()
- self.e2em() * operand.ps() * self.e2ep()
+ self.e2em() * operand.s() * self.e1em()
- self.e2ep() * operand.e1em() * self.epem()
+ self.e2ep() * operand.e1ep() * self.s()
- self.e2ep() * operand.e2em() * self.ps()
+ self.e2ep() * operand.e2ep() * self.m()
+ self.e2ep() * operand.epem() * self.e1em()
- self.e2ep() * operand.m() * self.e2ep()
+ self.e2ep() * operand.ps() * self.e2em()
- self.e2ep() * operand.s() * self.e1ep()
- self.epem() * operand.e1em() * self.e2ep()
+ self.epem() * operand.e1ep() * self.e2em()
+ self.epem() * operand.e2em() * self.e1ep()
- self.epem() * operand.e2ep() * self.e1em()
- self.epem() * operand.epem() * self.m()
- self.epem() * operand.m() * self.epem()
+ self.epem() * operand.ps() * self.s()
+ self.epem() * operand.s() * self.ps()
- self.m() * operand.e1em() * self.e1em()
+ self.m() * operand.e1ep() * self.e1ep()
- self.m() * operand.e2em() * self.e2em()
+ self.m() * operand.e2ep() * self.e2ep()
- self.m() * operand.epem() * self.epem()
+ self.m() * operand.m() * self.m()
- self.m() * operand.ps() * self.ps()
+ self.m() * operand.s() * self.s()
- self.ps() * operand.e1em() * self.e1ep()
+ self.ps() * operand.e1ep() * self.e1em()
- self.ps() * operand.e2em() * self.e2ep()
+ self.ps() * operand.e2ep() * self.e2em()
+ self.ps() * operand.epem() * self.s()
- self.ps() * operand.m() * self.ps()
+ self.ps() * operand.ps() * self.m()
- self.ps() * operand.s() * self.epem()
- self.s() * operand.e1em() * self.e2em()
+ self.s() * operand.e1ep() * self.e2ep()
+ self.s() * operand.e2em() * self.e1em()
- self.s() * operand.e2ep() * self.e1ep()
+ self.s() * operand.epem() * self.ps()
+ self.s() * operand.m() * self.s()
- self.s() * operand.ps() * self.epem()
- self.s() * operand.s() * self.m())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e1ep())
+ self.e1em() * operand.e1ep() * self.e1em()
- self.e1em() * operand.e2em() * self.e2ep()
+ self.e1em() * operand.e2ep() * self.e2em()
+ self.e1em() * operand.epem() * self.s()
- self.e1em() * operand.m() * self.ps()
+ self.e1em() * operand.ps() * self.m()
- self.e1em() * operand.s() * self.epem()
- self.e1ep() * operand.e1em() * self.e1em()
+ self.e1ep() * operand.e1ep() * self.e1ep()
- self.e1ep() * operand.e2em() * self.e2em()
+ self.e1ep() * operand.e2ep() * self.e2ep()
- self.e1ep() * operand.epem() * self.epem()
+ self.e1ep() * operand.m() * self.m()
- self.e1ep() * operand.ps() * self.ps()
+ self.e1ep() * operand.s() * self.s()
+ self.e2em() * operand.e1em() * self.e2ep()
- self.e2em() * operand.e1ep() * self.e2em()
- self.e2em() * operand.e2em() * self.e1ep()
+ self.e2em() * operand.e2ep() * self.e1em()
+ self.e2em() * operand.epem() * self.m()
+ self.e2em() * operand.m() * self.epem()
- self.e2em() * operand.ps() * self.s()
- self.e2em() * operand.s() * self.ps()
+ self.e2ep() * operand.e1em() * self.e2em()
- self.e2ep() * operand.e1ep() * self.e2ep()
- self.e2ep() * operand.e2em() * self.e1em()
+ self.e2ep() * operand.e2ep() * self.e1ep()
- self.e2ep() * operand.epem() * self.ps()
- self.e2ep() * operand.m() * self.s()
+ self.e2ep() * operand.ps() * self.epem()
+ self.e2ep() * operand.s() * self.m()
- self.epem() * operand.e1em() * self.s()
+ self.epem() * operand.e1ep() * self.epem()
- self.epem() * operand.e2em() * self.m()
+ self.epem() * operand.e2ep() * self.ps()
- self.epem() * operand.epem() * self.e1ep()
+ self.epem() * operand.m() * self.e2em()
- self.epem() * operand.ps() * self.e2ep()
+ self.epem() * operand.s() * self.e1em()
+ self.m() * operand.e1em() * self.ps()
- self.m() * operand.e1ep() * self.m()
- self.m() * operand.e2em() * self.epem()
+ self.m() * operand.e2ep() * self.s()
+ self.m() * operand.epem() * self.e2em()
+ self.m() * operand.m() * self.e1ep()
- self.m() * operand.ps() * self.e1em()
- self.m() * operand.s() * self.e2ep()
+ self.ps() * operand.e1em() * self.m()
- self.ps() * operand.e1ep() * self.ps()
- self.ps() * operand.e2em() * self.s()
+ self.ps() * operand.e2ep() * self.epem()
- self.ps() * operand.epem() * self.e2ep()
- self.ps() * operand.m() * self.e1em()
+ self.ps() * operand.ps() * self.e1ep()
+ self.ps() * operand.s() * self.e2em()
- self.s() * operand.e1em() * self.epem()
+ self.s() * operand.e1ep() * self.s()
- self.s() * operand.e2em() * self.ps()
+ self.s() * operand.e2ep() * self.m()
+ self.s() * operand.epem() * self.e1em()
- self.s() * operand.m() * self.e2ep()
+ self.s() * operand.ps() * self.e2em()
- self.s() * operand.s() * self.e1ep())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e2ep())
+ self.e1em() * operand.e1ep() * self.e2em()
+ self.e1em() * operand.e2em() * self.e1ep()
- self.e1em() * operand.e2ep() * self.e1em()
- self.e1em() * operand.epem() * self.m()
- self.e1em() * operand.m() * self.epem()
+ self.e1em() * operand.ps() * self.s()
+ self.e1em() * operand.s() * self.ps()
- self.e1ep() * operand.e1em() * self.e2em()
+ self.e1ep() * operand.e1ep() * self.e2ep()
+ self.e1ep() * operand.e2em() * self.e1em()
- self.e1ep() * operand.e2ep() * self.e1ep()
+ self.e1ep() * operand.epem() * self.ps()
+ self.e1ep() * operand.m() * self.s()
- self.e1ep() * operand.ps() * self.epem()
- self.e1ep() * operand.s() * self.m()
- self.e2em() * operand.e1em() * self.e1ep()
+ self.e2em() * operand.e1ep() * self.e1em()
- self.e2em() * operand.e2em() * self.e2ep()
+ self.e2em() * operand.e2ep() * self.e2em()
+ self.e2em() * operand.epem() * self.s()
- self.e2em() * operand.m() * self.ps()
+ self.e2em() * operand.ps() * self.m()
- self.e2em() * operand.s() * self.epem()
- self.e2ep() * operand.e1em() * self.e1em()
+ self.e2ep() * operand.e1ep() * self.e1ep()
- self.e2ep() * operand.e2em() * self.e2em()
+ self.e2ep() * operand.e2ep() * self.e2ep()
- self.e2ep() * operand.epem() * self.epem()
+ self.e2ep() * operand.m() * self.m()
- self.e2ep() * operand.ps() * self.ps()
+ self.e2ep() * operand.s() * self.s()
+ self.epem() * operand.e1em() * self.m()
- self.epem() * operand.e1ep() * self.ps()
- self.epem() * operand.e2em() * self.s()
+ self.epem() * operand.e2ep() * self.epem()
- self.epem() * operand.epem() * self.e2ep()
- self.epem() * operand.m() * self.e1em()
+ self.epem() * operand.ps() * self.e1ep()
+ self.epem() * operand.s() * self.e2em()
+ self.m() * operand.e1em() * self.epem()
- self.m() * operand.e1ep() * self.s()
+ self.m() * operand.e2em() * self.ps()
- self.m() * operand.e2ep() * self.m()
- self.m() * operand.epem() * self.e1em()
+ self.m() * operand.m() * self.e2ep()
- self.m() * operand.ps() * self.e2em()
+ self.m() * operand.s() * self.e1ep()
+ self.ps() * operand.e1em() * self.s()
- self.ps() * operand.e1ep() * self.epem()
+ self.ps() * operand.e2em() * self.m()
- self.ps() * operand.e2ep() * self.ps()
+ self.ps() * operand.epem() * self.e1ep()
- self.ps() * operand.m() * self.e2em()
+ self.ps() * operand.ps() * self.e2ep()
- self.ps() * operand.s() * self.e1em()
+ self.s() * operand.e1em() * self.ps()
- self.s() * operand.e1ep() * self.m()
- self.s() * operand.e2em() * self.epem()
+ self.s() * operand.e2ep() * self.s()
+ self.s() * operand.epem() * self.e2em()
+ self.s() * operand.m() * self.e1ep()
- self.s() * operand.ps() * self.e1em()
- self.s() * operand.s() * self.e2ep())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e1em())
+ self.e1em() * operand.e1ep() * self.e1ep()
- self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.e2ep() * self.e2ep()
- self.e1em() * operand.epem() * self.epem()
+ self.e1em() * operand.m() * self.m()
- self.e1em() * operand.ps() * self.ps()
+ self.e1em() * operand.s() * self.s()
- self.e1ep() * operand.e1em() * self.e1ep()
+ self.e1ep() * operand.e1ep() * self.e1em()
- self.e1ep() * operand.e2em() * self.e2ep()
+ self.e1ep() * operand.e2ep() * self.e2em()
+ self.e1ep() * operand.epem() * self.s()
- self.e1ep() * operand.m() * self.ps()
+ self.e1ep() * operand.ps() * self.m()
- self.e1ep() * operand.s() * self.epem()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e1ep() * self.e2ep()
- self.e2em() * operand.e2em() * self.e1em()
+ self.e2em() * operand.e2ep() * self.e1ep()
- self.e2em() * operand.epem() * self.ps()
- self.e2em() * operand.m() * self.s()
+ self.e2em() * operand.ps() * self.epem()
+ self.e2em() * operand.s() * self.m()
+ self.e2ep() * operand.e1em() * self.e2ep()
- self.e2ep() * operand.e1ep() * self.e2em()
- self.e2ep() * operand.e2em() * self.e1ep()
+ self.e2ep() * operand.e2ep() * self.e1em()
+ self.e2ep() * operand.epem() * self.m()
+ self.e2ep() * operand.m() * self.epem()
- self.e2ep() * operand.ps() * self.s()
- self.e2ep() * operand.s() * self.ps()
+ self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.e1ep() * self.s()
+ self.epem() * operand.e2em() * self.ps()
- self.epem() * operand.e2ep() * self.m()
- self.epem() * operand.epem() * self.e1em()
+ self.epem() * operand.m() * self.e2ep()
- self.epem() * operand.ps() * self.e2em()
+ self.epem() * operand.s() * self.e1ep()
- self.m() * operand.e1em() * self.m()
+ self.m() * operand.e1ep() * self.ps()
+ self.m() * operand.e2em() * self.s()
- self.m() * operand.e2ep() * self.epem()
+ self.m() * operand.epem() * self.e2ep()
+ self.m() * operand.m() * self.e1em()
- self.m() * operand.ps() * self.e1ep()
- self.m() * operand.s() * self.e2em()
- self.ps() * operand.e1em() * self.ps()
+ self.ps() * operand.e1ep() * self.m()
+ self.ps() * operand.e2em() * self.epem()
- self.ps() * operand.e2ep() * self.s()
- self.ps() * operand.epem() * self.e2em()
- self.ps() * operand.m() * self.e1ep()
+ self.ps() * operand.ps() * self.e1em()
+ self.ps() * operand.s() * self.e2ep()
+ self.s() * operand.e1em() * self.s()
- self.s() * operand.e1ep() * self.epem()
+ self.s() * operand.e2em() * self.m()
- self.s() * operand.e2ep() * self.ps()
+ self.s() * operand.epem() * self.e1ep()
- self.s() * operand.m() * self.e2em()
+ self.s() * operand.ps() * self.e2ep()
- self.s() * operand.s() * self.e1em())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e1ep() * self.e2ep()
+ self.e1em() * operand.e2em() * self.e1em()
- self.e1em() * operand.e2ep() * self.e1ep()
+ self.e1em() * operand.epem() * self.ps()
+ self.e1em() * operand.m() * self.s()
- self.e1em() * operand.ps() * self.epem()
- self.e1em() * operand.s() * self.m()
- self.e1ep() * operand.e1em() * self.e2ep()
+ self.e1ep() * operand.e1ep() * self.e2em()
+ self.e1ep() * operand.e2em() * self.e1ep()
- self.e1ep() * operand.e2ep() * self.e1em()
- self.e1ep() * operand.epem() * self.m()
- self.e1ep() * operand.m() * self.epem()
+ self.e1ep() * operand.ps() * self.s()
+ self.e1ep() * operand.s() * self.ps()
- self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e1ep() * self.e1ep()
- self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.e2ep() * self.e2ep()
- self.e2em() * operand.epem() * self.epem()
+ self.e2em() * operand.m() * self.m()
- self.e2em() * operand.ps() * self.ps()
+ self.e2em() * operand.s() * self.s()
- self.e2ep() * operand.e1em() * self.e1ep()
+ self.e2ep() * operand.e1ep() * self.e1em()
- self.e2ep() * operand.e2em() * self.e2ep()
+ self.e2ep() * operand.e2ep() * self.e2em()
+ self.e2ep() * operand.epem() * self.s()
- self.e2ep() * operand.m() * self.ps()
+ self.e2ep() * operand.ps() * self.m()
- self.e2ep() * operand.s() * self.epem()
- self.epem() * operand.e1em() * self.ps()
+ self.epem() * operand.e1ep() * self.m()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.e2ep() * self.s()
- self.epem() * operand.epem() * self.e2em()
- self.epem() * operand.m() * self.e1ep()
+ self.epem() * operand.ps() * self.e1em()
+ self.epem() * operand.s() * self.e2ep()
- self.m() * operand.e1em() * self.s()
+ self.m() * operand.e1ep() * self.epem()
- self.m() * operand.e2em() * self.m()
+ self.m() * operand.e2ep() * self.ps()
- self.m() * operand.epem() * self.e1ep()
+ self.m() * operand.m() * self.e2em()
- self.m() * operand.ps() * self.e2ep()
+ self.m() * operand.s() * self.e1em()
- self.ps() * operand.e1em() * self.epem()
+ self.ps() * operand.e1ep() * self.s()
- self.ps() * operand.e2em() * self.ps()
+ self.ps() * operand.e2ep() * self.m()
+ self.ps() * operand.epem() * self.e1em()
- self.ps() * operand.m() * self.e2ep()
+ self.ps() * operand.ps() * self.e2em()
- self.ps() * operand.s() * self.e1ep()
- self.s() * operand.e1em() * self.m()
+ self.s() * operand.e1ep() * self.ps()
+ self.s() * operand.e2em() * self.s()
- self.s() * operand.e2ep() * self.epem()
+ self.s() * operand.epem() * self.e2ep()
+ self.s() * operand.m() * self.e1em()
- self.s() * operand.ps() * self.e1ep()
- self.s() * operand.s() * self.e2em())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.epem())
+ self.e1em() * operand.e1ep() * self.s()
- self.e1em() * operand.e2em() * self.ps()
+ self.e1em() * operand.e2ep() * self.m()
+ self.e1em() * operand.epem() * self.e1em()
- self.e1em() * operand.m() * self.e2ep()
+ self.e1em() * operand.ps() * self.e2em()
- self.e1em() * operand.s() * self.e1ep()
- self.e1ep() * operand.e1em() * self.s()
+ self.e1ep() * operand.e1ep() * self.epem()
- self.e1ep() * operand.e2em() * self.m()
+ self.e1ep() * operand.e2ep() * self.ps()
- self.e1ep() * operand.epem() * self.e1ep()
+ self.e1ep() * operand.m() * self.e2em()
- self.e1ep() * operand.ps() * self.e2ep()
+ self.e1ep() * operand.s() * self.e1em()
+ self.e2em() * operand.e1em() * self.ps()
- self.e2em() * operand.e1ep() * self.m()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.e2ep() * self.s()
+ self.e2em() * operand.epem() * self.e2em()
+ self.e2em() * operand.m() * self.e1ep()
- self.e2em() * operand.ps() * self.e1em()
- self.e2em() * operand.s() * self.e2ep()
+ self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.e1ep() * self.ps()
- self.e2ep() * operand.e2em() * self.s()
+ self.e2ep() * operand.e2ep() * self.epem()
- self.e2ep() * operand.epem() * self.e2ep()
- self.e2ep() * operand.m() * self.e1em()
+ self.e2ep() * operand.ps() * self.e1ep()
+ self.e2ep() * operand.s() * self.e2em()
- self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e1ep() * self.e1ep()
- self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.e2ep() * self.e2ep()
- self.epem() * operand.epem() * self.epem()
+ self.epem() * operand.m() * self.m()
- self.epem() * operand.ps() * self.ps()
+ self.epem() * operand.s() * self.s()
+ self.m() * operand.e1em() * self.e2ep()
- self.m() * operand.e1ep() * self.e2em()
- self.m() * operand.e2em() * self.e1ep()
+ self.m() * operand.e2ep() * self.e1em()
+ self.m() * operand.epem() * self.m()
+ self.m() * operand.m() * self.epem()
- self.m() * operand.ps() * self.s()
- self.m() * operand.s() * self.ps()
+ self.ps() * operand.e1em() * self.e2em()
- self.ps() * operand.e1ep() * self.e2ep()
- self.ps() * operand.e2em() * self.e1em()
+ self.ps() * operand.e2ep() * self.e1ep()
- self.ps() * operand.epem() * self.ps()
- self.ps() * operand.m() * self.s()
+ self.ps() * operand.ps() * self.epem()
+ self.ps() * operand.s() * self.m()
- self.s() * operand.e1em() * self.e1ep()
+ self.s() * operand.e1ep() * self.e1em()
- self.s() * operand.e2em() * self.e2ep()
+ self.s() * operand.e2ep() * self.e2em()
+ self.s() * operand.epem() * self.s()
- self.s() * operand.m() * self.ps()
+ self.s() * operand.ps() * self.m()
- self.s() * operand.s() * self.epem())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.ps()
- self.e1em() * operand.e1ep() * self.m()
- self.e1em() * operand.e2em() * self.epem()
+ self.e1em() * operand.e2ep() * self.s()
+ self.e1em() * operand.epem() * self.e2em()
+ self.e1em() * operand.m() * self.e1ep()
- self.e1em() * operand.ps() * self.e1em()
- self.e1em() * operand.s() * self.e2ep()
+ self.e1ep() * operand.e1em() * self.m()
- self.e1ep() * operand.e1ep() * self.ps()
- self.e1ep() * operand.e2em() * self.s()
+ self.e1ep() * operand.e2ep() * self.epem()
- self.e1ep() * operand.epem() * self.e2ep()
- self.e1ep() * operand.m() * self.e1em()
+ self.e1ep() * operand.ps() * self.e1ep()
+ self.e1ep() * operand.s() * self.e2em()
+ self.e2em() * operand.e1em() * self.epem()
- self.e2em() * operand.e1ep() * self.s()
+ self.e2em() * operand.e2em() * self.ps()
- self.e2em() * operand.e2ep() * self.m()
- self.e2em() * operand.epem() * self.e1em()
+ self.e2em() * operand.m() * self.e2ep()
- self.e2em() * operand.ps() * self.e2em()
+ self.e2em() * operand.s() * self.e1ep()
+ self.e2ep() * operand.e1em() * self.s()
- self.e2ep() * operand.e1ep() * self.epem()
+ self.e2ep() * operand.e2em() * self.m()
- self.e2ep() * operand.e2ep() * self.ps()
+ self.e2ep() * operand.epem() * self.e1ep()
- self.e2ep() * operand.m() * self.e2em()
+ self.e2ep() * operand.ps() * self.e2ep()
- self.e2ep() * operand.s() * self.e1em()
- self.epem() * operand.e1em() * self.e2em()
+ self.epem() * operand.e1ep() * self.e2ep()
+ self.epem() * operand.e2em() * self.e1em()
- self.epem() * operand.e2ep() * self.e1ep()
+ self.epem() * operand.epem() * self.ps()
+ self.epem() * operand.m() * self.s()
- self.epem() * operand.ps() * self.epem()
- self.epem() * operand.s() * self.m()
- self.m() * operand.e1em() * self.e1ep()
+ self.m() * operand.e1ep() * self.e1em()
- self.m() * operand.e2em() * self.e2ep()
+ self.m() * operand.e2ep() * self.e2em()
+ self.m() * operand.epem() * self.s()
- self.m() * operand.m() * self.ps()
+ self.m() * operand.ps() * self.m()
- self.m() * operand.s() * self.epem()
- self.ps() * operand.e1em() * self.e1em()
+ self.ps() * operand.e1ep() * self.e1ep()
- self.ps() * operand.e2em() * self.e2em()
+ self.ps() * operand.e2ep() * self.e2ep()
- self.ps() * operand.epem() * self.epem()
+ self.ps() * operand.m() * self.m()
- self.ps() * operand.ps() * self.ps()
+ self.ps() * operand.s() * self.s()
- self.s() * operand.e1em() * self.e2ep()
+ self.s() * operand.e1ep() * self.e2em()
+ self.s() * operand.e2em() * self.e1ep()
- self.s() * operand.e2ep() * self.e1em()
- self.s() * operand.epem() * self.m()
- self.s() * operand.m() * self.epem()
+ self.s() * operand.ps() * self.s()
+ self.s() * operand.s() * self.ps())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<PointPair<T>> for Motor<T> {
type Output = PointPair<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &PointPair<T>) -> Option<PointPair<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(PointPair::new_unchecked(
(-(self.e1em() * operand.e1em() * self.m())
+ self.e1em() * operand.e1ep() * self.ps()
+ self.e1em() * operand.e2em() * self.s()
- self.e1em() * operand.e2ep() * self.epem()
+ self.e1em() * operand.epem() * self.e2ep()
+ self.e1em() * operand.m() * self.e1em()
- self.e1ep() * operand.e1em() * self.ps()
+ self.e1ep() * operand.e1ep() * self.m()
+ self.e1ep() * operand.e2em() * self.epem()
- self.e1ep() * operand.e2ep() * self.s()
- self.e1ep() * operand.epem() * self.e2em()
- self.e1ep() * operand.m() * self.e1ep()
- self.e2em() * operand.e1em() * self.s()
+ self.e2em() * operand.e1ep() * self.epem()
- self.e2em() * operand.e2em() * self.m()
+ self.e2em() * operand.e2ep() * self.ps()
- self.e2em() * operand.epem() * self.e1ep()
+ self.e2em() * operand.m() * self.e2em()
- self.e2ep() * operand.e1em() * self.epem()
+ self.e2ep() * operand.e1ep() * self.s()
- self.e2ep() * operand.e2em() * self.ps()
+ self.e2ep() * operand.e2ep() * self.m()
+ self.e2ep() * operand.epem() * self.e1em()
- self.e2ep() * operand.m() * self.e2ep()
- self.epem() * operand.e1em() * self.e2ep()
+ self.epem() * operand.e1ep() * self.e2em()
+ self.epem() * operand.e2em() * self.e1ep()
- self.epem() * operand.e2ep() * self.e1em()
- self.epem() * operand.epem() * self.m()
- self.epem() * operand.m() * self.epem()
- self.m() * operand.e1em() * self.e1em()
+ self.m() * operand.e1ep() * self.e1ep()
- self.m() * operand.e2em() * self.e2em()
+ self.m() * operand.e2ep() * self.e2ep()
- self.m() * operand.epem() * self.epem()
+ self.m() * operand.m() * self.m()
- self.ps() * operand.e1em() * self.e1ep()
+ self.ps() * operand.e1ep() * self.e1em()
- self.ps() * operand.e2em() * self.e2ep()
+ self.ps() * operand.e2ep() * self.e2em()
+ self.ps() * operand.epem() * self.s()
- self.ps() * operand.m() * self.ps()
- self.s() * operand.e1em() * self.e2em()
+ self.s() * operand.e1ep() * self.e2ep()
+ self.s() * operand.e2em() * self.e1em()
- self.s() * operand.e2ep() * self.e1ep()
+ self.s() * operand.epem() * self.ps()
+ self.s() * operand.m() * self.s())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e1ep())
+ self.e1em() * operand.e1ep() * self.e1em()
- self.e1em() * operand.e2em() * self.e2ep()
+ self.e1em() * operand.e2ep() * self.e2em()
+ self.e1em() * operand.epem() * self.s()
- self.e1em() * operand.m() * self.ps()
- self.e1ep() * operand.e1em() * self.e1em()
+ self.e1ep() * operand.e1ep() * self.e1ep()
- self.e1ep() * operand.e2em() * self.e2em()
+ self.e1ep() * operand.e2ep() * self.e2ep()
- self.e1ep() * operand.epem() * self.epem()
+ self.e1ep() * operand.m() * self.m()
+ self.e2em() * operand.e1em() * self.e2ep()
- self.e2em() * operand.e1ep() * self.e2em()
- self.e2em() * operand.e2em() * self.e1ep()
+ self.e2em() * operand.e2ep() * self.e1em()
+ self.e2em() * operand.epem() * self.m()
+ self.e2em() * operand.m() * self.epem()
+ self.e2ep() * operand.e1em() * self.e2em()
- self.e2ep() * operand.e1ep() * self.e2ep()
- self.e2ep() * operand.e2em() * self.e1em()
+ self.e2ep() * operand.e2ep() * self.e1ep()
- self.e2ep() * operand.epem() * self.ps()
- self.e2ep() * operand.m() * self.s()
- self.epem() * operand.e1em() * self.s()
+ self.epem() * operand.e1ep() * self.epem()
- self.epem() * operand.e2em() * self.m()
+ self.epem() * operand.e2ep() * self.ps()
- self.epem() * operand.epem() * self.e1ep()
+ self.epem() * operand.m() * self.e2em()
+ self.m() * operand.e1em() * self.ps()
- self.m() * operand.e1ep() * self.m()
- self.m() * operand.e2em() * self.epem()
+ self.m() * operand.e2ep() * self.s()
+ self.m() * operand.epem() * self.e2em()
+ self.m() * operand.m() * self.e1ep()
+ self.ps() * operand.e1em() * self.m()
- self.ps() * operand.e1ep() * self.ps()
- self.ps() * operand.e2em() * self.s()
+ self.ps() * operand.e2ep() * self.epem()
- self.ps() * operand.epem() * self.e2ep()
- self.ps() * operand.m() * self.e1em()
- self.s() * operand.e1em() * self.epem()
+ self.s() * operand.e1ep() * self.s()
- self.s() * operand.e2em() * self.ps()
+ self.s() * operand.e2ep() * self.m()
+ self.s() * operand.epem() * self.e1em()
- self.s() * operand.m() * self.e2ep())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e2ep())
+ self.e1em() * operand.e1ep() * self.e2em()
+ self.e1em() * operand.e2em() * self.e1ep()
- self.e1em() * operand.e2ep() * self.e1em()
- self.e1em() * operand.epem() * self.m()
- self.e1em() * operand.m() * self.epem()
- self.e1ep() * operand.e1em() * self.e2em()
+ self.e1ep() * operand.e1ep() * self.e2ep()
+ self.e1ep() * operand.e2em() * self.e1em()
- self.e1ep() * operand.e2ep() * self.e1ep()
+ self.e1ep() * operand.epem() * self.ps()
+ self.e1ep() * operand.m() * self.s()
- self.e2em() * operand.e1em() * self.e1ep()
+ self.e2em() * operand.e1ep() * self.e1em()
- self.e2em() * operand.e2em() * self.e2ep()
+ self.e2em() * operand.e2ep() * self.e2em()
+ self.e2em() * operand.epem() * self.s()
- self.e2em() * operand.m() * self.ps()
- self.e2ep() * operand.e1em() * self.e1em()
+ self.e2ep() * operand.e1ep() * self.e1ep()
- self.e2ep() * operand.e2em() * self.e2em()
+ self.e2ep() * operand.e2ep() * self.e2ep()
- self.e2ep() * operand.epem() * self.epem()
+ self.e2ep() * operand.m() * self.m()
+ self.epem() * operand.e1em() * self.m()
- self.epem() * operand.e1ep() * self.ps()
- self.epem() * operand.e2em() * self.s()
+ self.epem() * operand.e2ep() * self.epem()
- self.epem() * operand.epem() * self.e2ep()
- self.epem() * operand.m() * self.e1em()
+ self.m() * operand.e1em() * self.epem()
- self.m() * operand.e1ep() * self.s()
+ self.m() * operand.e2em() * self.ps()
- self.m() * operand.e2ep() * self.m()
- self.m() * operand.epem() * self.e1em()
+ self.m() * operand.m() * self.e2ep()
+ self.ps() * operand.e1em() * self.s()
- self.ps() * operand.e1ep() * self.epem()
+ self.ps() * operand.e2em() * self.m()
- self.ps() * operand.e2ep() * self.ps()
+ self.ps() * operand.epem() * self.e1ep()
- self.ps() * operand.m() * self.e2em()
+ self.s() * operand.e1em() * self.ps()
- self.s() * operand.e1ep() * self.m()
- self.s() * operand.e2em() * self.epem()
+ self.s() * operand.e2ep() * self.s()
+ self.s() * operand.epem() * self.e2em()
+ self.s() * operand.m() * self.e1ep())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e1em())
+ self.e1em() * operand.e1ep() * self.e1ep()
- self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.e2ep() * self.e2ep()
- self.e1em() * operand.epem() * self.epem()
+ self.e1em() * operand.m() * self.m()
- self.e1ep() * operand.e1em() * self.e1ep()
+ self.e1ep() * operand.e1ep() * self.e1em()
- self.e1ep() * operand.e2em() * self.e2ep()
+ self.e1ep() * operand.e2ep() * self.e2em()
+ self.e1ep() * operand.epem() * self.s()
- self.e1ep() * operand.m() * self.ps()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e1ep() * self.e2ep()
- self.e2em() * operand.e2em() * self.e1em()
+ self.e2em() * operand.e2ep() * self.e1ep()
- self.e2em() * operand.epem() * self.ps()
- self.e2em() * operand.m() * self.s()
+ self.e2ep() * operand.e1em() * self.e2ep()
- self.e2ep() * operand.e1ep() * self.e2em()
- self.e2ep() * operand.e2em() * self.e1ep()
+ self.e2ep() * operand.e2ep() * self.e1em()
+ self.e2ep() * operand.epem() * self.m()
+ self.e2ep() * operand.m() * self.epem()
+ self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.e1ep() * self.s()
+ self.epem() * operand.e2em() * self.ps()
- self.epem() * operand.e2ep() * self.m()
- self.epem() * operand.epem() * self.e1em()
+ self.epem() * operand.m() * self.e2ep()
- self.m() * operand.e1em() * self.m()
+ self.m() * operand.e1ep() * self.ps()
+ self.m() * operand.e2em() * self.s()
- self.m() * operand.e2ep() * self.epem()
+ self.m() * operand.epem() * self.e2ep()
+ self.m() * operand.m() * self.e1em()
- self.ps() * operand.e1em() * self.ps()
+ self.ps() * operand.e1ep() * self.m()
+ self.ps() * operand.e2em() * self.epem()
- self.ps() * operand.e2ep() * self.s()
- self.ps() * operand.epem() * self.e2em()
- self.ps() * operand.m() * self.e1ep()
+ self.s() * operand.e1em() * self.s()
- self.s() * operand.e1ep() * self.epem()
+ self.s() * operand.e2em() * self.m()
- self.s() * operand.e2ep() * self.ps()
+ self.s() * operand.epem() * self.e1ep()
- self.s() * operand.m() * self.e2em())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e1ep() * self.e2ep()
+ self.e1em() * operand.e2em() * self.e1em()
- self.e1em() * operand.e2ep() * self.e1ep()
+ self.e1em() * operand.epem() * self.ps()
+ self.e1em() * operand.m() * self.s()
- self.e1ep() * operand.e1em() * self.e2ep()
+ self.e1ep() * operand.e1ep() * self.e2em()
+ self.e1ep() * operand.e2em() * self.e1ep()
- self.e1ep() * operand.e2ep() * self.e1em()
- self.e1ep() * operand.epem() * self.m()
- self.e1ep() * operand.m() * self.epem()
- self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e1ep() * self.e1ep()
- self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.e2ep() * self.e2ep()
- self.e2em() * operand.epem() * self.epem()
+ self.e2em() * operand.m() * self.m()
- self.e2ep() * operand.e1em() * self.e1ep()
+ self.e2ep() * operand.e1ep() * self.e1em()
- self.e2ep() * operand.e2em() * self.e2ep()
+ self.e2ep() * operand.e2ep() * self.e2em()
+ self.e2ep() * operand.epem() * self.s()
- self.e2ep() * operand.m() * self.ps()
- self.epem() * operand.e1em() * self.ps()
+ self.epem() * operand.e1ep() * self.m()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.e2ep() * self.s()
- self.epem() * operand.epem() * self.e2em()
- self.epem() * operand.m() * self.e1ep()
- self.m() * operand.e1em() * self.s()
+ self.m() * operand.e1ep() * self.epem()
- self.m() * operand.e2em() * self.m()
+ self.m() * operand.e2ep() * self.ps()
- self.m() * operand.epem() * self.e1ep()
+ self.m() * operand.m() * self.e2em()
- self.ps() * operand.e1em() * self.epem()
+ self.ps() * operand.e1ep() * self.s()
- self.ps() * operand.e2em() * self.ps()
+ self.ps() * operand.e2ep() * self.m()
+ self.ps() * operand.epem() * self.e1em()
- self.ps() * operand.m() * self.e2ep()
- self.s() * operand.e1em() * self.m()
+ self.s() * operand.e1ep() * self.ps()
+ self.s() * operand.e2em() * self.s()
- self.s() * operand.e2ep() * self.epem()
+ self.s() * operand.epem() * self.e2ep()
+ self.s() * operand.m() * self.e1em())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.epem())
+ self.e1em() * operand.e1ep() * self.s()
- self.e1em() * operand.e2em() * self.ps()
+ self.e1em() * operand.e2ep() * self.m()
+ self.e1em() * operand.epem() * self.e1em()
- self.e1em() * operand.m() * self.e2ep()
- self.e1ep() * operand.e1em() * self.s()
+ self.e1ep() * operand.e1ep() * self.epem()
- self.e1ep() * operand.e2em() * self.m()
+ self.e1ep() * operand.e2ep() * self.ps()
- self.e1ep() * operand.epem() * self.e1ep()
+ self.e1ep() * operand.m() * self.e2em()
+ self.e2em() * operand.e1em() * self.ps()
- self.e2em() * operand.e1ep() * self.m()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.e2ep() * self.s()
+ self.e2em() * operand.epem() * self.e2em()
+ self.e2em() * operand.m() * self.e1ep()
+ self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.e1ep() * self.ps()
- self.e2ep() * operand.e2em() * self.s()
+ self.e2ep() * operand.e2ep() * self.epem()
- self.e2ep() * operand.epem() * self.e2ep()
- self.e2ep() * operand.m() * self.e1em()
- self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e1ep() * self.e1ep()
- self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.e2ep() * self.e2ep()
- self.epem() * operand.epem() * self.epem()
+ self.epem() * operand.m() * self.m()
+ self.m() * operand.e1em() * self.e2ep()
- self.m() * operand.e1ep() * self.e2em()
- self.m() * operand.e2em() * self.e1ep()
+ self.m() * operand.e2ep() * self.e1em()
+ self.m() * operand.epem() * self.m()
+ self.m() * operand.m() * self.epem()
+ self.ps() * operand.e1em() * self.e2em()
- self.ps() * operand.e1ep() * self.e2ep()
- self.ps() * operand.e2em() * self.e1em()
+ self.ps() * operand.e2ep() * self.e1ep()
- self.ps() * operand.epem() * self.ps()
- self.ps() * operand.m() * self.s()
- self.s() * operand.e1em() * self.e1ep()
+ self.s() * operand.e1ep() * self.e1em()
- self.s() * operand.e2em() * self.e2ep()
+ self.s() * operand.e2ep() * self.e2em()
+ self.s() * operand.epem() * self.s()
- self.s() * operand.m() * self.ps())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Pseudoscalar<T>> for Motor<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Pseudoscalar<T>) -> Option<Pseudoscalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Pseudoscalar::new_unchecked(
(-(self.e1em() * operand.ps() * self.e1em())
+ self.e1ep() * operand.ps() * self.e1ep()
- self.e2em() * operand.ps() * self.e2em()
+ self.e2ep() * operand.ps() * self.e2ep()
- self.epem() * operand.ps() * self.epem()
+ self.m() * operand.ps() * self.m()
- self.ps() * operand.ps() * self.ps()
+ self.s() * operand.ps() * self.s())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<RoundPoint<T>> for Motor<T> {
type Output = RoundPoint<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &RoundPoint<T>) -> Option<RoundPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(RoundPoint::new_unchecked(
(-(self.e1em() * operand.em() * self.s())
+ self.e1em() * operand.ep() * self.epem()
+ self.e1em() * operand.x() * self.e1em()
+ self.e1em() * operand.y() * self.e2em()
- self.e1ep() * operand.em() * self.epem()
+ self.e1ep() * operand.ep() * self.s()
- self.e1ep() * operand.x() * self.e1ep()
- self.e1ep() * operand.y() * self.e2ep()
- self.e2em() * operand.em() * self.m()
+ self.e2em() * operand.ep() * self.ps()
- self.e2em() * operand.x() * self.e2em()
+ self.e2em() * operand.y() * self.e1em()
- self.e2ep() * operand.em() * self.ps()
+ self.e2ep() * operand.ep() * self.m()
+ self.e2ep() * operand.x() * self.e2ep()
- self.e2ep() * operand.y() * self.e1ep()
- self.epem() * operand.em() * self.e1ep()
+ self.epem() * operand.ep() * self.e1em()
- self.epem() * operand.x() * self.epem()
- self.epem() * operand.y() * self.ps()
- self.m() * operand.em() * self.e2em()
+ self.m() * operand.ep() * self.e2ep()
- self.m() * operand.x() * self.m()
+ self.m() * operand.y() * self.s()
- self.ps() * operand.em() * self.e2ep()
+ self.ps() * operand.ep() * self.e2em()
+ self.ps() * operand.x() * self.ps()
- self.ps() * operand.y() * self.epem()
- self.s() * operand.em() * self.e1em()
+ self.s() * operand.ep() * self.e1ep()
+ self.s() * operand.x() * self.s()
+ self.s() * operand.y() * self.m())
* inv_norm_sq,
(self.e1em() * operand.em() * self.m() - self.e1em() * operand.ep() * self.ps()
+ self.e1em() * operand.x() * self.e2em()
- self.e1em() * operand.y() * self.e1em()
+ self.e1ep() * operand.em() * self.ps()
- self.e1ep() * operand.ep() * self.m()
- self.e1ep() * operand.x() * self.e2ep()
+ self.e1ep() * operand.y() * self.e1ep()
- self.e2em() * operand.em() * self.s()
+ self.e2em() * operand.ep() * self.epem()
+ self.e2em() * operand.x() * self.e1em()
+ self.e2em() * operand.y() * self.e2em()
- self.e2ep() * operand.em() * self.epem()
+ self.e2ep() * operand.ep() * self.s()
- self.e2ep() * operand.x() * self.e1ep()
- self.e2ep() * operand.y() * self.e2ep()
- self.epem() * operand.em() * self.e2ep()
+ self.epem() * operand.ep() * self.e2em()
+ self.epem() * operand.x() * self.ps()
- self.epem() * operand.y() * self.epem()
+ self.m() * operand.em() * self.e1em()
- self.m() * operand.ep() * self.e1ep()
- self.m() * operand.x() * self.s()
- self.m() * operand.y() * self.m()
+ self.ps() * operand.em() * self.e1ep()
- self.ps() * operand.ep() * self.e1em()
+ self.ps() * operand.x() * self.epem()
+ self.ps() * operand.y() * self.ps()
- self.s() * operand.em() * self.e2em()
+ self.s() * operand.ep() * self.e2ep()
- self.s() * operand.x() * self.m()
+ self.s() * operand.y() * self.s())
* inv_norm_sq,
(self.e1em() * operand.em() * self.e1ep() - self.e1em() * operand.ep() * self.e1em()
+ self.e1em() * operand.x() * self.epem()
+ self.e1em() * operand.y() * self.ps()
+ self.e1ep() * operand.em() * self.e1em()
- self.e1ep() * operand.ep() * self.e1ep()
- self.e1ep() * operand.x() * self.s()
- self.e1ep() * operand.y() * self.m()
+ self.e2em() * operand.em() * self.e2ep()
- self.e2em() * operand.ep() * self.e2em()
- self.e2em() * operand.x() * self.ps()
+ self.e2em() * operand.y() * self.epem()
+ self.e2ep() * operand.em() * self.e2em()
- self.e2ep() * operand.ep() * self.e2ep()
+ self.e2ep() * operand.x() * self.m()
- self.e2ep() * operand.y() * self.s()
- self.epem() * operand.em() * self.s()
+ self.epem() * operand.ep() * self.epem()
+ self.epem() * operand.x() * self.e1em()
+ self.epem() * operand.y() * self.e2em()
- self.m() * operand.em() * self.ps()
+ self.m() * operand.ep() * self.m()
+ self.m() * operand.x() * self.e2ep()
- self.m() * operand.y() * self.e1ep()
- self.ps() * operand.em() * self.m()
+ self.ps() * operand.ep() * self.ps()
- self.ps() * operand.x() * self.e2em()
+ self.ps() * operand.y() * self.e1em()
- self.s() * operand.em() * self.epem()
+ self.s() * operand.ep() * self.s()
- self.s() * operand.x() * self.e1ep()
- self.s() * operand.y() * self.e2ep())
* inv_norm_sq,
(self.e1em() * operand.em() * self.e1em()
- self.e1em() * operand.ep() * self.e1ep()
- self.e1em() * operand.x() * self.s()
- self.e1em() * operand.y() * self.m()
+ self.e1ep() * operand.em() * self.e1ep()
- self.e1ep() * operand.ep() * self.e1em()
+ self.e1ep() * operand.x() * self.epem()
+ self.e1ep() * operand.y() * self.ps()
+ self.e2em() * operand.em() * self.e2em()
- self.e2em() * operand.ep() * self.e2ep()
+ self.e2em() * operand.x() * self.m()
- self.e2em() * operand.y() * self.s()
+ self.e2ep() * operand.em() * self.e2ep()
- self.e2ep() * operand.ep() * self.e2em()
- self.e2ep() * operand.x() * self.ps()
+ self.e2ep() * operand.y() * self.epem()
+ self.epem() * operand.em() * self.epem()
- self.epem() * operand.ep() * self.s()
+ self.epem() * operand.x() * self.e1ep()
+ self.epem() * operand.y() * self.e2ep()
+ self.m() * operand.em() * self.m()
- self.m() * operand.ep() * self.ps()
+ self.m() * operand.x() * self.e2em()
- self.m() * operand.y() * self.e1em()
+ self.ps() * operand.em() * self.ps()
- self.ps() * operand.ep() * self.m()
- self.ps() * operand.x() * self.e2ep()
+ self.ps() * operand.y() * self.e1ep()
+ self.s() * operand.em() * self.s()
- self.s() * operand.ep() * self.epem()
- self.s() * operand.x() * self.e1em()
- self.s() * operand.y() * self.e2em())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Scalar<T>> for Motor<T> {
type Output = Scalar<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Scalar<T>) -> Option<Scalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Scalar::new_unchecked(
(-(self.e1em() * operand.s() * self.e1em()) + self.e1ep() * operand.s() * self.e1ep()
- self.e2em() * operand.s() * self.e2em()
+ self.e2ep() * operand.s() * self.e2ep()
- self.epem() * operand.s() * self.epem()
+ self.m() * operand.s() * self.m()
- self.ps() * operand.s() * self.ps()
+ self.s() * operand.s() * self.s())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Circle<T>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Circle<T>) -> Option<Circle<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Circle::new_unchecked(
(-(self.e1em() * operand.e12em() * self.e1ep())
+ self.e1em() * operand.e1epem() * self.m()
+ self.e1em() * operand.w() * self.e1em()
- self.e1ep() * operand.e12em() * self.e1em()
+ self.e1ep() * operand.e2epem() * self.epem()
+ self.e1ep() * operand.w() * self.e1ep()
- self.e2em() * operand.e12em() * self.e2ep()
+ self.e2em() * operand.e2epem() * self.m()
+ self.e2em() * operand.w() * self.e2em()
- self.e2ep() * operand.e12em() * self.e2em()
- self.e2ep() * operand.e1epem() * self.epem()
+ self.e2ep() * operand.w() * self.e2ep()
- self.epem() * operand.e1epem() * self.e2ep()
+ self.epem() * operand.e2epem() * self.e1ep()
+ self.epem() * operand.w() * self.epem()
+ self.m() * operand.e1epem() * self.e1em()
+ self.m() * operand.e2epem() * self.e2em()
+ self.m() * operand.w() * self.m())
* inv_norm_sq,
(-(self.e1em() * operand.e12em() * self.e1em())
+ self.e1em() * operand.e2epem() * self.epem()
+ self.e1em() * operand.w() * self.e1ep()
- self.e1ep() * operand.e12em() * self.e1ep()
+ self.e1ep() * operand.e1epem() * self.m()
+ self.e1ep() * operand.w() * self.e1em()
- self.e2em() * operand.e12em() * self.e2em()
- self.e2em() * operand.e1epem() * self.epem()
+ self.e2em() * operand.w() * self.e2ep()
- self.e2ep() * operand.e12em() * self.e2ep()
+ self.e2ep() * operand.e2epem() * self.m()
+ self.e2ep() * operand.w() * self.e2em()
+ self.epem() * operand.e12em() * self.epem()
- self.epem() * operand.e1epem() * self.e2em()
+ self.epem() * operand.e2epem() * self.e1em()
+ self.m() * operand.e12em() * self.m()
+ self.m() * operand.e1epem() * self.e1ep()
+ self.m() * operand.e2epem() * self.e2ep())
* inv_norm_sq,
(-(self.e1em() * operand.e1epem() * self.e1em())
- self.e1em() * operand.e2epem() * self.e2em()
- self.e1em() * operand.w() * self.m()
+ self.e1ep() * operand.e12em() * self.m()
+ self.e1ep() * operand.e1epem() * self.e1ep()
+ self.e1ep() * operand.e2epem() * self.e2ep()
- self.e2em() * operand.e12em() * self.epem()
+ self.e2em() * operand.e1epem() * self.e2em()
- self.e2em() * operand.e2epem() * self.e1em()
- self.e2ep() * operand.e1epem() * self.e2ep()
+ self.e2ep() * operand.e2epem() * self.e1ep()
+ self.e2ep() * operand.w() * self.epem()
- self.epem() * operand.e12em() * self.e2em()
- self.epem() * operand.e1epem() * self.epem()
+ self.epem() * operand.w() * self.e2ep()
+ self.m() * operand.e12em() * self.e1ep()
- self.m() * operand.e1epem() * self.m()
- self.m() * operand.w() * self.e1em())
* inv_norm_sq,
(self.e1em() * operand.e12em() * self.epem()
- self.e1em() * operand.e1epem() * self.e2em()
+ self.e1em() * operand.e2epem() * self.e1em()
+ self.e1ep() * operand.e1epem() * self.e2ep()
- self.e1ep() * operand.e2epem() * self.e1ep()
- self.e1ep() * operand.w() * self.epem()
- self.e2em() * operand.e1epem() * self.e1em()
- self.e2em() * operand.e2epem() * self.e2em()
- self.e2em() * operand.w() * self.m()
+ self.e2ep() * operand.e12em() * self.m()
+ self.e2ep() * operand.e1epem() * self.e1ep()
+ self.e2ep() * operand.e2epem() * self.e2ep()
+ self.epem() * operand.e12em() * self.e1em()
- self.epem() * operand.e2epem() * self.epem()
- self.epem() * operand.w() * self.e1ep()
+ self.m() * operand.e12em() * self.e2ep()
- self.m() * operand.e2epem() * self.m()
- self.m() * operand.w() * self.e2em())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<FlatPoint<T>> for PointPair<T> {
type Output = FlatPoint<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &FlatPoint<T>) -> Option<FlatPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(FlatPoint::new_unchecked(
(-(self.e1em() * operand.e1em() * self.e1em())
- self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.epem() * self.epem()
- self.e1ep() * operand.e1em() * self.e1ep()
- self.e1ep() * operand.e2em() * self.e2ep()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e2em() * self.e1em()
+ self.e2ep() * operand.e1em() * self.e2ep()
- self.e2ep() * operand.e2em() * self.e1ep()
+ self.e2ep() * operand.epem() * self.m()
+ self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.epem() * self.e1em()
- self.m() * operand.e1em() * self.m()
+ self.m() * operand.epem() * self.e2ep())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e2em() * self.e1em()
- self.e1ep() * operand.e1em() * self.e2ep()
+ self.e1ep() * operand.e2em() * self.e1ep()
- self.e1ep() * operand.epem() * self.m()
- self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.epem() * self.epem()
- self.e2ep() * operand.e1em() * self.e1ep()
- self.e2ep() * operand.e2em() * self.e2ep()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.epem() * self.e2em()
- self.m() * operand.e2em() * self.m()
- self.m() * operand.epem() * self.e1ep())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.epem())
+ self.e1em() * operand.epem() * self.e1em()
- self.e1ep() * operand.e2em() * self.m()
- self.e1ep() * operand.epem() * self.e1ep()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.epem() * self.e2em()
+ self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.epem() * self.e2ep()
- self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.epem() * self.epem()
+ self.m() * operand.e1em() * self.e2ep()
- self.m() * operand.e2em() * self.e1ep()
+ self.m() * operand.epem() * self.m())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Line<T>> for PointPair<T> {
type Output = Line<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Line<T>) -> Option<Line<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Line::new_unchecked(
(self.e1em() * operand.d() * self.epem()
- self.e1em() * operand.nx() * self.e1em()
- self.e1ep() * operand.nx() * self.e1ep()
+ self.e1ep() * operand.ny() * self.m()
- self.e2em() * operand.nx() * self.e2em()
- self.e2em() * operand.ny() * self.epem()
+ self.e2ep() * operand.d() * self.m()
- self.e2ep() * operand.nx() * self.e2ep()
+ self.epem() * operand.d() * self.e1em()
+ self.epem() * operand.nx() * self.epem()
- self.epem() * operand.ny() * self.e2em()
+ self.m() * operand.d() * self.e2ep()
+ self.m() * operand.nx() * self.m()
+ self.m() * operand.ny() * self.e1ep())
* inv_norm_sq,
(-(self.e1em() * operand.d() * self.e2em()) - self.e1em() * operand.ny() * self.e1em()
+ self.e1ep() * operand.d() * self.e2ep()
+ self.e1ep() * operand.nx() * self.m()
+ self.e1ep() * operand.ny() * self.e1ep()
- self.e2em() * operand.d() * self.e1em()
- self.e2em() * operand.nx() * self.epem()
+ self.e2em() * operand.ny() * self.e2em()
+ self.e2ep() * operand.d() * self.e1ep()
- self.e2ep() * operand.ny() * self.e2ep()
- self.epem() * operand.nx() * self.e2em()
- self.epem() * operand.ny() * self.epem()
+ self.m() * operand.nx() * self.e1ep()
- self.m() * operand.ny() * self.m())
* inv_norm_sq,
(self.e1em() * operand.d() * self.e1em() + self.e1em() * operand.nx() * self.epem()
- self.e1em() * operand.ny() * self.e2em()
- self.e1ep() * operand.d() * self.e1ep()
+ self.e1ep() * operand.ny() * self.e2ep()
- self.e2em() * operand.d() * self.e2em()
- self.e2em() * operand.ny() * self.e1em()
+ self.e2ep() * operand.d() * self.e2ep()
+ self.e2ep() * operand.nx() * self.m()
+ self.e2ep() * operand.ny() * self.e1ep()
- self.epem() * operand.d() * self.epem()
+ self.epem() * operand.nx() * self.e1em()
- self.m() * operand.d() * self.m()
+ self.m() * operand.nx() * self.e2ep())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Motor<T>> for PointPair<T> {
type Output = Motor<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Motor<T>) -> Option<Motor<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Motor::new_unchecked(
(-(self.e1em() * operand.e1ep() * self.epem())
+ self.e1em() * operand.e2em() * self.m()
+ self.e1em() * operand.epem() * self.e1ep()
- self.e1em() * operand.m() * self.e2em()
+ self.e1em() * operand.ps() * self.e2ep()
- self.e1em() * operand.s() * self.e1em()
+ self.e1ep() * operand.e1em() * self.epem()
- self.e1ep() * operand.e2ep() * self.m()
- self.e1ep() * operand.epem() * self.e1em()
+ self.e1ep() * operand.m() * self.e2ep()
- self.e1ep() * operand.ps() * self.e2em()
+ self.e1ep() * operand.s() * self.e1ep()
- self.e2em() * operand.e1em() * self.m()
- self.e2em() * operand.e2ep() * self.epem()
+ self.e2em() * operand.epem() * self.e2ep()
+ self.e2em() * operand.m() * self.e1em()
- self.e2em() * operand.ps() * self.e1ep()
- self.e2em() * operand.s() * self.e2em()
+ self.e2ep() * operand.e1ep() * self.m()
+ self.e2ep() * operand.e2em() * self.epem()
- self.e2ep() * operand.epem() * self.e2em()
- self.e2ep() * operand.m() * self.e1ep()
+ self.e2ep() * operand.ps() * self.e1em()
+ self.e2ep() * operand.s() * self.e2ep()
- self.epem() * operand.e1em() * self.e1ep()
+ self.epem() * operand.e1ep() * self.e1em()
- self.epem() * operand.e2em() * self.e2ep()
+ self.epem() * operand.e2ep() * self.e2em()
+ self.epem() * operand.ps() * self.m()
- self.epem() * operand.s() * self.epem()
+ self.m() * operand.e1em() * self.e2em()
- self.m() * operand.e1ep() * self.e2ep()
- self.m() * operand.e2em() * self.e1em()
+ self.m() * operand.e2ep() * self.e1ep()
+ self.m() * operand.ps() * self.epem()
+ self.m() * operand.s() * self.m())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.m())
- self.e1em() * operand.e2ep() * self.epem()
+ self.e1em() * operand.epem() * self.e2ep()
+ self.e1em() * operand.m() * self.e1em()
- self.e1em() * operand.ps() * self.e1ep()
- self.e1em() * operand.s() * self.e2em()
+ self.e1ep() * operand.e1ep() * self.m()
+ self.e1ep() * operand.e2em() * self.epem()
- self.e1ep() * operand.epem() * self.e2em()
- self.e1ep() * operand.m() * self.e1ep()
+ self.e1ep() * operand.ps() * self.e1em()
+ self.e1ep() * operand.s() * self.e2ep()
+ self.e2em() * operand.e1ep() * self.epem()
- self.e2em() * operand.e2em() * self.m()
- self.e2em() * operand.epem() * self.e1ep()
+ self.e2em() * operand.m() * self.e2em()
- self.e2em() * operand.ps() * self.e2ep()
+ self.e2em() * operand.s() * self.e1em()
- self.e2ep() * operand.e1em() * self.epem()
+ self.e2ep() * operand.e2ep() * self.m()
+ self.e2ep() * operand.epem() * self.e1em()
- self.e2ep() * operand.m() * self.e2ep()
+ self.e2ep() * operand.ps() * self.e2em()
- self.e2ep() * operand.s() * self.e1ep()
- self.epem() * operand.e1em() * self.e2ep()
+ self.epem() * operand.e1ep() * self.e2em()
+ self.epem() * operand.e2em() * self.e1ep()
- self.epem() * operand.e2ep() * self.e1em()
- self.epem() * operand.epem() * self.m()
- self.epem() * operand.m() * self.epem()
- self.m() * operand.e1em() * self.e1em()
+ self.m() * operand.e1ep() * self.e1ep()
- self.m() * operand.e2em() * self.e2em()
+ self.m() * operand.e2ep() * self.e2ep()
- self.m() * operand.epem() * self.epem()
+ self.m() * operand.m() * self.m())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e1ep())
+ self.e1em() * operand.e1ep() * self.e1em()
- self.e1em() * operand.e2em() * self.e2ep()
+ self.e1em() * operand.e2ep() * self.e2em()
+ self.e1em() * operand.ps() * self.m()
- self.e1em() * operand.s() * self.epem()
- self.e1ep() * operand.e1em() * self.e1em()
+ self.e1ep() * operand.e1ep() * self.e1ep()
- self.e1ep() * operand.e2em() * self.e2em()
+ self.e1ep() * operand.e2ep() * self.e2ep()
- self.e1ep() * operand.epem() * self.epem()
+ self.e1ep() * operand.m() * self.m()
+ self.e2em() * operand.e1em() * self.e2ep()
- self.e2em() * operand.e1ep() * self.e2em()
- self.e2em() * operand.e2em() * self.e1ep()
+ self.e2em() * operand.e2ep() * self.e1em()
+ self.e2em() * operand.epem() * self.m()
+ self.e2em() * operand.m() * self.epem()
+ self.e2ep() * operand.e1em() * self.e2em()
- self.e2ep() * operand.e1ep() * self.e2ep()
- self.e2ep() * operand.e2em() * self.e1em()
+ self.e2ep() * operand.e2ep() * self.e1ep()
+ self.e2ep() * operand.ps() * self.epem()
+ self.e2ep() * operand.s() * self.m()
+ self.epem() * operand.e1ep() * self.epem()
- self.epem() * operand.e2em() * self.m()
- self.epem() * operand.epem() * self.e1ep()
+ self.epem() * operand.m() * self.e2em()
- self.epem() * operand.ps() * self.e2ep()
+ self.epem() * operand.s() * self.e1em()
- self.m() * operand.e1ep() * self.m()
- self.m() * operand.e2em() * self.epem()
+ self.m() * operand.epem() * self.e2em()
+ self.m() * operand.m() * self.e1ep()
- self.m() * operand.ps() * self.e1em()
- self.m() * operand.s() * self.e2ep())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e2ep())
+ self.e1em() * operand.e1ep() * self.e2em()
+ self.e1em() * operand.e2em() * self.e1ep()
- self.e1em() * operand.e2ep() * self.e1em()
- self.e1em() * operand.epem() * self.m()
- self.e1em() * operand.m() * self.epem()
- self.e1ep() * operand.e1em() * self.e2em()
+ self.e1ep() * operand.e1ep() * self.e2ep()
+ self.e1ep() * operand.e2em() * self.e1em()
- self.e1ep() * operand.e2ep() * self.e1ep()
- self.e1ep() * operand.ps() * self.epem()
- self.e1ep() * operand.s() * self.m()
- self.e2em() * operand.e1em() * self.e1ep()
+ self.e2em() * operand.e1ep() * self.e1em()
- self.e2em() * operand.e2em() * self.e2ep()
+ self.e2em() * operand.e2ep() * self.e2em()
+ self.e2em() * operand.ps() * self.m()
- self.e2em() * operand.s() * self.epem()
- self.e2ep() * operand.e1em() * self.e1em()
+ self.e2ep() * operand.e1ep() * self.e1ep()
- self.e2ep() * operand.e2em() * self.e2em()
+ self.e2ep() * operand.e2ep() * self.e2ep()
- self.e2ep() * operand.epem() * self.epem()
+ self.e2ep() * operand.m() * self.m()
+ self.epem() * operand.e1em() * self.m()
+ self.epem() * operand.e2ep() * self.epem()
- self.epem() * operand.epem() * self.e2ep()
- self.epem() * operand.m() * self.e1em()
+ self.epem() * operand.ps() * self.e1ep()
+ self.epem() * operand.s() * self.e2em()
+ self.m() * operand.e1em() * self.epem()
- self.m() * operand.e2ep() * self.m()
- self.m() * operand.epem() * self.e1em()
+ self.m() * operand.m() * self.e2ep()
- self.m() * operand.ps() * self.e2em()
+ self.m() * operand.s() * self.e1ep())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e1em())
+ self.e1em() * operand.e1ep() * self.e1ep()
- self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.e2ep() * self.e2ep()
- self.e1em() * operand.epem() * self.epem()
+ self.e1em() * operand.m() * self.m()
- self.e1ep() * operand.e1em() * self.e1ep()
+ self.e1ep() * operand.e1ep() * self.e1em()
- self.e1ep() * operand.e2em() * self.e2ep()
+ self.e1ep() * operand.e2ep() * self.e2em()
+ self.e1ep() * operand.ps() * self.m()
- self.e1ep() * operand.s() * self.epem()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e1ep() * self.e2ep()
- self.e2em() * operand.e2em() * self.e1em()
+ self.e2em() * operand.e2ep() * self.e1ep()
+ self.e2em() * operand.ps() * self.epem()
+ self.e2em() * operand.s() * self.m()
+ self.e2ep() * operand.e1em() * self.e2ep()
- self.e2ep() * operand.e1ep() * self.e2em()
- self.e2ep() * operand.e2em() * self.e1ep()
+ self.e2ep() * operand.e2ep() * self.e1em()
+ self.e2ep() * operand.epem() * self.m()
+ self.e2ep() * operand.m() * self.epem()
+ self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.e2ep() * self.m()
- self.epem() * operand.epem() * self.e1em()
+ self.epem() * operand.m() * self.e2ep()
- self.epem() * operand.ps() * self.e2em()
+ self.epem() * operand.s() * self.e1ep()
- self.m() * operand.e1em() * self.m()
- self.m() * operand.e2ep() * self.epem()
+ self.m() * operand.epem() * self.e2ep()
+ self.m() * operand.m() * self.e1em()
- self.m() * operand.ps() * self.e1ep()
- self.m() * operand.s() * self.e2em())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e1ep() * self.e2ep()
+ self.e1em() * operand.e2em() * self.e1em()
- self.e1em() * operand.e2ep() * self.e1ep()
- self.e1em() * operand.ps() * self.epem()
- self.e1em() * operand.s() * self.m()
- self.e1ep() * operand.e1em() * self.e2ep()
+ self.e1ep() * operand.e1ep() * self.e2em()
+ self.e1ep() * operand.e2em() * self.e1ep()
- self.e1ep() * operand.e2ep() * self.e1em()
- self.e1ep() * operand.epem() * self.m()
- self.e1ep() * operand.m() * self.epem()
- self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e1ep() * self.e1ep()
- self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.e2ep() * self.e2ep()
- self.e2em() * operand.epem() * self.epem()
+ self.e2em() * operand.m() * self.m()
- self.e2ep() * operand.e1em() * self.e1ep()
+ self.e2ep() * operand.e1ep() * self.e1em()
- self.e2ep() * operand.e2em() * self.e2ep()
+ self.e2ep() * operand.e2ep() * self.e2em()
+ self.e2ep() * operand.ps() * self.m()
- self.e2ep() * operand.s() * self.epem()
+ self.epem() * operand.e1ep() * self.m()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.epem() * self.e2em()
- self.epem() * operand.m() * self.e1ep()
+ self.epem() * operand.ps() * self.e1em()
+ self.epem() * operand.s() * self.e2ep()
+ self.m() * operand.e1ep() * self.epem()
- self.m() * operand.e2em() * self.m()
- self.m() * operand.epem() * self.e1ep()
+ self.m() * operand.m() * self.e2em()
- self.m() * operand.ps() * self.e2ep()
+ self.m() * operand.s() * self.e1em())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.epem())
+ self.e1em() * operand.e2ep() * self.m()
+ self.e1em() * operand.epem() * self.e1em()
- self.e1em() * operand.m() * self.e2ep()
+ self.e1em() * operand.ps() * self.e2em()
- self.e1em() * operand.s() * self.e1ep()
+ self.e1ep() * operand.e1ep() * self.epem()
- self.e1ep() * operand.e2em() * self.m()
- self.e1ep() * operand.epem() * self.e1ep()
+ self.e1ep() * operand.m() * self.e2em()
- self.e1ep() * operand.ps() * self.e2ep()
+ self.e1ep() * operand.s() * self.e1em()
- self.e2em() * operand.e1ep() * self.m()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.epem() * self.e2em()
+ self.e2em() * operand.m() * self.e1ep()
- self.e2em() * operand.ps() * self.e1em()
- self.e2em() * operand.s() * self.e2ep()
+ self.e2ep() * operand.e1em() * self.m()
+ self.e2ep() * operand.e2ep() * self.epem()
- self.e2ep() * operand.epem() * self.e2ep()
- self.e2ep() * operand.m() * self.e1em()
+ self.e2ep() * operand.ps() * self.e1ep()
+ self.e2ep() * operand.s() * self.e2em()
- self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e1ep() * self.e1ep()
- self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.e2ep() * self.e2ep()
- self.epem() * operand.epem() * self.epem()
+ self.epem() * operand.m() * self.m()
+ self.m() * operand.e1em() * self.e2ep()
- self.m() * operand.e1ep() * self.e2em()
- self.m() * operand.e2em() * self.e1ep()
+ self.m() * operand.e2ep() * self.e1em()
+ self.m() * operand.epem() * self.m()
+ self.m() * operand.m() * self.epem())
* inv_norm_sq,
(-(self.e1em() * operand.e1ep() * self.m())
- self.e1em() * operand.e2em() * self.epem()
+ self.e1em() * operand.epem() * self.e2em()
+ self.e1em() * operand.m() * self.e1ep()
- self.e1em() * operand.ps() * self.e1em()
- self.e1em() * operand.s() * self.e2ep()
+ self.e1ep() * operand.e1em() * self.m()
+ self.e1ep() * operand.e2ep() * self.epem()
- self.e1ep() * operand.epem() * self.e2ep()
- self.e1ep() * operand.m() * self.e1em()
+ self.e1ep() * operand.ps() * self.e1ep()
+ self.e1ep() * operand.s() * self.e2em()
+ self.e2em() * operand.e1em() * self.epem()
- self.e2em() * operand.e2ep() * self.m()
- self.e2em() * operand.epem() * self.e1em()
+ self.e2em() * operand.m() * self.e2ep()
- self.e2em() * operand.ps() * self.e2em()
+ self.e2em() * operand.s() * self.e1ep()
- self.e2ep() * operand.e1ep() * self.epem()
+ self.e2ep() * operand.e2em() * self.m()
+ self.e2ep() * operand.epem() * self.e1ep()
- self.e2ep() * operand.m() * self.e2em()
+ self.e2ep() * operand.ps() * self.e2ep()
- self.e2ep() * operand.s() * self.e1em()
- self.epem() * operand.e1em() * self.e2em()
+ self.epem() * operand.e1ep() * self.e2ep()
+ self.epem() * operand.e2em() * self.e1em()
- self.epem() * operand.e2ep() * self.e1ep()
- self.epem() * operand.ps() * self.epem()
- self.epem() * operand.s() * self.m()
- self.m() * operand.e1em() * self.e1ep()
+ self.m() * operand.e1ep() * self.e1em()
- self.m() * operand.e2em() * self.e2ep()
+ self.m() * operand.e2ep() * self.e2em()
+ self.m() * operand.ps() * self.m()
- self.m() * operand.s() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<PointPair<T>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &PointPair<T>) -> Option<PointPair<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(PointPair::new_unchecked(
(-(self.e1em() * operand.e1em() * self.m())
- self.e1em() * operand.e2ep() * self.epem()
+ self.e1em() * operand.epem() * self.e2ep()
+ self.e1em() * operand.m() * self.e1em()
+ self.e1ep() * operand.e1ep() * self.m()
+ self.e1ep() * operand.e2em() * self.epem()
- self.e1ep() * operand.epem() * self.e2em()
- self.e1ep() * operand.m() * self.e1ep()
+ self.e2em() * operand.e1ep() * self.epem()
- self.e2em() * operand.e2em() * self.m()
- self.e2em() * operand.epem() * self.e1ep()
+ self.e2em() * operand.m() * self.e2em()
- self.e2ep() * operand.e1em() * self.epem()
+ self.e2ep() * operand.e2ep() * self.m()
+ self.e2ep() * operand.epem() * self.e1em()
- self.e2ep() * operand.m() * self.e2ep()
- self.epem() * operand.e1em() * self.e2ep()
+ self.epem() * operand.e1ep() * self.e2em()
+ self.epem() * operand.e2em() * self.e1ep()
- self.epem() * operand.e2ep() * self.e1em()
- self.epem() * operand.epem() * self.m()
- self.epem() * operand.m() * self.epem()
- self.m() * operand.e1em() * self.e1em()
+ self.m() * operand.e1ep() * self.e1ep()
- self.m() * operand.e2em() * self.e2em()
+ self.m() * operand.e2ep() * self.e2ep()
- self.m() * operand.epem() * self.epem()
+ self.m() * operand.m() * self.m())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e1ep())
+ self.e1em() * operand.e1ep() * self.e1em()
- self.e1em() * operand.e2em() * self.e2ep()
+ self.e1em() * operand.e2ep() * self.e2em()
- self.e1ep() * operand.e1em() * self.e1em()
+ self.e1ep() * operand.e1ep() * self.e1ep()
- self.e1ep() * operand.e2em() * self.e2em()
+ self.e1ep() * operand.e2ep() * self.e2ep()
- self.e1ep() * operand.epem() * self.epem()
+ self.e1ep() * operand.m() * self.m()
+ self.e2em() * operand.e1em() * self.e2ep()
- self.e2em() * operand.e1ep() * self.e2em()
- self.e2em() * operand.e2em() * self.e1ep()
+ self.e2em() * operand.e2ep() * self.e1em()
+ self.e2em() * operand.epem() * self.m()
+ self.e2em() * operand.m() * self.epem()
+ self.e2ep() * operand.e1em() * self.e2em()
- self.e2ep() * operand.e1ep() * self.e2ep()
- self.e2ep() * operand.e2em() * self.e1em()
+ self.e2ep() * operand.e2ep() * self.e1ep()
+ self.epem() * operand.e1ep() * self.epem()
- self.epem() * operand.e2em() * self.m()
- self.epem() * operand.epem() * self.e1ep()
+ self.epem() * operand.m() * self.e2em()
- self.m() * operand.e1ep() * self.m()
- self.m() * operand.e2em() * self.epem()
+ self.m() * operand.epem() * self.e2em()
+ self.m() * operand.m() * self.e1ep())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e2ep())
+ self.e1em() * operand.e1ep() * self.e2em()
+ self.e1em() * operand.e2em() * self.e1ep()
- self.e1em() * operand.e2ep() * self.e1em()
- self.e1em() * operand.epem() * self.m()
- self.e1em() * operand.m() * self.epem()
- self.e1ep() * operand.e1em() * self.e2em()
+ self.e1ep() * operand.e1ep() * self.e2ep()
+ self.e1ep() * operand.e2em() * self.e1em()
- self.e1ep() * operand.e2ep() * self.e1ep()
- self.e2em() * operand.e1em() * self.e1ep()
+ self.e2em() * operand.e1ep() * self.e1em()
- self.e2em() * operand.e2em() * self.e2ep()
+ self.e2em() * operand.e2ep() * self.e2em()
- self.e2ep() * operand.e1em() * self.e1em()
+ self.e2ep() * operand.e1ep() * self.e1ep()
- self.e2ep() * operand.e2em() * self.e2em()
+ self.e2ep() * operand.e2ep() * self.e2ep()
- self.e2ep() * operand.epem() * self.epem()
+ self.e2ep() * operand.m() * self.m()
+ self.epem() * operand.e1em() * self.m()
+ self.epem() * operand.e2ep() * self.epem()
- self.epem() * operand.epem() * self.e2ep()
- self.epem() * operand.m() * self.e1em()
+ self.m() * operand.e1em() * self.epem()
- self.m() * operand.e2ep() * self.m()
- self.m() * operand.epem() * self.e1em()
+ self.m() * operand.m() * self.e2ep())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e1em())
+ self.e1em() * operand.e1ep() * self.e1ep()
- self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.e2ep() * self.e2ep()
- self.e1em() * operand.epem() * self.epem()
+ self.e1em() * operand.m() * self.m()
- self.e1ep() * operand.e1em() * self.e1ep()
+ self.e1ep() * operand.e1ep() * self.e1em()
- self.e1ep() * operand.e2em() * self.e2ep()
+ self.e1ep() * operand.e2ep() * self.e2em()
+ self.e2em() * operand.e1em() * self.e2em()
- self.e2em() * operand.e1ep() * self.e2ep()
- self.e2em() * operand.e2em() * self.e1em()
+ self.e2em() * operand.e2ep() * self.e1ep()
+ self.e2ep() * operand.e1em() * self.e2ep()
- self.e2ep() * operand.e1ep() * self.e2em()
- self.e2ep() * operand.e2em() * self.e1ep()
+ self.e2ep() * operand.e2ep() * self.e1em()
+ self.e2ep() * operand.epem() * self.m()
+ self.e2ep() * operand.m() * self.epem()
+ self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.e2ep() * self.m()
- self.epem() * operand.epem() * self.e1em()
+ self.epem() * operand.m() * self.e2ep()
- self.m() * operand.e1em() * self.m()
- self.m() * operand.e2ep() * self.epem()
+ self.m() * operand.epem() * self.e2ep()
+ self.m() * operand.m() * self.e1em())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.e2em())
+ self.e1em() * operand.e1ep() * self.e2ep()
+ self.e1em() * operand.e2em() * self.e1em()
- self.e1em() * operand.e2ep() * self.e1ep()
- self.e1ep() * operand.e1em() * self.e2ep()
+ self.e1ep() * operand.e1ep() * self.e2em()
+ self.e1ep() * operand.e2em() * self.e1ep()
- self.e1ep() * operand.e2ep() * self.e1em()
- self.e1ep() * operand.epem() * self.m()
- self.e1ep() * operand.m() * self.epem()
- self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e1ep() * self.e1ep()
- self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.e2ep() * self.e2ep()
- self.e2em() * operand.epem() * self.epem()
+ self.e2em() * operand.m() * self.m()
- self.e2ep() * operand.e1em() * self.e1ep()
+ self.e2ep() * operand.e1ep() * self.e1em()
- self.e2ep() * operand.e2em() * self.e2ep()
+ self.e2ep() * operand.e2ep() * self.e2em()
+ self.epem() * operand.e1ep() * self.m()
+ self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.epem() * self.e2em()
- self.epem() * operand.m() * self.e1ep()
+ self.m() * operand.e1ep() * self.epem()
- self.m() * operand.e2em() * self.m()
- self.m() * operand.epem() * self.e1ep()
+ self.m() * operand.m() * self.e2em())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.epem())
+ self.e1em() * operand.e2ep() * self.m()
+ self.e1em() * operand.epem() * self.e1em()
- self.e1em() * operand.m() * self.e2ep()
+ self.e1ep() * operand.e1ep() * self.epem()
- self.e1ep() * operand.e2em() * self.m()
- self.e1ep() * operand.epem() * self.e1ep()
+ self.e1ep() * operand.m() * self.e2em()
- self.e2em() * operand.e1ep() * self.m()
- self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.epem() * self.e2em()
+ self.e2em() * operand.m() * self.e1ep()
+ self.e2ep() * operand.e1em() * self.m()
+ self.e2ep() * operand.e2ep() * self.epem()
- self.e2ep() * operand.epem() * self.e2ep()
- self.e2ep() * operand.m() * self.e1em()
- self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e1ep() * self.e1ep()
- self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.e2ep() * self.e2ep()
- self.epem() * operand.epem() * self.epem()
+ self.epem() * operand.m() * self.m()
+ self.m() * operand.e1em() * self.e2ep()
- self.m() * operand.e1ep() * self.e2em()
- self.m() * operand.e2em() * self.e1ep()
+ self.m() * operand.e2ep() * self.e1em()
+ self.m() * operand.epem() * self.m()
+ self.m() * operand.m() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Pseudoscalar<T>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Pseudoscalar<T>) -> Option<Pseudoscalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Pseudoscalar::new_unchecked(
(-(self.e1em() * operand.ps() * self.e1em())
+ self.e1ep() * operand.ps() * self.e1ep()
- self.e2em() * operand.ps() * self.e2em()
+ self.e2ep() * operand.ps() * self.e2ep()
- self.epem() * operand.ps() * self.epem()
+ self.m() * operand.ps() * self.m())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<RoundPoint<T>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &RoundPoint<T>) -> Option<RoundPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(RoundPoint::new_unchecked(
(self.e1em() * operand.ep() * self.epem()
+ self.e1em() * operand.x() * self.e1em()
+ self.e1em() * operand.y() * self.e2em()
- self.e1ep() * operand.em() * self.epem()
- self.e1ep() * operand.x() * self.e1ep()
- self.e1ep() * operand.y() * self.e2ep()
- self.e2em() * operand.em() * self.m()
- self.e2em() * operand.x() * self.e2em()
+ self.e2em() * operand.y() * self.e1em()
+ self.e2ep() * operand.ep() * self.m()
+ self.e2ep() * operand.x() * self.e2ep()
- self.e2ep() * operand.y() * self.e1ep()
- self.epem() * operand.em() * self.e1ep()
+ self.epem() * operand.ep() * self.e1em()
- self.epem() * operand.x() * self.epem()
- self.m() * operand.em() * self.e2em()
+ self.m() * operand.ep() * self.e2ep()
- self.m() * operand.x() * self.m())
* inv_norm_sq,
(self.e1em() * operand.em() * self.m() + self.e1em() * operand.x() * self.e2em()
- self.e1em() * operand.y() * self.e1em()
- self.e1ep() * operand.ep() * self.m()
- self.e1ep() * operand.x() * self.e2ep()
+ self.e1ep() * operand.y() * self.e1ep()
+ self.e2em() * operand.ep() * self.epem()
+ self.e2em() * operand.x() * self.e1em()
+ self.e2em() * operand.y() * self.e2em()
- self.e2ep() * operand.em() * self.epem()
- self.e2ep() * operand.x() * self.e1ep()
- self.e2ep() * operand.y() * self.e2ep()
- self.epem() * operand.em() * self.e2ep()
+ self.epem() * operand.ep() * self.e2em()
- self.epem() * operand.y() * self.epem()
+ self.m() * operand.em() * self.e1em()
- self.m() * operand.ep() * self.e1ep()
- self.m() * operand.y() * self.m())
* inv_norm_sq,
(self.e1em() * operand.em() * self.e1ep() - self.e1em() * operand.ep() * self.e1em()
+ self.e1em() * operand.x() * self.epem()
+ self.e1ep() * operand.em() * self.e1em()
- self.e1ep() * operand.ep() * self.e1ep()
- self.e1ep() * operand.y() * self.m()
+ self.e2em() * operand.em() * self.e2ep()
- self.e2em() * operand.ep() * self.e2em()
+ self.e2em() * operand.y() * self.epem()
+ self.e2ep() * operand.em() * self.e2em()
- self.e2ep() * operand.ep() * self.e2ep()
+ self.e2ep() * operand.x() * self.m()
+ self.epem() * operand.ep() * self.epem()
+ self.epem() * operand.x() * self.e1em()
+ self.epem() * operand.y() * self.e2em()
+ self.m() * operand.ep() * self.m()
+ self.m() * operand.x() * self.e2ep()
- self.m() * operand.y() * self.e1ep())
* inv_norm_sq,
(self.e1em() * operand.em() * self.e1em()
- self.e1em() * operand.ep() * self.e1ep()
- self.e1em() * operand.y() * self.m()
+ self.e1ep() * operand.em() * self.e1ep()
- self.e1ep() * operand.ep() * self.e1em()
+ self.e1ep() * operand.x() * self.epem()
+ self.e2em() * operand.em() * self.e2em()
- self.e2em() * operand.ep() * self.e2ep()
+ self.e2em() * operand.x() * self.m()
+ self.e2ep() * operand.em() * self.e2ep()
- self.e2ep() * operand.ep() * self.e2em()
+ self.e2ep() * operand.y() * self.epem()
+ self.epem() * operand.em() * self.epem()
+ self.epem() * operand.x() * self.e1ep()
+ self.epem() * operand.y() * self.e2ep()
+ self.m() * operand.em() * self.m()
+ self.m() * operand.x() * self.e2em()
- self.m() * operand.y() * self.e1em())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Scalar<T>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Scalar<T>) -> Option<Scalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Scalar::new_unchecked(
(-(self.e1em() * operand.s() * self.e1em()) + self.e1ep() * operand.s() * self.e1ep()
- self.e2em() * operand.s() * self.e2em()
+ self.e2ep() * operand.s() * self.e2ep()
- self.epem() * operand.s() * self.epem()
+ self.m() * operand.s() * self.m())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Circle<T>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Circle<T>) -> Option<Circle<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Circle::new_unchecked(
(self.ps() * operand.w() * self.ps()) * inv_norm_sq,
(self.ps() * operand.e12em() * self.ps()) * inv_norm_sq,
(self.ps() * operand.e1epem() * self.ps()) * inv_norm_sq,
(self.ps() * operand.e2epem() * self.ps()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<FlatPoint<T>> for Pseudoscalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &FlatPoint<T>) -> Option<FlatPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(FlatPoint::new_unchecked(
(-(self.ps() * operand.e1em() * self.ps())) * inv_norm_sq,
(-(self.ps() * operand.e2em() * self.ps())) * inv_norm_sq,
(-(self.ps() * operand.epem() * self.ps())) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Line<T>> for Pseudoscalar<T> {
type Output = Line<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Line<T>) -> Option<Line<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Line::new_unchecked(
(self.ps() * operand.nx() * self.ps()) * inv_norm_sq,
(self.ps() * operand.ny() * self.ps()) * inv_norm_sq,
(self.ps() * operand.d() * self.ps()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Motor<T>> for Pseudoscalar<T> {
type Output = Motor<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Motor<T>) -> Option<Motor<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Motor::new_unchecked(
(-(self.ps() * operand.s() * self.ps())) * inv_norm_sq,
(-(self.ps() * operand.m() * self.ps())) * inv_norm_sq,
(-(self.ps() * operand.e1ep() * self.ps())) * inv_norm_sq,
(-(self.ps() * operand.e2ep() * self.ps())) * inv_norm_sq,
(-(self.ps() * operand.e1em() * self.ps())) * inv_norm_sq,
(-(self.ps() * operand.e2em() * self.ps())) * inv_norm_sq,
(-(self.ps() * operand.epem() * self.ps())) * inv_norm_sq,
(-(self.ps() * operand.ps() * self.ps())) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<PointPair<T>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &PointPair<T>) -> Option<PointPair<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(PointPair::new_unchecked(
(-(self.ps() * operand.m() * self.ps())) * inv_norm_sq,
(-(self.ps() * operand.e1ep() * self.ps())) * inv_norm_sq,
(-(self.ps() * operand.e2ep() * self.ps())) * inv_norm_sq,
(-(self.ps() * operand.e1em() * self.ps())) * inv_norm_sq,
(-(self.ps() * operand.e2em() * self.ps())) * inv_norm_sq,
(-(self.ps() * operand.epem() * self.ps())) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Pseudoscalar<T>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Pseudoscalar<T>) -> Option<Pseudoscalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Pseudoscalar::new_unchecked(
(-(self.ps() * operand.ps() * self.ps())) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<RoundPoint<T>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &RoundPoint<T>) -> Option<RoundPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(RoundPoint::new_unchecked(
(self.ps() * operand.x() * self.ps()) * inv_norm_sq,
(self.ps() * operand.y() * self.ps()) * inv_norm_sq,
(self.ps() * operand.ep() * self.ps()) * inv_norm_sq,
(self.ps() * operand.em() * self.ps()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Scalar<T>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Scalar<T>) -> Option<Scalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Scalar::new_unchecked(
(-(self.ps() * operand.s() * self.ps())) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Circle<T>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Circle<T>) -> Option<Circle<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Circle::new_unchecked(
(-(self.em() * operand.e12em() * self.ep()) + self.em() * operand.e1epem() * self.y()
- self.em() * operand.e2epem() * self.x()
+ self.em() * operand.w() * self.em()
- self.ep() * operand.e12em() * self.em()
+ self.ep() * operand.w() * self.ep()
- self.x() * operand.e2epem() * self.em()
+ self.x() * operand.w() * self.x()
+ self.y() * operand.e1epem() * self.em()
+ self.y() * operand.w() * self.y())
* inv_norm_sq,
(-(self.em() * operand.e12em() * self.em()) + self.em() * operand.w() * self.ep()
- self.ep() * operand.e12em() * self.ep()
+ self.ep() * operand.e1epem() * self.y()
- self.ep() * operand.e2epem() * self.x()
+ self.ep() * operand.w() * self.em()
+ self.x() * operand.e12em() * self.x()
- self.x() * operand.e2epem() * self.ep()
+ self.y() * operand.e12em() * self.y()
+ self.y() * operand.e1epem() * self.ep())
* inv_norm_sq,
(-(self.em() * operand.e1epem() * self.em()) - self.em() * operand.w() * self.y()
+ self.ep() * operand.e12em() * self.y()
+ self.ep() * operand.e1epem() * self.ep()
+ self.x() * operand.e1epem() * self.x()
+ self.x() * operand.e2epem() * self.y()
+ self.y() * operand.e12em() * self.ep()
- self.y() * operand.e1epem() * self.y()
+ self.y() * operand.e2epem() * self.x()
- self.y() * operand.w() * self.em())
* inv_norm_sq,
(-(self.em() * operand.e2epem() * self.em()) + self.em() * operand.w() * self.x()
- self.ep() * operand.e12em() * self.x()
+ self.ep() * operand.e2epem() * self.ep()
- self.x() * operand.e12em() * self.ep()
+ self.x() * operand.e1epem() * self.y()
- self.x() * operand.e2epem() * self.x()
+ self.x() * operand.w() * self.em()
+ self.y() * operand.e1epem() * self.x()
+ self.y() * operand.e2epem() * self.y())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<FlatPoint<T>> for RoundPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &FlatPoint<T>) -> Option<FlatPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(FlatPoint::new_unchecked(
(self.em() * operand.e1em() * self.em() + self.ep() * operand.e1em() * self.ep()
- self.ep() * operand.epem() * self.x()
- self.x() * operand.e1em() * self.x()
- self.x() * operand.e2em() * self.y()
- self.x() * operand.epem() * self.ep()
+ self.y() * operand.e1em() * self.y()
- self.y() * operand.e2em() * self.x())
* inv_norm_sq,
(self.em() * operand.e2em() * self.em() + self.ep() * operand.e2em() * self.ep()
- self.ep() * operand.epem() * self.y()
- self.x() * operand.e1em() * self.y()
+ self.x() * operand.e2em() * self.x()
- self.y() * operand.e1em() * self.x()
- self.y() * operand.e2em() * self.y()
- self.y() * operand.epem() * self.ep())
* inv_norm_sq,
(self.em() * operand.epem() * self.em()
- self.ep() * operand.e1em() * self.x()
- self.ep() * operand.e2em() * self.y()
- self.ep() * operand.epem() * self.ep()
- self.x() * operand.e1em() * self.ep()
+ self.x() * operand.epem() * self.x()
- self.y() * operand.e2em() * self.ep()
+ self.y() * operand.epem() * self.y())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Line<T>> for RoundPoint<T> {
type Output = Line<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Line<T>) -> Option<Line<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Line::new_unchecked(
(-(self.em() * operand.nx() * self.em())
- self.ep() * operand.d() * self.x()
- self.ep() * operand.nx() * self.ep()
+ self.ep() * operand.ny() * self.y()
- self.x() * operand.d() * self.ep()
+ self.x() * operand.nx() * self.x()
+ self.y() * operand.nx() * self.y()
+ self.y() * operand.ny() * self.ep())
* inv_norm_sq,
(-(self.em() * operand.ny() * self.em())
+ self.ep() * operand.nx() * self.y()
+ self.ep() * operand.ny() * self.ep()
+ self.x() * operand.d() * self.y()
+ self.x() * operand.ny() * self.x()
+ self.y() * operand.d() * self.x()
+ self.y() * operand.nx() * self.ep()
- self.y() * operand.ny() * self.y())
* inv_norm_sq,
(-(self.em() * operand.d() * self.em()) + self.ep() * operand.d() * self.ep()
- self.ep() * operand.nx() * self.x()
- self.x() * operand.d() * self.x()
- self.x() * operand.nx() * self.ep()
+ self.x() * operand.ny() * self.y()
+ self.y() * operand.d() * self.y()
+ self.y() * operand.ny() * self.x())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Motor<T>> for RoundPoint<T> {
type Output = Motor<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Motor<T>) -> Option<Motor<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Motor::new_unchecked(
(self.em() * operand.e1em() * self.x()
+ self.em() * operand.e2em() * self.y()
+ self.em() * operand.epem() * self.ep()
- self.em() * operand.s() * self.em()
- self.ep() * operand.e1ep() * self.x()
- self.ep() * operand.e2ep() * self.y()
- self.ep() * operand.epem() * self.em()
+ self.ep() * operand.s() * self.ep()
- self.x() * operand.e1em() * self.em()
+ self.x() * operand.e1ep() * self.ep()
+ self.x() * operand.m() * self.y()
+ self.x() * operand.s() * self.x()
- self.y() * operand.e2em() * self.em()
+ self.y() * operand.e2ep() * self.ep()
- self.y() * operand.m() * self.x()
+ self.y() * operand.s() * self.y())
* inv_norm_sq,
(self.em() * operand.e1em() * self.y()
- self.em() * operand.e2em() * self.x()
- self.em() * operand.m() * self.em()
+ self.em() * operand.ps() * self.ep()
- self.ep() * operand.e1ep() * self.y()
+ self.ep() * operand.e2ep() * self.x()
+ self.ep() * operand.m() * self.ep()
- self.ep() * operand.ps() * self.em()
- self.x() * operand.e2em() * self.em()
+ self.x() * operand.e2ep() * self.ep()
- self.x() * operand.m() * self.x()
+ self.x() * operand.s() * self.y()
+ self.y() * operand.e1em() * self.em()
- self.y() * operand.e1ep() * self.ep()
- self.y() * operand.m() * self.y()
- self.y() * operand.s() * self.x())
* inv_norm_sq,
(self.em() * operand.e1em() * self.ep()
- self.em() * operand.e1ep() * self.em()
- self.em() * operand.epem() * self.x()
- self.em() * operand.ps() * self.y()
+ self.ep() * operand.e1em() * self.em()
- self.ep() * operand.e1ep() * self.ep()
- self.ep() * operand.m() * self.y()
- self.ep() * operand.s() * self.x()
- self.x() * operand.e1ep() * self.x()
- self.x() * operand.e2ep() * self.y()
- self.x() * operand.epem() * self.em()
+ self.x() * operand.s() * self.ep()
+ self.y() * operand.e1ep() * self.y()
- self.y() * operand.e2ep() * self.x()
- self.y() * operand.m() * self.ep()
+ self.y() * operand.ps() * self.em())
* inv_norm_sq,
(self.em() * operand.e2em() * self.ep()
- self.em() * operand.e2ep() * self.em()
- self.em() * operand.epem() * self.y()
+ self.em() * operand.ps() * self.x()
+ self.ep() * operand.e2em() * self.em()
- self.ep() * operand.e2ep() * self.ep()
+ self.ep() * operand.m() * self.x()
- self.ep() * operand.s() * self.y()
- self.x() * operand.e1ep() * self.y()
+ self.x() * operand.e2ep() * self.x()
+ self.x() * operand.m() * self.ep()
- self.x() * operand.ps() * self.em()
- self.y() * operand.e1ep() * self.x()
- self.y() * operand.e2ep() * self.y()
- self.y() * operand.epem() * self.em()
+ self.y() * operand.s() * self.ep())
* inv_norm_sq,
(self.em() * operand.e1em() * self.em()
- self.em() * operand.e1ep() * self.ep()
- self.em() * operand.m() * self.y()
- self.em() * operand.s() * self.x()
+ self.ep() * operand.e1em() * self.ep()
- self.ep() * operand.e1ep() * self.em()
- self.ep() * operand.epem() * self.x()
- self.ep() * operand.ps() * self.y()
- self.x() * operand.e1em() * self.x()
- self.x() * operand.e2em() * self.y()
- self.x() * operand.epem() * self.ep()
+ self.x() * operand.s() * self.em()
+ self.y() * operand.e1em() * self.y()
- self.y() * operand.e2em() * self.x()
- self.y() * operand.m() * self.em()
+ self.y() * operand.ps() * self.ep())
* inv_norm_sq,
(self.em() * operand.e2em() * self.em() - self.em() * operand.e2ep() * self.ep()
+ self.em() * operand.m() * self.x()
- self.em() * operand.s() * self.y()
+ self.ep() * operand.e2em() * self.ep()
- self.ep() * operand.e2ep() * self.em()
- self.ep() * operand.epem() * self.y()
+ self.ep() * operand.ps() * self.x()
- self.x() * operand.e1em() * self.y()
+ self.x() * operand.e2em() * self.x()
+ self.x() * operand.m() * self.em()
- self.x() * operand.ps() * self.ep()
- self.y() * operand.e1em() * self.x()
- self.y() * operand.e2em() * self.y()
- self.y() * operand.epem() * self.ep()
+ self.y() * operand.s() * self.em())
* inv_norm_sq,
(self.em() * operand.e1ep() * self.x()
+ self.em() * operand.e2ep() * self.y()
+ self.em() * operand.epem() * self.em()
- self.em() * operand.s() * self.ep()
- self.ep() * operand.e1em() * self.x()
- self.ep() * operand.e2em() * self.y()
- self.ep() * operand.epem() * self.ep()
+ self.ep() * operand.s() * self.em()
- self.x() * operand.e1em() * self.ep()
+ self.x() * operand.e1ep() * self.em()
+ self.x() * operand.epem() * self.x()
+ self.x() * operand.ps() * self.y()
- self.y() * operand.e2em() * self.ep()
+ self.y() * operand.e2ep() * self.em()
+ self.y() * operand.epem() * self.y()
- self.y() * operand.ps() * self.x())
* inv_norm_sq,
(self.em() * operand.e1ep() * self.y()
- self.em() * operand.e2ep() * self.x()
- self.em() * operand.m() * self.ep()
+ self.em() * operand.ps() * self.em()
- self.ep() * operand.e1em() * self.y()
+ self.ep() * operand.e2em() * self.x()
+ self.ep() * operand.m() * self.em()
- self.ep() * operand.ps() * self.ep()
- self.x() * operand.e2em() * self.ep()
+ self.x() * operand.e2ep() * self.em()
+ self.x() * operand.epem() * self.y()
- self.x() * operand.ps() * self.x()
+ self.y() * operand.e1em() * self.ep()
- self.y() * operand.e1ep() * self.em()
- self.y() * operand.epem() * self.x()
- self.y() * operand.ps() * self.y())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<PointPair<T>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &PointPair<T>) -> Option<PointPair<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(PointPair::new_unchecked(
(self.em() * operand.e1em() * self.y()
- self.em() * operand.e2em() * self.x()
- self.em() * operand.m() * self.em()
- self.ep() * operand.e1ep() * self.y()
+ self.ep() * operand.e2ep() * self.x()
+ self.ep() * operand.m() * self.ep()
- self.x() * operand.e2em() * self.em()
+ self.x() * operand.e2ep() * self.ep()
- self.x() * operand.m() * self.x()
+ self.y() * operand.e1em() * self.em()
- self.y() * operand.e1ep() * self.ep()
- self.y() * operand.m() * self.y())
* inv_norm_sq,
(self.em() * operand.e1em() * self.ep()
- self.em() * operand.e1ep() * self.em()
- self.em() * operand.epem() * self.x()
+ self.ep() * operand.e1em() * self.em()
- self.ep() * operand.e1ep() * self.ep()
- self.ep() * operand.m() * self.y()
- self.x() * operand.e1ep() * self.x()
- self.x() * operand.e2ep() * self.y()
- self.x() * operand.epem() * self.em()
+ self.y() * operand.e1ep() * self.y()
- self.y() * operand.e2ep() * self.x()
- self.y() * operand.m() * self.ep())
* inv_norm_sq,
(self.em() * operand.e2em() * self.ep()
- self.em() * operand.e2ep() * self.em()
- self.em() * operand.epem() * self.y()
+ self.ep() * operand.e2em() * self.em()
- self.ep() * operand.e2ep() * self.ep()
+ self.ep() * operand.m() * self.x()
- self.x() * operand.e1ep() * self.y()
+ self.x() * operand.e2ep() * self.x()
+ self.x() * operand.m() * self.ep()
- self.y() * operand.e1ep() * self.x()
- self.y() * operand.e2ep() * self.y()
- self.y() * operand.epem() * self.em())
* inv_norm_sq,
(self.em() * operand.e1em() * self.em()
- self.em() * operand.e1ep() * self.ep()
- self.em() * operand.m() * self.y()
+ self.ep() * operand.e1em() * self.ep()
- self.ep() * operand.e1ep() * self.em()
- self.ep() * operand.epem() * self.x()
- self.x() * operand.e1em() * self.x()
- self.x() * operand.e2em() * self.y()
- self.x() * operand.epem() * self.ep()
+ self.y() * operand.e1em() * self.y()
- self.y() * operand.e2em() * self.x()
- self.y() * operand.m() * self.em())
* inv_norm_sq,
(self.em() * operand.e2em() * self.em() - self.em() * operand.e2ep() * self.ep()
+ self.em() * operand.m() * self.x()
+ self.ep() * operand.e2em() * self.ep()
- self.ep() * operand.e2ep() * self.em()
- self.ep() * operand.epem() * self.y()
- self.x() * operand.e1em() * self.y()
+ self.x() * operand.e2em() * self.x()
+ self.x() * operand.m() * self.em()
- self.y() * operand.e1em() * self.x()
- self.y() * operand.e2em() * self.y()
- self.y() * operand.epem() * self.ep())
* inv_norm_sq,
(self.em() * operand.e1ep() * self.x()
+ self.em() * operand.e2ep() * self.y()
+ self.em() * operand.epem() * self.em()
- self.ep() * operand.e1em() * self.x()
- self.ep() * operand.e2em() * self.y()
- self.ep() * operand.epem() * self.ep()
- self.x() * operand.e1em() * self.ep()
+ self.x() * operand.e1ep() * self.em()
+ self.x() * operand.epem() * self.x()
- self.y() * operand.e2em() * self.ep()
+ self.y() * operand.e2ep() * self.em()
+ self.y() * operand.epem() * self.y())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Pseudoscalar<T>> for RoundPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Pseudoscalar<T>) -> Option<Pseudoscalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Pseudoscalar::new_unchecked(
(self.em() * operand.ps() * self.em()
- self.ep() * operand.ps() * self.ep()
- self.x() * operand.ps() * self.x()
- self.y() * operand.ps() * self.y())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<RoundPoint<T>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &RoundPoint<T>) -> Option<RoundPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(RoundPoint::new_unchecked(
(-(self.em() * operand.em() * self.x())
+ self.em() * operand.x() * self.em()
+ self.ep() * operand.ep() * self.x()
- self.ep() * operand.x() * self.ep()
- self.x() * operand.em() * self.em()
+ self.x() * operand.ep() * self.ep()
+ self.x() * operand.x() * self.x()
+ self.x() * operand.y() * self.y()
- self.y() * operand.x() * self.y()
+ self.y() * operand.y() * self.x())
* inv_norm_sq,
(-(self.em() * operand.em() * self.y())
+ self.em() * operand.y() * self.em()
+ self.ep() * operand.ep() * self.y()
- self.ep() * operand.y() * self.ep()
+ self.x() * operand.x() * self.y()
- self.x() * operand.y() * self.x()
- self.y() * operand.em() * self.em()
+ self.y() * operand.ep() * self.ep()
+ self.y() * operand.x() * self.x()
+ self.y() * operand.y() * self.y())
* inv_norm_sq,
(-(self.em() * operand.em() * self.ep()) + self.em() * operand.ep() * self.em()
- self.ep() * operand.em() * self.em()
+ self.ep() * operand.ep() * self.ep()
+ self.ep() * operand.x() * self.x()
+ self.ep() * operand.y() * self.y()
- self.x() * operand.ep() * self.x()
+ self.x() * operand.x() * self.ep()
- self.y() * operand.ep() * self.y()
+ self.y() * operand.y() * self.ep())
* inv_norm_sq,
(-(self.em() * operand.em() * self.em())
+ self.em() * operand.ep() * self.ep()
+ self.em() * operand.x() * self.x()
+ self.em() * operand.y() * self.y()
- self.ep() * operand.em() * self.ep()
+ self.ep() * operand.ep() * self.em()
- self.x() * operand.em() * self.x()
+ self.x() * operand.x() * self.em()
- self.y() * operand.em() * self.y()
+ self.y() * operand.y() * self.em())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Scalar<T>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Scalar<T>) -> Option<Scalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Scalar::new_unchecked(
(-(self.em() * operand.s() * self.em())
+ self.ep() * operand.s() * self.ep()
+ self.x() * operand.s() * self.x()
+ self.y() * operand.s() * self.y())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Circle<T>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Circle<T>) -> Option<Circle<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Circle::new_unchecked(
(self.s() * operand.w() * self.s()) * inv_norm_sq,
(self.s() * operand.e12em() * self.s()) * inv_norm_sq,
(self.s() * operand.e1epem() * self.s()) * inv_norm_sq,
(self.s() * operand.e2epem() * self.s()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<FlatPoint<T>> for Scalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &FlatPoint<T>) -> Option<FlatPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(FlatPoint::new_unchecked(
(self.s() * operand.e1em() * self.s()) * inv_norm_sq,
(self.s() * operand.e2em() * self.s()) * inv_norm_sq,
(self.s() * operand.epem() * self.s()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Line<T>> for Scalar<T> {
type Output = Line<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Line<T>) -> Option<Line<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Line::new_unchecked(
(self.s() * operand.nx() * self.s()) * inv_norm_sq,
(self.s() * operand.ny() * self.s()) * inv_norm_sq,
(self.s() * operand.d() * self.s()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Motor<T>> for Scalar<T> {
type Output = Motor<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Motor<T>) -> Option<Motor<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Motor::new_unchecked(
(self.s() * operand.s() * self.s()) * inv_norm_sq,
(self.s() * operand.m() * self.s()) * inv_norm_sq,
(self.s() * operand.e1ep() * self.s()) * inv_norm_sq,
(self.s() * operand.e2ep() * self.s()) * inv_norm_sq,
(self.s() * operand.e1em() * self.s()) * inv_norm_sq,
(self.s() * operand.e2em() * self.s()) * inv_norm_sq,
(self.s() * operand.epem() * self.s()) * inv_norm_sq,
(self.s() * operand.ps() * self.s()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<PointPair<T>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &PointPair<T>) -> Option<PointPair<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(PointPair::new_unchecked(
(self.s() * operand.m() * self.s()) * inv_norm_sq,
(self.s() * operand.e1ep() * self.s()) * inv_norm_sq,
(self.s() * operand.e2ep() * self.s()) * inv_norm_sq,
(self.s() * operand.e1em() * self.s()) * inv_norm_sq,
(self.s() * operand.e2em() * self.s()) * inv_norm_sq,
(self.s() * operand.epem() * self.s()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Pseudoscalar<T>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Pseudoscalar<T>) -> Option<Pseudoscalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Pseudoscalar::new_unchecked(
(self.s() * operand.ps() * self.s()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<RoundPoint<T>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &RoundPoint<T>) -> Option<RoundPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(RoundPoint::new_unchecked(
(self.s() * operand.x() * self.s()) * inv_norm_sq,
(self.s() * operand.y() * self.s()) * inv_norm_sq,
(self.s() * operand.ep() * self.s()) * inv_norm_sq,
(self.s() * operand.em() * self.s()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseSandwich<Scalar<T>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn try_inverse_sandwich(&self, operand: &Scalar<T>) -> Option<Scalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Scalar::new_unchecked(
(self.s() * operand.s() * self.s()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Circle<T>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Circle<T>) -> Option<Circle<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Circle::new_unchecked(
(-(self.e12em() * operand.e12em() * self.w())
+ self.e12em() * operand.w() * self.e12em()
- self.e1epem() * operand.e1epem() * self.w()
+ self.e1epem() * operand.w() * self.e1epem()
- self.e2epem() * operand.e2epem() * self.w()
+ self.e2epem() * operand.w() * self.e2epem()
- self.w() * operand.e12em() * self.e12em()
- self.w() * operand.e1epem() * self.e1epem()
- self.w() * operand.e2epem() * self.e2epem()
+ self.w() * operand.w() * self.w())
* inv_norm_sq,
(-(self.e12em() * operand.e12em() * self.e12em())
- self.e12em() * operand.e1epem() * self.e1epem()
- self.e12em() * operand.e2epem() * self.e2epem()
+ self.e12em() * operand.w() * self.w()
+ self.e1epem() * operand.e12em() * self.e1epem()
- self.e1epem() * operand.e1epem() * self.e12em()
+ self.e2epem() * operand.e12em() * self.e2epem()
- self.e2epem() * operand.e2epem() * self.e12em()
- self.w() * operand.e12em() * self.w()
+ self.w() * operand.w() * self.e12em())
* inv_norm_sq,
(-(self.e12em() * operand.e12em() * self.e1epem())
+ self.e12em() * operand.e1epem() * self.e12em()
- self.e1epem() * operand.e12em() * self.e12em()
- self.e1epem() * operand.e1epem() * self.e1epem()
- self.e1epem() * operand.e2epem() * self.e2epem()
+ self.e1epem() * operand.w() * self.w()
+ self.e2epem() * operand.e1epem() * self.e2epem()
- self.e2epem() * operand.e2epem() * self.e1epem()
- self.w() * operand.e1epem() * self.w()
+ self.w() * operand.w() * self.e1epem())
* inv_norm_sq,
(-(self.e12em() * operand.e12em() * self.e2epem())
+ self.e12em() * operand.e2epem() * self.e12em()
- self.e1epem() * operand.e1epem() * self.e2epem()
+ self.e1epem() * operand.e2epem() * self.e1epem()
- self.e2epem() * operand.e12em() * self.e12em()
- self.e2epem() * operand.e1epem() * self.e1epem()
- self.e2epem() * operand.e2epem() * self.e2epem()
+ self.e2epem() * operand.w() * self.w()
- self.w() * operand.e2epem() * self.w()
+ self.w() * operand.w() * self.e2epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<FlatPoint<T>> for Circle<T> {
type Output = FlatPoint<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &FlatPoint<T>) -> Option<FlatPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(FlatPoint::new_unchecked(
(self.e12em() * operand.e1em() * self.e12em()
- self.e12em() * operand.epem() * self.e2epem()
+ self.e1epem() * operand.e1em() * self.e1epem()
+ self.e1epem() * operand.e2em() * self.e2epem()
- self.e2epem() * operand.e1em() * self.e2epem()
+ self.e2epem() * operand.e2em() * self.e1epem()
- self.e2epem() * operand.epem() * self.e12em()
+ self.w() * operand.e1em() * self.w())
* inv_norm_sq,
(self.e12em() * operand.e2em() * self.e12em()
+ self.e12em() * operand.epem() * self.e1epem()
+ self.e1epem() * operand.e1em() * self.e2epem()
- self.e1epem() * operand.e2em() * self.e1epem()
+ self.e1epem() * operand.epem() * self.e12em()
+ self.e2epem() * operand.e1em() * self.e1epem()
+ self.e2epem() * operand.e2em() * self.e2epem()
+ self.w() * operand.e2em() * self.w())
* inv_norm_sq,
(-(self.e12em() * operand.e1em() * self.e2epem())
+ self.e12em() * operand.e2em() * self.e1epem()
- self.e12em() * operand.epem() * self.e12em()
+ self.e1epem() * operand.e2em() * self.e12em()
+ self.e1epem() * operand.epem() * self.e1epem()
- self.e2epem() * operand.e1em() * self.e12em()
+ self.e2epem() * operand.epem() * self.e2epem()
+ self.w() * operand.epem() * self.w())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Line<T>> for Circle<T> {
type Output = Line<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Line<T>) -> Option<Line<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Line::new_unchecked(
(-(self.e12em() * operand.d() * self.e2epem())
- self.e12em() * operand.nx() * self.e12em()
- self.e12em() * operand.ny() * self.e1epem()
+ self.e1epem() * operand.nx() * self.e1epem()
- self.e1epem() * operand.ny() * self.e12em()
- self.e2epem() * operand.d() * self.e12em()
+ self.e2epem() * operand.nx() * self.e2epem()
- self.w() * operand.nx() * self.w())
* inv_norm_sq,
(-(self.e12em() * operand.nx() * self.e1epem())
+ self.e12em() * operand.ny() * self.e12em()
- self.e1epem() * operand.d() * self.e2epem()
- self.e1epem() * operand.nx() * self.e12em()
- self.e1epem() * operand.ny() * self.e1epem()
- self.e2epem() * operand.d() * self.e1epem()
+ self.e2epem() * operand.ny() * self.e2epem()
- self.w() * operand.ny() * self.w())
* inv_norm_sq,
(self.e12em() * operand.d() * self.e12em()
- self.e12em() * operand.nx() * self.e2epem()
+ self.e1epem() * operand.d() * self.e1epem()
- self.e1epem() * operand.ny() * self.e2epem()
- self.e2epem() * operand.d() * self.e2epem()
- self.e2epem() * operand.nx() * self.e12em()
- self.e2epem() * operand.ny() * self.e1epem()
- self.w() * operand.d() * self.w())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Motor<T>> for Circle<T> {
type Output = Motor<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Motor<T>) -> Option<Motor<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Motor::new_unchecked(
(self.e12em() * operand.e1ep() * self.e2epem()
- self.e12em() * operand.e2ep() * self.e1epem()
+ self.e12em() * operand.epem() * self.w()
+ self.e12em() * operand.s() * self.e12em()
- self.e1epem() * operand.e2em() * self.w()
+ self.e1epem() * operand.e2ep() * self.e12em()
- self.e1epem() * operand.m() * self.e2epem()
+ self.e1epem() * operand.s() * self.e1epem()
+ self.e2epem() * operand.e1em() * self.w()
- self.e2epem() * operand.e1ep() * self.e12em()
+ self.e2epem() * operand.m() * self.e1epem()
+ self.e2epem() * operand.s() * self.e2epem()
- self.w() * operand.e1em() * self.e2epem()
+ self.w() * operand.e2em() * self.e1epem()
- self.w() * operand.epem() * self.e12em()
- self.w() * operand.s() * self.w())
* inv_norm_sq,
(self.e12em() * operand.e1ep() * self.e1epem()
+ self.e12em() * operand.e2ep() * self.e2epem()
+ self.e12em() * operand.m() * self.e12em()
+ self.e12em() * operand.ps() * self.w()
- self.e1epem() * operand.e1em() * self.w()
+ self.e1epem() * operand.e1ep() * self.e12em()
- self.e1epem() * operand.m() * self.e1epem()
- self.e1epem() * operand.s() * self.e2epem()
- self.e2epem() * operand.e2em() * self.w()
+ self.e2epem() * operand.e2ep() * self.e12em()
- self.e2epem() * operand.m() * self.e2epem()
+ self.e2epem() * operand.s() * self.e1epem()
- self.w() * operand.e1em() * self.e1epem()
- self.w() * operand.e2em() * self.e2epem()
- self.w() * operand.m() * self.w()
- self.w() * operand.ps() * self.e12em())
* inv_norm_sq,
(self.e12em() * operand.e1em() * self.w()
- self.e12em() * operand.e1ep() * self.e12em()
+ self.e12em() * operand.m() * self.e1epem()
+ self.e12em() * operand.s() * self.e2epem()
+ self.e1epem() * operand.e1ep() * self.e1epem()
+ self.e1epem() * operand.e2ep() * self.e2epem()
+ self.e1epem() * operand.m() * self.e12em()
+ self.e1epem() * operand.ps() * self.w()
- self.e2epem() * operand.e1ep() * self.e2epem()
+ self.e2epem() * operand.e2ep() * self.e1epem()
- self.e2epem() * operand.epem() * self.w()
- self.e2epem() * operand.s() * self.e12em()
+ self.w() * operand.e1em() * self.e12em()
- self.w() * operand.e1ep() * self.w()
- self.w() * operand.epem() * self.e2epem()
- self.w() * operand.ps() * self.e1epem())
* inv_norm_sq,
(self.e12em() * operand.e2em() * self.w()
- self.e12em() * operand.e2ep() * self.e12em()
+ self.e12em() * operand.m() * self.e2epem()
- self.e12em() * operand.s() * self.e1epem()
+ self.e1epem() * operand.e1ep() * self.e2epem()
- self.e1epem() * operand.e2ep() * self.e1epem()
+ self.e1epem() * operand.epem() * self.w()
+ self.e1epem() * operand.s() * self.e12em()
+ self.e2epem() * operand.e1ep() * self.e1epem()
+ self.e2epem() * operand.e2ep() * self.e2epem()
+ self.e2epem() * operand.m() * self.e12em()
+ self.e2epem() * operand.ps() * self.w()
+ self.w() * operand.e2em() * self.e12em()
- self.w() * operand.e2ep() * self.w()
+ self.w() * operand.epem() * self.e1epem()
- self.w() * operand.ps() * self.e2epem())
* inv_norm_sq,
(self.e12em() * operand.e1em() * self.e12em()
- self.e12em() * operand.e1ep() * self.w()
- self.e12em() * operand.epem() * self.e2epem()
- self.e12em() * operand.ps() * self.e1epem()
+ self.e1epem() * operand.e1em() * self.e1epem()
+ self.e1epem() * operand.e2em() * self.e2epem()
+ self.e1epem() * operand.m() * self.w()
+ self.e1epem() * operand.ps() * self.e12em()
- self.e2epem() * operand.e1em() * self.e2epem()
+ self.e2epem() * operand.e2em() * self.e1epem()
- self.e2epem() * operand.epem() * self.e12em()
- self.e2epem() * operand.s() * self.w()
+ self.w() * operand.e1em() * self.w()
- self.w() * operand.e1ep() * self.e12em()
+ self.w() * operand.m() * self.e1epem()
+ self.w() * operand.s() * self.e2epem())
* inv_norm_sq,
(self.e12em() * operand.e2em() * self.e12em()
- self.e12em() * operand.e2ep() * self.w()
+ self.e12em() * operand.epem() * self.e1epem()
- self.e12em() * operand.ps() * self.e2epem()
+ self.e1epem() * operand.e1em() * self.e2epem()
- self.e1epem() * operand.e2em() * self.e1epem()
+ self.e1epem() * operand.epem() * self.e12em()
+ self.e1epem() * operand.s() * self.w()
+ self.e2epem() * operand.e1em() * self.e1epem()
+ self.e2epem() * operand.e2em() * self.e2epem()
+ self.e2epem() * operand.m() * self.w()
+ self.e2epem() * operand.ps() * self.e12em()
+ self.w() * operand.e2em() * self.w()
- self.w() * operand.e2ep() * self.e12em()
+ self.w() * operand.m() * self.e2epem()
- self.w() * operand.s() * self.e1epem())
* inv_norm_sq,
(-(self.e12em() * operand.e1em() * self.e2epem())
+ self.e12em() * operand.e2em() * self.e1epem()
- self.e12em() * operand.epem() * self.e12em()
- self.e12em() * operand.s() * self.w()
+ self.e1epem() * operand.e2em() * self.e12em()
- self.e1epem() * operand.e2ep() * self.w()
+ self.e1epem() * operand.epem() * self.e1epem()
- self.e1epem() * operand.ps() * self.e2epem()
- self.e2epem() * operand.e1em() * self.e12em()
+ self.e2epem() * operand.e1ep() * self.w()
+ self.e2epem() * operand.epem() * self.e2epem()
+ self.e2epem() * operand.ps() * self.e1epem()
+ self.w() * operand.e1ep() * self.e2epem()
- self.w() * operand.e2ep() * self.e1epem()
+ self.w() * operand.epem() * self.w()
+ self.w() * operand.s() * self.e12em())
* inv_norm_sq,
(-(self.e12em() * operand.e1em() * self.e1epem())
- self.e12em() * operand.e2em() * self.e2epem()
- self.e12em() * operand.m() * self.w()
- self.e12em() * operand.ps() * self.e12em()
+ self.e1epem() * operand.e1em() * self.e12em()
- self.e1epem() * operand.e1ep() * self.w()
- self.e1epem() * operand.epem() * self.e2epem()
- self.e1epem() * operand.ps() * self.e1epem()
+ self.e2epem() * operand.e2em() * self.e12em()
- self.e2epem() * operand.e2ep() * self.w()
+ self.e2epem() * operand.epem() * self.e1epem()
- self.e2epem() * operand.ps() * self.e2epem()
+ self.w() * operand.e1ep() * self.e1epem()
+ self.w() * operand.e2ep() * self.e2epem()
+ self.w() * operand.m() * self.e12em()
+ self.w() * operand.ps() * self.w())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<PointPair<T>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &PointPair<T>) -> Option<PointPair<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(PointPair::new_unchecked(
(self.e12em() * operand.e1ep() * self.e1epem()
+ self.e12em() * operand.e2ep() * self.e2epem()
+ self.e12em() * operand.m() * self.e12em()
- self.e1epem() * operand.e1em() * self.w()
+ self.e1epem() * operand.e1ep() * self.e12em()
- self.e1epem() * operand.m() * self.e1epem()
- self.e2epem() * operand.e2em() * self.w()
+ self.e2epem() * operand.e2ep() * self.e12em()
- self.e2epem() * operand.m() * self.e2epem()
- self.w() * operand.e1em() * self.e1epem()
- self.w() * operand.e2em() * self.e2epem()
- self.w() * operand.m() * self.w())
* inv_norm_sq,
(self.e12em() * operand.e1em() * self.w()
- self.e12em() * operand.e1ep() * self.e12em()
+ self.e12em() * operand.m() * self.e1epem()
+ self.e1epem() * operand.e1ep() * self.e1epem()
+ self.e1epem() * operand.e2ep() * self.e2epem()
+ self.e1epem() * operand.m() * self.e12em()
- self.e2epem() * operand.e1ep() * self.e2epem()
+ self.e2epem() * operand.e2ep() * self.e1epem()
- self.e2epem() * operand.epem() * self.w()
+ self.w() * operand.e1em() * self.e12em()
- self.w() * operand.e1ep() * self.w()
- self.w() * operand.epem() * self.e2epem())
* inv_norm_sq,
(self.e12em() * operand.e2em() * self.w()
- self.e12em() * operand.e2ep() * self.e12em()
+ self.e12em() * operand.m() * self.e2epem()
+ self.e1epem() * operand.e1ep() * self.e2epem()
- self.e1epem() * operand.e2ep() * self.e1epem()
+ self.e1epem() * operand.epem() * self.w()
+ self.e2epem() * operand.e1ep() * self.e1epem()
+ self.e2epem() * operand.e2ep() * self.e2epem()
+ self.e2epem() * operand.m() * self.e12em()
+ self.w() * operand.e2em() * self.e12em()
- self.w() * operand.e2ep() * self.w()
+ self.w() * operand.epem() * self.e1epem())
* inv_norm_sq,
(self.e12em() * operand.e1em() * self.e12em()
- self.e12em() * operand.e1ep() * self.w()
- self.e12em() * operand.epem() * self.e2epem()
+ self.e1epem() * operand.e1em() * self.e1epem()
+ self.e1epem() * operand.e2em() * self.e2epem()
+ self.e1epem() * operand.m() * self.w()
- self.e2epem() * operand.e1em() * self.e2epem()
+ self.e2epem() * operand.e2em() * self.e1epem()
- self.e2epem() * operand.epem() * self.e12em()
+ self.w() * operand.e1em() * self.w()
- self.w() * operand.e1ep() * self.e12em()
+ self.w() * operand.m() * self.e1epem())
* inv_norm_sq,
(self.e12em() * operand.e2em() * self.e12em()
- self.e12em() * operand.e2ep() * self.w()
+ self.e12em() * operand.epem() * self.e1epem()
+ self.e1epem() * operand.e1em() * self.e2epem()
- self.e1epem() * operand.e2em() * self.e1epem()
+ self.e1epem() * operand.epem() * self.e12em()
+ self.e2epem() * operand.e1em() * self.e1epem()
+ self.e2epem() * operand.e2em() * self.e2epem()
+ self.e2epem() * operand.m() * self.w()
+ self.w() * operand.e2em() * self.w()
- self.w() * operand.e2ep() * self.e12em()
+ self.w() * operand.m() * self.e2epem())
* inv_norm_sq,
(-(self.e12em() * operand.e1em() * self.e2epem())
+ self.e12em() * operand.e2em() * self.e1epem()
- self.e12em() * operand.epem() * self.e12em()
+ self.e1epem() * operand.e2em() * self.e12em()
- self.e1epem() * operand.e2ep() * self.w()
+ self.e1epem() * operand.epem() * self.e1epem()
- self.e2epem() * operand.e1em() * self.e12em()
+ self.e2epem() * operand.e1ep() * self.w()
+ self.e2epem() * operand.epem() * self.e2epem()
+ self.w() * operand.e1ep() * self.e2epem()
- self.w() * operand.e2ep() * self.e1epem()
+ self.w() * operand.epem() * self.w())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Pseudoscalar<T>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Pseudoscalar<T>) -> Option<Pseudoscalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Pseudoscalar::new_unchecked(
(-(self.e12em() * operand.ps() * self.e12em())
- self.e1epem() * operand.ps() * self.e1epem()
- self.e2epem() * operand.ps() * self.e2epem()
+ self.w() * operand.ps() * self.w())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<RoundPoint<T>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &RoundPoint<T>) -> Option<RoundPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(RoundPoint::new_unchecked(
(self.e12em() * operand.ep() * self.e2epem()
- self.e12em() * operand.x() * self.e12em()
- self.e1epem() * operand.x() * self.e1epem()
- self.e1epem() * operand.y() * self.e2epem()
- self.e2epem() * operand.em() * self.w()
+ self.e2epem() * operand.ep() * self.e12em()
+ self.e2epem() * operand.x() * self.e2epem()
- self.e2epem() * operand.y() * self.e1epem()
- self.w() * operand.em() * self.e2epem()
+ self.w() * operand.x() * self.w())
* inv_norm_sq,
(-(self.e12em() * operand.ep() * self.e1epem())
- self.e12em() * operand.y() * self.e12em()
+ self.e1epem() * operand.em() * self.w()
- self.e1epem() * operand.ep() * self.e12em()
- self.e1epem() * operand.x() * self.e2epem()
+ self.e1epem() * operand.y() * self.e1epem()
- self.e2epem() * operand.x() * self.e1epem()
- self.e2epem() * operand.y() * self.e2epem()
+ self.w() * operand.em() * self.e1epem()
+ self.w() * operand.y() * self.w())
* inv_norm_sq,
(-(self.e12em() * operand.em() * self.w())
+ self.e12em() * operand.ep() * self.e12em()
+ self.e12em() * operand.x() * self.e2epem()
- self.e12em() * operand.y() * self.e1epem()
- self.e1epem() * operand.ep() * self.e1epem()
- self.e1epem() * operand.y() * self.e12em()
- self.e2epem() * operand.ep() * self.e2epem()
+ self.e2epem() * operand.x() * self.e12em()
- self.w() * operand.em() * self.e12em()
+ self.w() * operand.ep() * self.w())
* inv_norm_sq,
(-(self.e12em() * operand.em() * self.e12em())
+ self.e12em() * operand.ep() * self.w()
- self.e1epem() * operand.em() * self.e1epem()
- self.e1epem() * operand.y() * self.w()
- self.e2epem() * operand.em() * self.e2epem()
+ self.e2epem() * operand.x() * self.w()
- self.w() * operand.em() * self.w()
+ self.w() * operand.ep() * self.e12em()
+ self.w() * operand.x() * self.e2epem()
- self.w() * operand.y() * self.e1epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Scalar<T>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Scalar<T>) -> Option<Scalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Scalar::new_unchecked(
(self.e12em() * operand.s() * self.e12em()
+ self.e1epem() * operand.s() * self.e1epem()
+ self.e2epem() * operand.s() * self.e2epem()
- self.w() * operand.s() * self.w())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Circle<T>> for FlatPoint<T> {
type Output = Circle<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Circle<T>) -> Option<Circle<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Circle::new_unchecked(
(self.e1em() * operand.w() * self.e1em()
+ self.e2em() * operand.w() * self.e2em()
+ self.epem() * operand.w() * self.epem())
* inv_norm_sq,
(-(self.e1em() * operand.e12em() * self.e1em())
+ self.e1em() * operand.e2epem() * self.epem()
- self.e2em() * operand.e12em() * self.e2em()
- self.e2em() * operand.e1epem() * self.epem()
+ self.epem() * operand.e12em() * self.epem()
- self.epem() * operand.e1epem() * self.e2em()
+ self.epem() * operand.e2epem() * self.e1em())
* inv_norm_sq,
(-(self.e1em() * operand.e1epem() * self.e1em())
- self.e1em() * operand.e2epem() * self.e2em()
- self.e2em() * operand.e12em() * self.epem()
+ self.e2em() * operand.e1epem() * self.e2em()
- self.e2em() * operand.e2epem() * self.e1em()
- self.epem() * operand.e12em() * self.e2em()
- self.epem() * operand.e1epem() * self.epem())
* inv_norm_sq,
(self.e1em() * operand.e12em() * self.epem()
- self.e1em() * operand.e1epem() * self.e2em()
+ self.e1em() * operand.e2epem() * self.e1em()
- self.e2em() * operand.e1epem() * self.e1em()
- self.e2em() * operand.e2epem() * self.e2em()
+ self.epem() * operand.e12em() * self.e1em()
- self.epem() * operand.e2epem() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<FlatPoint<T>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &FlatPoint<T>) -> Option<FlatPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(FlatPoint::new_unchecked(
(self.e1em() * operand.e1em() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.epem() * self.epem()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1em()
- self.epem() * operand.e1em() * self.epem()
+ self.epem() * operand.epem() * self.e1em())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e2em()
- self.e1em() * operand.e2em() * self.e1em()
+ self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.epem() * self.epem()
- self.epem() * operand.e2em() * self.epem()
+ self.epem() * operand.epem() * self.e2em())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.epem()
- self.e1em() * operand.epem() * self.e1em()
+ self.e2em() * operand.e2em() * self.epem()
- self.e2em() * operand.epem() * self.e2em()
+ self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.epem() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Line<T>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Line<T>) -> Option<Line<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Line::new_unchecked(
(self.e1em() * operand.d() * self.epem()
- self.e1em() * operand.nx() * self.e1em()
- self.e2em() * operand.nx() * self.e2em()
- self.e2em() * operand.ny() * self.epem()
+ self.epem() * operand.d() * self.e1em()
+ self.epem() * operand.nx() * self.epem()
- self.epem() * operand.ny() * self.e2em())
* inv_norm_sq,
(-(self.e1em() * operand.d() * self.e2em())
- self.e1em() * operand.ny() * self.e1em()
- self.e2em() * operand.d() * self.e1em()
- self.e2em() * operand.nx() * self.epem()
+ self.e2em() * operand.ny() * self.e2em()
- self.epem() * operand.nx() * self.e2em()
- self.epem() * operand.ny() * self.epem())
* inv_norm_sq,
(self.e1em() * operand.d() * self.e1em() + self.e1em() * operand.nx() * self.epem()
- self.e1em() * operand.ny() * self.e2em()
- self.e2em() * operand.d() * self.e2em()
- self.e2em() * operand.ny() * self.e1em()
- self.epem() * operand.d() * self.epem()
+ self.epem() * operand.nx() * self.e1em())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Motor<T>> for FlatPoint<T> {
type Output = Motor<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Motor<T>) -> Option<Motor<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Motor::new_unchecked(
(-(self.e1em() * operand.e1ep() * self.epem())
- self.e1em() * operand.m() * self.e2em()
+ self.e1em() * operand.s() * self.e1em()
- self.e2em() * operand.e2ep() * self.epem()
+ self.e2em() * operand.m() * self.e1em()
+ self.e2em() * operand.s() * self.e2em()
+ self.epem() * operand.e1ep() * self.e1em()
+ self.epem() * operand.e2ep() * self.e2em()
+ self.epem() * operand.s() * self.epem())
* inv_norm_sq,
(self.e1em() * operand.e2ep() * self.epem()
- self.e1em() * operand.m() * self.e1em()
- self.e1em() * operand.s() * self.e2em()
- self.e2em() * operand.e1ep() * self.epem()
- self.e2em() * operand.m() * self.e2em()
+ self.e2em() * operand.s() * self.e1em()
- self.epem() * operand.e1ep() * self.e2em()
+ self.epem() * operand.e2ep() * self.e1em()
+ self.epem() * operand.m() * self.epem())
* inv_norm_sq,
(-(self.e1em() * operand.e1ep() * self.e1em())
- self.e1em() * operand.e2ep() * self.e2em()
- self.e1em() * operand.s() * self.epem()
+ self.e2em() * operand.e1ep() * self.e2em()
- self.e2em() * operand.e2ep() * self.e1em()
- self.e2em() * operand.m() * self.epem()
- self.epem() * operand.e1ep() * self.epem()
- self.epem() * operand.m() * self.e2em()
+ self.epem() * operand.s() * self.e1em())
* inv_norm_sq,
(-(self.e1em() * operand.e1ep() * self.e2em())
+ self.e1em() * operand.e2ep() * self.e1em()
+ self.e1em() * operand.m() * self.epem()
- self.e2em() * operand.e1ep() * self.e1em()
- self.e2em() * operand.e2ep() * self.e2em()
- self.e2em() * operand.s() * self.epem()
- self.epem() * operand.e2ep() * self.epem()
+ self.epem() * operand.m() * self.e1em()
+ self.epem() * operand.s() * self.e2em())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.epem() * self.epem()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1em()
+ self.e2em() * operand.ps() * self.epem()
- self.epem() * operand.e1em() * self.epem()
+ self.epem() * operand.epem() * self.e1em()
- self.epem() * operand.ps() * self.e2em())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e2em()
- self.e1em() * operand.e2em() * self.e1em()
- self.e1em() * operand.ps() * self.epem()
+ self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.epem() * self.epem()
- self.epem() * operand.e2em() * self.epem()
+ self.epem() * operand.epem() * self.e2em()
+ self.epem() * operand.ps() * self.e1em())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.epem()
- self.e1em() * operand.epem() * self.e1em()
+ self.e1em() * operand.ps() * self.e2em()
+ self.e2em() * operand.e2em() * self.epem()
- self.e2em() * operand.epem() * self.e2em()
- self.e2em() * operand.ps() * self.e1em()
+ self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.epem() * self.epem())
* inv_norm_sq,
(-(self.e1em() * operand.e2em() * self.epem())
+ self.e1em() * operand.epem() * self.e2em()
+ self.e1em() * operand.ps() * self.e1em()
+ self.e2em() * operand.e1em() * self.epem()
- self.e2em() * operand.epem() * self.e1em()
+ self.e2em() * operand.ps() * self.e2em()
- self.epem() * operand.e1em() * self.e2em()
+ self.epem() * operand.e2em() * self.e1em()
+ self.epem() * operand.ps() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<PointPair<T>> for FlatPoint<T> {
type Output = PointPair<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &PointPair<T>) -> Option<PointPair<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(PointPair::new_unchecked(
(self.e1em() * operand.e2ep() * self.epem()
- self.e1em() * operand.m() * self.e1em()
- self.e2em() * operand.e1ep() * self.epem()
- self.e2em() * operand.m() * self.e2em()
- self.epem() * operand.e1ep() * self.e2em()
+ self.epem() * operand.e2ep() * self.e1em()
+ self.epem() * operand.m() * self.epem())
* inv_norm_sq,
(-(self.e1em() * operand.e1ep() * self.e1em())
- self.e1em() * operand.e2ep() * self.e2em()
+ self.e2em() * operand.e1ep() * self.e2em()
- self.e2em() * operand.e2ep() * self.e1em()
- self.e2em() * operand.m() * self.epem()
- self.epem() * operand.e1ep() * self.epem()
- self.epem() * operand.m() * self.e2em())
* inv_norm_sq,
(-(self.e1em() * operand.e1ep() * self.e2em())
+ self.e1em() * operand.e2ep() * self.e1em()
+ self.e1em() * operand.m() * self.epem()
- self.e2em() * operand.e1ep() * self.e1em()
- self.e2em() * operand.e2ep() * self.e2em()
- self.epem() * operand.e2ep() * self.epem()
+ self.epem() * operand.m() * self.e1em())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.epem() * self.epem()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1em()
- self.epem() * operand.e1em() * self.epem()
+ self.epem() * operand.epem() * self.e1em())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e2em()
- self.e1em() * operand.e2em() * self.e1em()
+ self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.epem() * self.epem()
- self.epem() * operand.e2em() * self.epem()
+ self.epem() * operand.epem() * self.e2em())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.epem()
- self.e1em() * operand.epem() * self.e1em()
+ self.e2em() * operand.e2em() * self.epem()
- self.e2em() * operand.epem() * self.e2em()
+ self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.epem() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Pseudoscalar<T>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Pseudoscalar<T>) -> Option<Pseudoscalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Pseudoscalar::new_unchecked(
(self.e1em() * operand.ps() * self.e1em()
+ self.e2em() * operand.ps() * self.e2em()
+ self.epem() * operand.ps() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<RoundPoint<T>> for FlatPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &RoundPoint<T>) -> Option<RoundPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(RoundPoint::new_unchecked(
(self.e1em() * operand.ep() * self.epem()
+ self.e1em() * operand.x() * self.e1em()
+ self.e1em() * operand.y() * self.e2em()
- self.e2em() * operand.x() * self.e2em()
+ self.e2em() * operand.y() * self.e1em()
+ self.epem() * operand.ep() * self.e1em()
- self.epem() * operand.x() * self.epem())
* inv_norm_sq,
(self.e1em() * operand.x() * self.e2em() - self.e1em() * operand.y() * self.e1em()
+ self.e2em() * operand.ep() * self.epem()
+ self.e2em() * operand.x() * self.e1em()
+ self.e2em() * operand.y() * self.e2em()
+ self.epem() * operand.ep() * self.e2em()
- self.epem() * operand.y() * self.epem())
* inv_norm_sq,
(-(self.e1em() * operand.ep() * self.e1em()) + self.e1em() * operand.x() * self.epem()
- self.e2em() * operand.ep() * self.e2em()
+ self.e2em() * operand.y() * self.epem()
+ self.epem() * operand.ep() * self.epem()
+ self.epem() * operand.x() * self.e1em()
+ self.epem() * operand.y() * self.e2em())
* inv_norm_sq,
(self.e1em() * operand.em() * self.e1em()
+ self.e2em() * operand.em() * self.e2em()
+ self.epem() * operand.em() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Scalar<T>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Scalar<T>) -> Option<Scalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Scalar::new_unchecked(
(self.e1em() * operand.s() * self.e1em()
+ self.e2em() * operand.s() * self.e2em()
+ self.epem() * operand.s() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Circle<T>> for Line<T> {
type Output = Circle<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Circle<T>) -> Option<Circle<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Circle::new_unchecked(
(self.d() * operand.w() * self.d()
+ self.nx() * operand.w() * self.nx()
+ self.ny() * operand.w() * self.ny())
* inv_norm_sq,
(self.d() * operand.e12em() * self.d()
- self.d() * operand.e2epem() * self.nx()
- self.nx() * operand.e12em() * self.nx()
- self.nx() * operand.e1epem() * self.ny()
- self.nx() * operand.e2epem() * self.d()
+ self.ny() * operand.e12em() * self.ny()
- self.ny() * operand.e1epem() * self.nx())
* inv_norm_sq,
(self.d() * operand.e1epem() * self.d()
- self.d() * operand.e2epem() * self.ny()
- self.nx() * operand.e12em() * self.ny()
+ self.nx() * operand.e1epem() * self.nx()
- self.ny() * operand.e12em() * self.nx()
- self.ny() * operand.e1epem() * self.ny()
- self.ny() * operand.e2epem() * self.d())
* inv_norm_sq,
(-(self.d() * operand.e12em() * self.nx())
- self.d() * operand.e1epem() * self.ny()
- self.d() * operand.e2epem() * self.d()
- self.nx() * operand.e12em() * self.d()
+ self.nx() * operand.e2epem() * self.nx()
- self.ny() * operand.e1epem() * self.d()
+ self.ny() * operand.e2epem() * self.ny())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<FlatPoint<T>> for Line<T> {
type Output = FlatPoint<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &FlatPoint<T>) -> Option<FlatPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(FlatPoint::new_unchecked(
(-(self.d() * operand.e1em() * self.d()) + self.d() * operand.e2em() * self.ny()
- self.d() * operand.epem() * self.nx()
+ self.nx() * operand.e1em() * self.nx()
- self.nx() * operand.epem() * self.d()
+ self.ny() * operand.e1em() * self.ny()
+ self.ny() * operand.e2em() * self.d())
* inv_norm_sq,
(self.d() * operand.e1em() * self.ny()
+ self.d() * operand.e2em() * self.d()
+ self.nx() * operand.e2em() * self.nx()
+ self.nx() * operand.epem() * self.ny()
+ self.ny() * operand.e1em() * self.d()
- self.ny() * operand.e2em() * self.ny()
+ self.ny() * operand.epem() * self.nx())
* inv_norm_sq,
(-(self.d() * operand.e1em() * self.nx()) + self.d() * operand.epem() * self.d()
- self.nx() * operand.e1em() * self.d()
+ self.nx() * operand.e2em() * self.ny()
- self.nx() * operand.epem() * self.nx()
+ self.ny() * operand.e2em() * self.nx()
+ self.ny() * operand.epem() * self.ny())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Line<T>> for Line<T> {
type Output = Line<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Line<T>) -> Option<Line<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Line::new_unchecked(
(-(self.d() * operand.d() * self.nx()) + self.d() * operand.nx() * self.d()
- self.nx() * operand.d() * self.d()
- self.nx() * operand.nx() * self.nx()
- self.nx() * operand.ny() * self.ny()
+ self.ny() * operand.nx() * self.ny()
- self.ny() * operand.ny() * self.nx())
* inv_norm_sq,
(-(self.d() * operand.d() * self.ny()) + self.d() * operand.ny() * self.d()
- self.nx() * operand.nx() * self.ny()
+ self.nx() * operand.ny() * self.nx()
- self.ny() * operand.d() * self.d()
- self.ny() * operand.nx() * self.nx()
- self.ny() * operand.ny() * self.ny())
* inv_norm_sq,
(-(self.d() * operand.d() * self.d())
- self.d() * operand.nx() * self.nx()
- self.d() * operand.ny() * self.ny()
+ self.nx() * operand.d() * self.nx()
- self.nx() * operand.nx() * self.d()
+ self.ny() * operand.d() * self.ny()
- self.ny() * operand.ny() * self.d())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Motor<T>> for Line<T> {
type Output = Motor<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Motor<T>) -> Option<Motor<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Motor::new_unchecked(
(-(self.d() * operand.e1ep() * self.nx())
+ self.d() * operand.m() * self.ny()
+ self.d() * operand.s() * self.d()
+ self.nx() * operand.e1ep() * self.d()
- self.nx() * operand.e2ep() * self.ny()
+ self.nx() * operand.s() * self.nx()
+ self.ny() * operand.e2ep() * self.nx()
- self.ny() * operand.m() * self.d()
+ self.ny() * operand.s() * self.ny())
* inv_norm_sq,
(self.d() * operand.e2ep() * self.nx() - self.d() * operand.m() * self.d()
+ self.d() * operand.s() * self.ny()
+ self.nx() * operand.e1ep() * self.ny()
+ self.nx() * operand.e2ep() * self.d()
+ self.nx() * operand.m() * self.nx()
+ self.ny() * operand.e1ep() * self.nx()
- self.ny() * operand.m() * self.ny()
- self.ny() * operand.s() * self.d())
* inv_norm_sq,
(-(self.d() * operand.e1ep() * self.d()) + self.d() * operand.e2ep() * self.ny()
- self.d() * operand.s() * self.nx()
- self.nx() * operand.e1ep() * self.nx()
+ self.nx() * operand.m() * self.ny()
+ self.nx() * operand.s() * self.d()
+ self.ny() * operand.e1ep() * self.ny()
+ self.ny() * operand.e2ep() * self.d()
+ self.ny() * operand.m() * self.nx())
* inv_norm_sq,
(self.d() * operand.e1ep() * self.ny()
+ self.d() * operand.e2ep() * self.d()
+ self.d() * operand.m() * self.nx()
- self.nx() * operand.e2ep() * self.nx()
+ self.nx() * operand.m() * self.d()
- self.nx() * operand.s() * self.ny()
+ self.ny() * operand.e1ep() * self.d()
- self.ny() * operand.e2ep() * self.ny()
+ self.ny() * operand.s() * self.nx())
* inv_norm_sq,
(-(self.d() * operand.e1em() * self.d()) + self.d() * operand.e2em() * self.ny()
- self.d() * operand.epem() * self.nx()
+ self.nx() * operand.e1em() * self.nx()
- self.nx() * operand.epem() * self.d()
- self.nx() * operand.ps() * self.ny()
+ self.ny() * operand.e1em() * self.ny()
+ self.ny() * operand.e2em() * self.d()
+ self.ny() * operand.ps() * self.nx())
* inv_norm_sq,
(self.d() * operand.e1em() * self.ny()
+ self.d() * operand.e2em() * self.d()
+ self.d() * operand.ps() * self.nx()
+ self.nx() * operand.e2em() * self.nx()
+ self.nx() * operand.epem() * self.ny()
- self.nx() * operand.ps() * self.d()
+ self.ny() * operand.e1em() * self.d()
- self.ny() * operand.e2em() * self.ny()
+ self.ny() * operand.epem() * self.nx())
* inv_norm_sq,
(-(self.d() * operand.e1em() * self.nx())
+ self.d() * operand.epem() * self.d()
+ self.d() * operand.ps() * self.ny()
- self.nx() * operand.e1em() * self.d()
+ self.nx() * operand.e2em() * self.ny()
- self.nx() * operand.epem() * self.nx()
+ self.ny() * operand.e2em() * self.nx()
+ self.ny() * operand.epem() * self.ny()
- self.ny() * operand.ps() * self.d())
* inv_norm_sq,
(self.d() * operand.e2em() * self.nx() + self.d() * operand.epem() * self.ny()
- self.d() * operand.ps() * self.d()
- self.nx() * operand.e1em() * self.ny()
- self.nx() * operand.e2em() * self.d()
- self.nx() * operand.ps() * self.nx()
+ self.ny() * operand.e1em() * self.nx()
- self.ny() * operand.epem() * self.d()
- self.ny() * operand.ps() * self.ny())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<PointPair<T>> for Line<T> {
type Output = PointPair<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &PointPair<T>) -> Option<PointPair<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(PointPair::new_unchecked(
(self.d() * operand.e2ep() * self.nx() - self.d() * operand.m() * self.d()
+ self.nx() * operand.e1ep() * self.ny()
+ self.nx() * operand.e2ep() * self.d()
+ self.nx() * operand.m() * self.nx()
+ self.ny() * operand.e1ep() * self.nx()
- self.ny() * operand.m() * self.ny())
* inv_norm_sq,
(-(self.d() * operand.e1ep() * self.d()) + self.d() * operand.e2ep() * self.ny()
- self.nx() * operand.e1ep() * self.nx()
+ self.nx() * operand.m() * self.ny()
+ self.ny() * operand.e1ep() * self.ny()
+ self.ny() * operand.e2ep() * self.d()
+ self.ny() * operand.m() * self.nx())
* inv_norm_sq,
(self.d() * operand.e1ep() * self.ny()
+ self.d() * operand.e2ep() * self.d()
+ self.d() * operand.m() * self.nx()
- self.nx() * operand.e2ep() * self.nx()
+ self.nx() * operand.m() * self.d()
+ self.ny() * operand.e1ep() * self.d()
- self.ny() * operand.e2ep() * self.ny())
* inv_norm_sq,
(-(self.d() * operand.e1em() * self.d()) + self.d() * operand.e2em() * self.ny()
- self.d() * operand.epem() * self.nx()
+ self.nx() * operand.e1em() * self.nx()
- self.nx() * operand.epem() * self.d()
+ self.ny() * operand.e1em() * self.ny()
+ self.ny() * operand.e2em() * self.d())
* inv_norm_sq,
(self.d() * operand.e1em() * self.ny()
+ self.d() * operand.e2em() * self.d()
+ self.nx() * operand.e2em() * self.nx()
+ self.nx() * operand.epem() * self.ny()
+ self.ny() * operand.e1em() * self.d()
- self.ny() * operand.e2em() * self.ny()
+ self.ny() * operand.epem() * self.nx())
* inv_norm_sq,
(-(self.d() * operand.e1em() * self.nx()) + self.d() * operand.epem() * self.d()
- self.nx() * operand.e1em() * self.d()
+ self.nx() * operand.e2em() * self.ny()
- self.nx() * operand.epem() * self.nx()
+ self.ny() * operand.e2em() * self.nx()
+ self.ny() * operand.epem() * self.ny())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Pseudoscalar<T>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Pseudoscalar<T>) -> Option<Pseudoscalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Pseudoscalar::new_unchecked(
(-(self.d() * operand.ps() * self.d())
- self.nx() * operand.ps() * self.nx()
- self.ny() * operand.ps() * self.ny())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<RoundPoint<T>> for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &RoundPoint<T>) -> Option<RoundPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(RoundPoint::new_unchecked(
(self.d() * operand.ep() * self.nx() + self.d() * operand.x() * self.d()
- self.d() * operand.y() * self.ny()
+ self.nx() * operand.ep() * self.d()
- self.nx() * operand.x() * self.nx()
- self.ny() * operand.x() * self.ny()
- self.ny() * operand.y() * self.d())
* inv_norm_sq,
(-(self.d() * operand.x() * self.ny())
- self.d() * operand.y() * self.d()
- self.nx() * operand.ep() * self.ny()
- self.nx() * operand.y() * self.nx()
- self.ny() * operand.ep() * self.nx()
- self.ny() * operand.x() * self.d()
+ self.ny() * operand.y() * self.ny())
* inv_norm_sq,
(-(self.d() * operand.ep() * self.d())
+ self.d() * operand.x() * self.nx()
+ self.nx() * operand.ep() * self.nx()
+ self.nx() * operand.x() * self.d()
- self.nx() * operand.y() * self.ny()
- self.ny() * operand.ep() * self.ny()
- self.ny() * operand.y() * self.nx())
* inv_norm_sq,
(-(self.d() * operand.em() * self.d())
- self.nx() * operand.em() * self.nx()
- self.ny() * operand.em() * self.ny())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Scalar<T>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Scalar<T>) -> Option<Scalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Scalar::new_unchecked(
(self.d() * operand.s() * self.d()
+ self.nx() * operand.s() * self.nx()
+ self.ny() * operand.s() * self.ny())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Circle<T>> for Motor<T> {
type Output = Circle<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Circle<T>) -> Option<Circle<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Circle::new_unchecked(
(-(self.e1em() * operand.e12em() * self.e1ep())
+ self.e1em() * operand.e1epem() * self.m()
+ self.e1em() * operand.e2epem() * self.s()
+ self.e1em() * operand.w() * self.e1em()
- self.e1ep() * operand.e12em() * self.e1em()
+ self.e1ep() * operand.e1epem() * self.ps()
+ self.e1ep() * operand.e2epem() * self.epem()
+ self.e1ep() * operand.w() * self.e1ep()
- self.e2em() * operand.e12em() * self.e2ep()
- self.e2em() * operand.e1epem() * self.s()
+ self.e2em() * operand.e2epem() * self.m()
+ self.e2em() * operand.w() * self.e2em()
- self.e2ep() * operand.e12em() * self.e2em()
- self.e2ep() * operand.e1epem() * self.epem()
+ self.e2ep() * operand.e2epem() * self.ps()
+ self.e2ep() * operand.w() * self.e2ep()
+ self.epem() * operand.e12em() * self.s()
- self.epem() * operand.e1epem() * self.e2ep()
+ self.epem() * operand.e2epem() * self.e1ep()
+ self.epem() * operand.w() * self.epem()
+ self.m() * operand.e12em() * self.ps()
+ self.m() * operand.e1epem() * self.e1em()
+ self.m() * operand.e2epem() * self.e2em()
+ self.m() * operand.w() * self.m()
+ self.ps() * operand.e12em() * self.m()
+ self.ps() * operand.e1epem() * self.e1ep()
+ self.ps() * operand.e2epem() * self.e2ep()
+ self.ps() * operand.w() * self.ps()
+ self.s() * operand.e12em() * self.epem()
- self.s() * operand.e1epem() * self.e2em()
+ self.s() * operand.e2epem() * self.e1em()
+ self.s() * operand.w() * self.s())
* inv_norm_sq,
(-(self.e1em() * operand.e12em() * self.e1em())
+ self.e1em() * operand.e1epem() * self.ps()
+ self.e1em() * operand.e2epem() * self.epem()
+ self.e1em() * operand.w() * self.e1ep()
- self.e1ep() * operand.e12em() * self.e1ep()
+ self.e1ep() * operand.e1epem() * self.m()
+ self.e1ep() * operand.e2epem() * self.s()
+ self.e1ep() * operand.w() * self.e1em()
- self.e2em() * operand.e12em() * self.e2em()
- self.e2em() * operand.e1epem() * self.epem()
+ self.e2em() * operand.e2epem() * self.ps()
+ self.e2em() * operand.w() * self.e2ep()
- self.e2ep() * operand.e12em() * self.e2ep()
- self.e2ep() * operand.e1epem() * self.s()
+ self.e2ep() * operand.e2epem() * self.m()
+ self.e2ep() * operand.w() * self.e2em()
+ self.epem() * operand.e12em() * self.epem()
- self.epem() * operand.e1epem() * self.e2em()
+ self.epem() * operand.e2epem() * self.e1em()
+ self.epem() * operand.w() * self.s()
+ self.m() * operand.e12em() * self.m()
+ self.m() * operand.e1epem() * self.e1ep()
+ self.m() * operand.e2epem() * self.e2ep()
+ self.m() * operand.w() * self.ps()
+ self.ps() * operand.e12em() * self.ps()
+ self.ps() * operand.e1epem() * self.e1em()
+ self.ps() * operand.e2epem() * self.e2em()
+ self.ps() * operand.w() * self.m()
+ self.s() * operand.e12em() * self.s()
- self.s() * operand.e1epem() * self.e2ep()
+ self.s() * operand.e2epem() * self.e1ep()
+ self.s() * operand.w() * self.epem())
* inv_norm_sq,
(-(self.e1em() * operand.e12em() * self.ps())
- self.e1em() * operand.e1epem() * self.e1em()
- self.e1em() * operand.e2epem() * self.e2em()
- self.e1em() * operand.w() * self.m()
+ self.e1ep() * operand.e12em() * self.m()
+ self.e1ep() * operand.e1epem() * self.e1ep()
+ self.e1ep() * operand.e2epem() * self.e2ep()
+ self.e1ep() * operand.w() * self.ps()
- self.e2em() * operand.e12em() * self.epem()
+ self.e2em() * operand.e1epem() * self.e2em()
- self.e2em() * operand.e2epem() * self.e1em()
- self.e2em() * operand.w() * self.s()
+ self.e2ep() * operand.e12em() * self.s()
- self.e2ep() * operand.e1epem() * self.e2ep()
+ self.e2ep() * operand.e2epem() * self.e1ep()
+ self.e2ep() * operand.w() * self.epem()
- self.epem() * operand.e12em() * self.e2em()
- self.epem() * operand.e1epem() * self.epem()
+ self.epem() * operand.e2epem() * self.ps()
+ self.epem() * operand.w() * self.e2ep()
+ self.m() * operand.e12em() * self.e1ep()
- self.m() * operand.e1epem() * self.m()
- self.m() * operand.e2epem() * self.s()
- self.m() * operand.w() * self.e1em()
- self.ps() * operand.e12em() * self.e1em()
+ self.ps() * operand.e1epem() * self.ps()
+ self.ps() * operand.e2epem() * self.epem()
+ self.ps() * operand.w() * self.e1ep()
+ self.s() * operand.e12em() * self.e2ep()
+ self.s() * operand.e1epem() * self.s()
- self.s() * operand.e2epem() * self.m()
- self.s() * operand.w() * self.e2em())
* inv_norm_sq,
(self.e1em() * operand.e12em() * self.epem()
- self.e1em() * operand.e1epem() * self.e2em()
+ self.e1em() * operand.e2epem() * self.e1em()
+ self.e1em() * operand.w() * self.s()
- self.e1ep() * operand.e12em() * self.s()
+ self.e1ep() * operand.e1epem() * self.e2ep()
- self.e1ep() * operand.e2epem() * self.e1ep()
- self.e1ep() * operand.w() * self.epem()
- self.e2em() * operand.e12em() * self.ps()
- self.e2em() * operand.e1epem() * self.e1em()
- self.e2em() * operand.e2epem() * self.e2em()
- self.e2em() * operand.w() * self.m()
+ self.e2ep() * operand.e12em() * self.m()
+ self.e2ep() * operand.e1epem() * self.e1ep()
+ self.e2ep() * operand.e2epem() * self.e2ep()
+ self.e2ep() * operand.w() * self.ps()
+ self.epem() * operand.e12em() * self.e1em()
- self.epem() * operand.e1epem() * self.ps()
- self.epem() * operand.e2epem() * self.epem()
- self.epem() * operand.w() * self.e1ep()
+ self.m() * operand.e12em() * self.e2ep()
+ self.m() * operand.e1epem() * self.s()
- self.m() * operand.e2epem() * self.m()
- self.m() * operand.w() * self.e2em()
- self.ps() * operand.e12em() * self.e2em()
- self.ps() * operand.e1epem() * self.epem()
+ self.ps() * operand.e2epem() * self.ps()
+ self.ps() * operand.w() * self.e2ep()
- self.s() * operand.e12em() * self.e1ep()
+ self.s() * operand.e1epem() * self.m()
+ self.s() * operand.e2epem() * self.s()
+ self.s() * operand.w() * self.e1em())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<FlatPoint<T>> for Motor<T> {
type Output = FlatPoint<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &FlatPoint<T>) -> Option<FlatPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(FlatPoint::new_unchecked(
(self.e1em() * operand.e1em() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.epem() * self.epem()
+ self.e1ep() * operand.e1em() * self.e1ep()
+ self.e1ep() * operand.e2em() * self.e2ep()
+ self.e1ep() * operand.epem() * self.s()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1em()
- self.e2em() * operand.epem() * self.ps()
- self.e2ep() * operand.e1em() * self.e2ep()
+ self.e2ep() * operand.e2em() * self.e1ep()
- self.e2ep() * operand.epem() * self.m()
- self.epem() * operand.e1em() * self.epem()
+ self.epem() * operand.e2em() * self.ps()
+ self.epem() * operand.epem() * self.e1em()
+ self.m() * operand.e1em() * self.m()
+ self.m() * operand.e2em() * self.s()
- self.m() * operand.epem() * self.e2ep()
+ self.ps() * operand.e1em() * self.ps()
+ self.ps() * operand.e2em() * self.epem()
- self.ps() * operand.epem() * self.e2em()
- self.s() * operand.e1em() * self.s()
+ self.s() * operand.e2em() * self.m()
+ self.s() * operand.epem() * self.e1ep())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e2em()
- self.e1em() * operand.e2em() * self.e1em()
+ self.e1em() * operand.epem() * self.ps()
+ self.e1ep() * operand.e1em() * self.e2ep()
- self.e1ep() * operand.e2em() * self.e1ep()
+ self.e1ep() * operand.epem() * self.m()
+ self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.epem() * self.epem()
+ self.e2ep() * operand.e1em() * self.e1ep()
+ self.e2ep() * operand.e2em() * self.e2ep()
+ self.e2ep() * operand.epem() * self.s()
- self.epem() * operand.e1em() * self.ps()
- self.epem() * operand.e2em() * self.epem()
+ self.epem() * operand.epem() * self.e2em()
- self.m() * operand.e1em() * self.s()
+ self.m() * operand.e2em() * self.m()
+ self.m() * operand.epem() * self.e1ep()
- self.ps() * operand.e1em() * self.epem()
+ self.ps() * operand.e2em() * self.ps()
+ self.ps() * operand.epem() * self.e1em()
- self.s() * operand.e1em() * self.m()
- self.s() * operand.e2em() * self.s()
+ self.s() * operand.epem() * self.e2ep())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.epem()
- self.e1em() * operand.e2em() * self.ps()
- self.e1em() * operand.epem() * self.e1em()
- self.e1ep() * operand.e1em() * self.s()
+ self.e1ep() * operand.e2em() * self.m()
+ self.e1ep() * operand.epem() * self.e1ep()
+ self.e2em() * operand.e1em() * self.ps()
+ self.e2em() * operand.e2em() * self.epem()
- self.e2em() * operand.epem() * self.e2em()
- self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.e2em() * self.s()
+ self.e2ep() * operand.epem() * self.e2ep()
+ self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.epem() * self.epem()
- self.m() * operand.e1em() * self.e2ep()
+ self.m() * operand.e2em() * self.e1ep()
- self.m() * operand.epem() * self.m()
+ self.ps() * operand.e1em() * self.e2em()
- self.ps() * operand.e2em() * self.e1em()
+ self.ps() * operand.epem() * self.ps()
- self.s() * operand.e1em() * self.e1ep()
- self.s() * operand.e2em() * self.e2ep()
- self.s() * operand.epem() * self.s())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Line<T>> for Motor<T> {
type Output = Line<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Line<T>) -> Option<Line<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Line::new_unchecked(
(self.e1em() * operand.d() * self.epem() - self.e1em() * operand.nx() * self.e1em()
+ self.e1em() * operand.ny() * self.ps()
+ self.e1ep() * operand.d() * self.s()
- self.e1ep() * operand.nx() * self.e1ep()
+ self.e1ep() * operand.ny() * self.m()
+ self.e2em() * operand.d() * self.ps()
- self.e2em() * operand.nx() * self.e2em()
- self.e2em() * operand.ny() * self.epem()
+ self.e2ep() * operand.d() * self.m()
- self.e2ep() * operand.nx() * self.e2ep()
- self.e2ep() * operand.ny() * self.s()
+ self.epem() * operand.d() * self.e1em()
+ self.epem() * operand.nx() * self.epem()
- self.epem() * operand.ny() * self.e2em()
+ self.m() * operand.d() * self.e2ep()
+ self.m() * operand.nx() * self.m()
+ self.m() * operand.ny() * self.e1ep()
+ self.ps() * operand.d() * self.e2em()
+ self.ps() * operand.nx() * self.ps()
+ self.ps() * operand.ny() * self.e1em()
+ self.s() * operand.d() * self.e1ep()
+ self.s() * operand.nx() * self.s()
- self.s() * operand.ny() * self.e2ep())
* inv_norm_sq,
(-(self.e1em() * operand.d() * self.e2em())
- self.e1em() * operand.nx() * self.ps()
- self.e1em() * operand.ny() * self.e1em()
+ self.e1ep() * operand.d() * self.e2ep()
+ self.e1ep() * operand.nx() * self.m()
+ self.e1ep() * operand.ny() * self.e1ep()
- self.e2em() * operand.d() * self.e1em()
- self.e2em() * operand.nx() * self.epem()
+ self.e2em() * operand.ny() * self.e2em()
+ self.e2ep() * operand.d() * self.e1ep()
+ self.e2ep() * operand.nx() * self.s()
- self.e2ep() * operand.ny() * self.e2ep()
+ self.epem() * operand.d() * self.ps()
- self.epem() * operand.nx() * self.e2em()
- self.epem() * operand.ny() * self.epem()
- self.m() * operand.d() * self.s()
+ self.m() * operand.nx() * self.e1ep()
- self.m() * operand.ny() * self.m()
+ self.ps() * operand.d() * self.epem()
- self.ps() * operand.nx() * self.e1em()
+ self.ps() * operand.ny() * self.ps()
- self.s() * operand.d() * self.m()
+ self.s() * operand.nx() * self.e2ep()
+ self.s() * operand.ny() * self.s())
* inv_norm_sq,
(self.e1em() * operand.d() * self.e1em() + self.e1em() * operand.nx() * self.epem()
- self.e1em() * operand.ny() * self.e2em()
- self.e1ep() * operand.d() * self.e1ep()
- self.e1ep() * operand.nx() * self.s()
+ self.e1ep() * operand.ny() * self.e2ep()
- self.e2em() * operand.d() * self.e2em()
- self.e2em() * operand.nx() * self.ps()
- self.e2em() * operand.ny() * self.e1em()
+ self.e2ep() * operand.d() * self.e2ep()
+ self.e2ep() * operand.nx() * self.m()
+ self.e2ep() * operand.ny() * self.e1ep()
- self.epem() * operand.d() * self.epem()
+ self.epem() * operand.nx() * self.e1em()
- self.epem() * operand.ny() * self.ps()
- self.m() * operand.d() * self.m()
+ self.m() * operand.nx() * self.e2ep()
+ self.m() * operand.ny() * self.s()
+ self.ps() * operand.d() * self.ps()
- self.ps() * operand.nx() * self.e2em()
- self.ps() * operand.ny() * self.epem()
+ self.s() * operand.d() * self.s()
- self.s() * operand.nx() * self.e1ep()
+ self.s() * operand.ny() * self.m())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Motor<T>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Motor<T>) -> Option<Motor<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Motor::new_unchecked(
(-(self.e1em() * operand.e1em() * self.s())
- self.e1em() * operand.e1ep() * self.epem()
+ self.e1em() * operand.e2em() * self.m()
+ self.e1em() * operand.e2ep() * self.ps()
+ self.e1em() * operand.epem() * self.e1ep()
- self.e1em() * operand.m() * self.e2em()
- self.e1em() * operand.ps() * self.e2ep()
+ self.e1em() * operand.s() * self.e1em()
+ self.e1ep() * operand.e1em() * self.epem()
+ self.e1ep() * operand.e1ep() * self.s()
- self.e1ep() * operand.e2em() * self.ps()
- self.e1ep() * operand.e2ep() * self.m()
- self.e1ep() * operand.epem() * self.e1em()
+ self.e1ep() * operand.m() * self.e2ep()
+ self.e1ep() * operand.ps() * self.e2em()
- self.e1ep() * operand.s() * self.e1ep()
- self.e2em() * operand.e1em() * self.m()
- self.e2em() * operand.e1ep() * self.ps()
- self.e2em() * operand.e2em() * self.s()
- self.e2em() * operand.e2ep() * self.epem()
+ self.e2em() * operand.epem() * self.e2ep()
+ self.e2em() * operand.m() * self.e1em()
+ self.e2em() * operand.ps() * self.e1ep()
+ self.e2em() * operand.s() * self.e2em()
+ self.e2ep() * operand.e1em() * self.ps()
+ self.e2ep() * operand.e1ep() * self.m()
+ self.e2ep() * operand.e2em() * self.epem()
+ self.e2ep() * operand.e2ep() * self.s()
- self.e2ep() * operand.epem() * self.e2em()
- self.e2ep() * operand.m() * self.e1ep()
- self.e2ep() * operand.ps() * self.e1em()
- self.e2ep() * operand.s() * self.e2ep()
- self.epem() * operand.e1em() * self.e1ep()
+ self.epem() * operand.e1ep() * self.e1em()
- self.epem() * operand.e2em() * self.e2ep()
+ self.epem() * operand.e2ep() * self.e2em()
- self.epem() * operand.epem() * self.s()
+ self.epem() * operand.m() * self.ps()
- self.epem() * operand.ps() * self.m()
+ self.epem() * operand.s() * self.epem()
+ self.m() * operand.e1em() * self.e2em()
- self.m() * operand.e1ep() * self.e2ep()
- self.m() * operand.e2em() * self.e1em()
+ self.m() * operand.e2ep() * self.e1ep()
+ self.m() * operand.epem() * self.ps()
+ self.m() * operand.m() * self.s()
- self.m() * operand.ps() * self.epem()
- self.m() * operand.s() * self.m()
- self.ps() * operand.e1em() * self.e2ep()
+ self.ps() * operand.e1ep() * self.e2em()
+ self.ps() * operand.e2em() * self.e1ep()
- self.ps() * operand.e2ep() * self.e1em()
- self.ps() * operand.epem() * self.m()
- self.ps() * operand.m() * self.epem()
+ self.ps() * operand.ps() * self.s()
+ self.ps() * operand.s() * self.ps()
+ self.s() * operand.e1em() * self.e1em()
- self.s() * operand.e1ep() * self.e1ep()
+ self.s() * operand.e2em() * self.e2em()
- self.s() * operand.e2ep() * self.e2ep()
+ self.s() * operand.epem() * self.epem()
- self.s() * operand.m() * self.m()
+ self.s() * operand.ps() * self.ps()
- self.s() * operand.s() * self.s())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.m()
+ self.e1em() * operand.e1ep() * self.ps()
+ self.e1em() * operand.e2em() * self.s()
+ self.e1em() * operand.e2ep() * self.epem()
- self.e1em() * operand.epem() * self.e2ep()
- self.e1em() * operand.m() * self.e1em()
- self.e1em() * operand.ps() * self.e1ep()
- self.e1em() * operand.s() * self.e2em()
- self.e1ep() * operand.e1em() * self.ps()
- self.e1ep() * operand.e1ep() * self.m()
- self.e1ep() * operand.e2em() * self.epem()
- self.e1ep() * operand.e2ep() * self.s()
+ self.e1ep() * operand.epem() * self.e2em()
+ self.e1ep() * operand.m() * self.e1ep()
+ self.e1ep() * operand.ps() * self.e1em()
+ self.e1ep() * operand.s() * self.e2ep()
- self.e2em() * operand.e1em() * self.s()
- self.e2em() * operand.e1ep() * self.epem()
+ self.e2em() * operand.e2em() * self.m()
+ self.e2em() * operand.e2ep() * self.ps()
+ self.e2em() * operand.epem() * self.e1ep()
- self.e2em() * operand.m() * self.e2em()
- self.e2em() * operand.ps() * self.e2ep()
+ self.e2em() * operand.s() * self.e1em()
+ self.e2ep() * operand.e1em() * self.epem()
+ self.e2ep() * operand.e1ep() * self.s()
- self.e2ep() * operand.e2em() * self.ps()
- self.e2ep() * operand.e2ep() * self.m()
- self.e2ep() * operand.epem() * self.e1em()
+ self.e2ep() * operand.m() * self.e2ep()
+ self.e2ep() * operand.ps() * self.e2em()
- self.e2ep() * operand.s() * self.e1ep()
+ self.epem() * operand.e1em() * self.e2ep()
- self.epem() * operand.e1ep() * self.e2em()
- self.epem() * operand.e2em() * self.e1ep()
+ self.epem() * operand.e2ep() * self.e1em()
+ self.epem() * operand.epem() * self.m()
+ self.epem() * operand.m() * self.epem()
- self.epem() * operand.ps() * self.s()
- self.epem() * operand.s() * self.ps()
+ self.m() * operand.e1em() * self.e1em()
- self.m() * operand.e1ep() * self.e1ep()
+ self.m() * operand.e2em() * self.e2em()
- self.m() * operand.e2ep() * self.e2ep()
+ self.m() * operand.epem() * self.epem()
- self.m() * operand.m() * self.m()
+ self.m() * operand.ps() * self.ps()
- self.m() * operand.s() * self.s()
- self.ps() * operand.e1em() * self.e1ep()
+ self.ps() * operand.e1ep() * self.e1em()
- self.ps() * operand.e2em() * self.e2ep()
+ self.ps() * operand.e2ep() * self.e2em()
- self.ps() * operand.epem() * self.s()
+ self.ps() * operand.m() * self.ps()
- self.ps() * operand.ps() * self.m()
+ self.ps() * operand.s() * self.epem()
- self.s() * operand.e1em() * self.e2em()
+ self.s() * operand.e1ep() * self.e2ep()
+ self.s() * operand.e2em() * self.e1em()
- self.s() * operand.e2ep() * self.e1ep()
- self.s() * operand.epem() * self.ps()
- self.s() * operand.m() * self.s()
+ self.s() * operand.ps() * self.epem()
+ self.s() * operand.s() * self.m())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e1ep()
- self.e1em() * operand.e1ep() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2ep()
- self.e1em() * operand.e2ep() * self.e2em()
+ self.e1em() * operand.epem() * self.s()
- self.e1em() * operand.m() * self.ps()
+ self.e1em() * operand.ps() * self.m()
- self.e1em() * operand.s() * self.epem()
+ self.e1ep() * operand.e1em() * self.e1em()
- self.e1ep() * operand.e1ep() * self.e1ep()
+ self.e1ep() * operand.e2em() * self.e2em()
- self.e1ep() * operand.e2ep() * self.e2ep()
+ self.e1ep() * operand.epem() * self.epem()
- self.e1ep() * operand.m() * self.m()
+ self.e1ep() * operand.ps() * self.ps()
- self.e1ep() * operand.s() * self.s()
- self.e2em() * operand.e1em() * self.e2ep()
+ self.e2em() * operand.e1ep() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1ep()
- self.e2em() * operand.e2ep() * self.e1em()
- self.e2em() * operand.epem() * self.m()
- self.e2em() * operand.m() * self.epem()
+ self.e2em() * operand.ps() * self.s()
+ self.e2em() * operand.s() * self.ps()
- self.e2ep() * operand.e1em() * self.e2em()
+ self.e2ep() * operand.e1ep() * self.e2ep()
+ self.e2ep() * operand.e2em() * self.e1em()
- self.e2ep() * operand.e2ep() * self.e1ep()
- self.e2ep() * operand.epem() * self.ps()
- self.e2ep() * operand.m() * self.s()
+ self.e2ep() * operand.ps() * self.epem()
+ self.e2ep() * operand.s() * self.m()
- self.epem() * operand.e1em() * self.s()
- self.epem() * operand.e1ep() * self.epem()
+ self.epem() * operand.e2em() * self.m()
+ self.epem() * operand.e2ep() * self.ps()
+ self.epem() * operand.epem() * self.e1ep()
- self.epem() * operand.m() * self.e2em()
- self.epem() * operand.ps() * self.e2ep()
+ self.epem() * operand.s() * self.e1em()
+ self.m() * operand.e1em() * self.ps()
+ self.m() * operand.e1ep() * self.m()
+ self.m() * operand.e2em() * self.epem()
+ self.m() * operand.e2ep() * self.s()
- self.m() * operand.epem() * self.e2em()
- self.m() * operand.m() * self.e1ep()
- self.m() * operand.ps() * self.e1em()
- self.m() * operand.s() * self.e2ep()
+ self.ps() * operand.e1em() * self.m()
+ self.ps() * operand.e1ep() * self.ps()
+ self.ps() * operand.e2em() * self.s()
+ self.ps() * operand.e2ep() * self.epem()
- self.ps() * operand.epem() * self.e2ep()
- self.ps() * operand.m() * self.e1em()
- self.ps() * operand.ps() * self.e1ep()
- self.ps() * operand.s() * self.e2em()
- self.s() * operand.e1em() * self.epem()
- self.s() * operand.e1ep() * self.s()
+ self.s() * operand.e2em() * self.ps()
+ self.s() * operand.e2ep() * self.m()
+ self.s() * operand.epem() * self.e1em()
- self.s() * operand.m() * self.e2ep()
- self.s() * operand.ps() * self.e2em()
+ self.s() * operand.s() * self.e1ep())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e2ep()
- self.e1em() * operand.e1ep() * self.e2em()
- self.e1em() * operand.e2em() * self.e1ep()
+ self.e1em() * operand.e2ep() * self.e1em()
+ self.e1em() * operand.epem() * self.m()
+ self.e1em() * operand.m() * self.epem()
- self.e1em() * operand.ps() * self.s()
- self.e1em() * operand.s() * self.ps()
+ self.e1ep() * operand.e1em() * self.e2em()
- self.e1ep() * operand.e1ep() * self.e2ep()
- self.e1ep() * operand.e2em() * self.e1em()
+ self.e1ep() * operand.e2ep() * self.e1ep()
+ self.e1ep() * operand.epem() * self.ps()
+ self.e1ep() * operand.m() * self.s()
- self.e1ep() * operand.ps() * self.epem()
- self.e1ep() * operand.s() * self.m()
+ self.e2em() * operand.e1em() * self.e1ep()
- self.e2em() * operand.e1ep() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2ep()
- self.e2em() * operand.e2ep() * self.e2em()
+ self.e2em() * operand.epem() * self.s()
- self.e2em() * operand.m() * self.ps()
+ self.e2em() * operand.ps() * self.m()
- self.e2em() * operand.s() * self.epem()
+ self.e2ep() * operand.e1em() * self.e1em()
- self.e2ep() * operand.e1ep() * self.e1ep()
+ self.e2ep() * operand.e2em() * self.e2em()
- self.e2ep() * operand.e2ep() * self.e2ep()
+ self.e2ep() * operand.epem() * self.epem()
- self.e2ep() * operand.m() * self.m()
+ self.e2ep() * operand.ps() * self.ps()
- self.e2ep() * operand.s() * self.s()
- self.epem() * operand.e1em() * self.m()
- self.epem() * operand.e1ep() * self.ps()
- self.epem() * operand.e2em() * self.s()
- self.epem() * operand.e2ep() * self.epem()
+ self.epem() * operand.epem() * self.e2ep()
+ self.epem() * operand.m() * self.e1em()
+ self.epem() * operand.ps() * self.e1ep()
+ self.epem() * operand.s() * self.e2em()
- self.m() * operand.e1em() * self.epem()
- self.m() * operand.e1ep() * self.s()
+ self.m() * operand.e2em() * self.ps()
+ self.m() * operand.e2ep() * self.m()
+ self.m() * operand.epem() * self.e1em()
- self.m() * operand.m() * self.e2ep()
- self.m() * operand.ps() * self.e2em()
+ self.m() * operand.s() * self.e1ep()
- self.ps() * operand.e1em() * self.s()
- self.ps() * operand.e1ep() * self.epem()
+ self.ps() * operand.e2em() * self.m()
+ self.ps() * operand.e2ep() * self.ps()
+ self.ps() * operand.epem() * self.e1ep()
- self.ps() * operand.m() * self.e2em()
- self.ps() * operand.ps() * self.e2ep()
+ self.ps() * operand.s() * self.e1em()
- self.s() * operand.e1em() * self.ps()
- self.s() * operand.e1ep() * self.m()
- self.s() * operand.e2em() * self.epem()
- self.s() * operand.e2ep() * self.s()
+ self.s() * operand.epem() * self.e2em()
+ self.s() * operand.m() * self.e1ep()
+ self.s() * operand.ps() * self.e1em()
+ self.s() * operand.s() * self.e2ep())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e1em()
- self.e1em() * operand.e1ep() * self.e1ep()
+ self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.e2ep() * self.e2ep()
+ self.e1em() * operand.epem() * self.epem()
- self.e1em() * operand.m() * self.m()
+ self.e1em() * operand.ps() * self.ps()
- self.e1em() * operand.s() * self.s()
+ self.e1ep() * operand.e1em() * self.e1ep()
- self.e1ep() * operand.e1ep() * self.e1em()
+ self.e1ep() * operand.e2em() * self.e2ep()
- self.e1ep() * operand.e2ep() * self.e2em()
+ self.e1ep() * operand.epem() * self.s()
- self.e1ep() * operand.m() * self.ps()
+ self.e1ep() * operand.ps() * self.m()
- self.e1ep() * operand.s() * self.epem()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e1ep() * self.e2ep()
+ self.e2em() * operand.e2em() * self.e1em()
- self.e2em() * operand.e2ep() * self.e1ep()
- self.e2em() * operand.epem() * self.ps()
- self.e2em() * operand.m() * self.s()
+ self.e2em() * operand.ps() * self.epem()
+ self.e2em() * operand.s() * self.m()
- self.e2ep() * operand.e1em() * self.e2ep()
+ self.e2ep() * operand.e1ep() * self.e2em()
+ self.e2ep() * operand.e2em() * self.e1ep()
- self.e2ep() * operand.e2ep() * self.e1em()
- self.e2ep() * operand.epem() * self.m()
- self.e2ep() * operand.m() * self.epem()
+ self.e2ep() * operand.ps() * self.s()
+ self.e2ep() * operand.s() * self.ps()
- self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.e1ep() * self.s()
+ self.epem() * operand.e2em() * self.ps()
+ self.epem() * operand.e2ep() * self.m()
+ self.epem() * operand.epem() * self.e1em()
- self.epem() * operand.m() * self.e2ep()
- self.epem() * operand.ps() * self.e2em()
+ self.epem() * operand.s() * self.e1ep()
+ self.m() * operand.e1em() * self.m()
+ self.m() * operand.e1ep() * self.ps()
+ self.m() * operand.e2em() * self.s()
+ self.m() * operand.e2ep() * self.epem()
- self.m() * operand.epem() * self.e2ep()
- self.m() * operand.m() * self.e1em()
- self.m() * operand.ps() * self.e1ep()
- self.m() * operand.s() * self.e2em()
+ self.ps() * operand.e1em() * self.ps()
+ self.ps() * operand.e1ep() * self.m()
+ self.ps() * operand.e2em() * self.epem()
+ self.ps() * operand.e2ep() * self.s()
- self.ps() * operand.epem() * self.e2em()
- self.ps() * operand.m() * self.e1ep()
- self.ps() * operand.ps() * self.e1em()
- self.ps() * operand.s() * self.e2ep()
- self.s() * operand.e1em() * self.s()
- self.s() * operand.e1ep() * self.epem()
+ self.s() * operand.e2em() * self.m()
+ self.s() * operand.e2ep() * self.ps()
+ self.s() * operand.epem() * self.e1ep()
- self.s() * operand.m() * self.e2em()
- self.s() * operand.ps() * self.e2ep()
+ self.s() * operand.s() * self.e1em())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e2em()
- self.e1em() * operand.e1ep() * self.e2ep()
- self.e1em() * operand.e2em() * self.e1em()
+ self.e1em() * operand.e2ep() * self.e1ep()
+ self.e1em() * operand.epem() * self.ps()
+ self.e1em() * operand.m() * self.s()
- self.e1em() * operand.ps() * self.epem()
- self.e1em() * operand.s() * self.m()
+ self.e1ep() * operand.e1em() * self.e2ep()
- self.e1ep() * operand.e1ep() * self.e2em()
- self.e1ep() * operand.e2em() * self.e1ep()
+ self.e1ep() * operand.e2ep() * self.e1em()
+ self.e1ep() * operand.epem() * self.m()
+ self.e1ep() * operand.m() * self.epem()
- self.e1ep() * operand.ps() * self.s()
- self.e1ep() * operand.s() * self.ps()
+ self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e1ep() * self.e1ep()
+ self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.e2ep() * self.e2ep()
+ self.e2em() * operand.epem() * self.epem()
- self.e2em() * operand.m() * self.m()
+ self.e2em() * operand.ps() * self.ps()
- self.e2em() * operand.s() * self.s()
+ self.e2ep() * operand.e1em() * self.e1ep()
- self.e2ep() * operand.e1ep() * self.e1em()
+ self.e2ep() * operand.e2em() * self.e2ep()
- self.e2ep() * operand.e2ep() * self.e2em()
+ self.e2ep() * operand.epem() * self.s()
- self.e2ep() * operand.m() * self.ps()
+ self.e2ep() * operand.ps() * self.m()
- self.e2ep() * operand.s() * self.epem()
- self.epem() * operand.e1em() * self.ps()
- self.epem() * operand.e1ep() * self.m()
- self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.e2ep() * self.s()
+ self.epem() * operand.epem() * self.e2em()
+ self.epem() * operand.m() * self.e1ep()
+ self.epem() * operand.ps() * self.e1em()
+ self.epem() * operand.s() * self.e2ep()
- self.m() * operand.e1em() * self.s()
- self.m() * operand.e1ep() * self.epem()
+ self.m() * operand.e2em() * self.m()
+ self.m() * operand.e2ep() * self.ps()
+ self.m() * operand.epem() * self.e1ep()
- self.m() * operand.m() * self.e2em()
- self.m() * operand.ps() * self.e2ep()
+ self.m() * operand.s() * self.e1em()
- self.ps() * operand.e1em() * self.epem()
- self.ps() * operand.e1ep() * self.s()
+ self.ps() * operand.e2em() * self.ps()
+ self.ps() * operand.e2ep() * self.m()
+ self.ps() * operand.epem() * self.e1em()
- self.ps() * operand.m() * self.e2ep()
- self.ps() * operand.ps() * self.e2em()
+ self.ps() * operand.s() * self.e1ep()
- self.s() * operand.e1em() * self.m()
- self.s() * operand.e1ep() * self.ps()
- self.s() * operand.e2em() * self.s()
- self.s() * operand.e2ep() * self.epem()
+ self.s() * operand.epem() * self.e2ep()
+ self.s() * operand.m() * self.e1em()
+ self.s() * operand.ps() * self.e1ep()
+ self.s() * operand.s() * self.e2em())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.epem() + self.e1em() * operand.e1ep() * self.s()
- self.e1em() * operand.e2em() * self.ps()
- self.e1em() * operand.e2ep() * self.m()
- self.e1em() * operand.epem() * self.e1em()
+ self.e1em() * operand.m() * self.e2ep()
+ self.e1em() * operand.ps() * self.e2em()
- self.e1em() * operand.s() * self.e1ep()
- self.e1ep() * operand.e1em() * self.s()
- self.e1ep() * operand.e1ep() * self.epem()
+ self.e1ep() * operand.e2em() * self.m()
+ self.e1ep() * operand.e2ep() * self.ps()
+ self.e1ep() * operand.epem() * self.e1ep()
- self.e1ep() * operand.m() * self.e2em()
- self.e1ep() * operand.ps() * self.e2ep()
+ self.e1ep() * operand.s() * self.e1em()
+ self.e2em() * operand.e1em() * self.ps()
+ self.e2em() * operand.e1ep() * self.m()
+ self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.e2ep() * self.s()
- self.e2em() * operand.epem() * self.e2em()
- self.e2em() * operand.m() * self.e1ep()
- self.e2em() * operand.ps() * self.e1em()
- self.e2em() * operand.s() * self.e2ep()
- self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.e1ep() * self.ps()
- self.e2ep() * operand.e2em() * self.s()
- self.e2ep() * operand.e2ep() * self.epem()
+ self.e2ep() * operand.epem() * self.e2ep()
+ self.e2ep() * operand.m() * self.e1em()
+ self.e2ep() * operand.ps() * self.e1ep()
+ self.e2ep() * operand.s() * self.e2em()
+ self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e1ep() * self.e1ep()
+ self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.e2ep() * self.e2ep()
+ self.epem() * operand.epem() * self.epem()
- self.epem() * operand.m() * self.m()
+ self.epem() * operand.ps() * self.ps()
- self.epem() * operand.s() * self.s()
- self.m() * operand.e1em() * self.e2ep()
+ self.m() * operand.e1ep() * self.e2em()
+ self.m() * operand.e2em() * self.e1ep()
- self.m() * operand.e2ep() * self.e1em()
- self.m() * operand.epem() * self.m()
- self.m() * operand.m() * self.epem()
+ self.m() * operand.ps() * self.s()
+ self.m() * operand.s() * self.ps()
+ self.ps() * operand.e1em() * self.e2em()
- self.ps() * operand.e1ep() * self.e2ep()
- self.ps() * operand.e2em() * self.e1em()
+ self.ps() * operand.e2ep() * self.e1ep()
+ self.ps() * operand.epem() * self.ps()
+ self.ps() * operand.m() * self.s()
- self.ps() * operand.ps() * self.epem()
- self.ps() * operand.s() * self.m()
- self.s() * operand.e1em() * self.e1ep()
+ self.s() * operand.e1ep() * self.e1em()
- self.s() * operand.e2em() * self.e2ep()
+ self.s() * operand.e2ep() * self.e2em()
- self.s() * operand.epem() * self.s()
+ self.s() * operand.m() * self.ps()
- self.s() * operand.ps() * self.m()
+ self.s() * operand.s() * self.epem())
* inv_norm_sq,
(-(self.e1em() * operand.e1em() * self.ps())
- self.e1em() * operand.e1ep() * self.m()
- self.e1em() * operand.e2em() * self.epem()
- self.e1em() * operand.e2ep() * self.s()
+ self.e1em() * operand.epem() * self.e2em()
+ self.e1em() * operand.m() * self.e1ep()
+ self.e1em() * operand.ps() * self.e1em()
+ self.e1em() * operand.s() * self.e2ep()
+ self.e1ep() * operand.e1em() * self.m()
+ self.e1ep() * operand.e1ep() * self.ps()
+ self.e1ep() * operand.e2em() * self.s()
+ self.e1ep() * operand.e2ep() * self.epem()
- self.e1ep() * operand.epem() * self.e2ep()
- self.e1ep() * operand.m() * self.e1em()
- self.e1ep() * operand.ps() * self.e1ep()
- self.e1ep() * operand.s() * self.e2em()
+ self.e2em() * operand.e1em() * self.epem()
+ self.e2em() * operand.e1ep() * self.s()
- self.e2em() * operand.e2em() * self.ps()
- self.e2em() * operand.e2ep() * self.m()
- self.e2em() * operand.epem() * self.e1em()
+ self.e2em() * operand.m() * self.e2ep()
+ self.e2em() * operand.ps() * self.e2em()
- self.e2em() * operand.s() * self.e1ep()
- self.e2ep() * operand.e1em() * self.s()
- self.e2ep() * operand.e1ep() * self.epem()
+ self.e2ep() * operand.e2em() * self.m()
+ self.e2ep() * operand.e2ep() * self.ps()
+ self.e2ep() * operand.epem() * self.e1ep()
- self.e2ep() * operand.m() * self.e2em()
- self.e2ep() * operand.ps() * self.e2ep()
+ self.e2ep() * operand.s() * self.e1em()
- self.epem() * operand.e1em() * self.e2em()
+ self.epem() * operand.e1ep() * self.e2ep()
+ self.epem() * operand.e2em() * self.e1em()
- self.epem() * operand.e2ep() * self.e1ep()
- self.epem() * operand.epem() * self.ps()
- self.epem() * operand.m() * self.s()
+ self.epem() * operand.ps() * self.epem()
+ self.epem() * operand.s() * self.m()
- self.m() * operand.e1em() * self.e1ep()
+ self.m() * operand.e1ep() * self.e1em()
- self.m() * operand.e2em() * self.e2ep()
+ self.m() * operand.e2ep() * self.e2em()
- self.m() * operand.epem() * self.s()
+ self.m() * operand.m() * self.ps()
- self.m() * operand.ps() * self.m()
+ self.m() * operand.s() * self.epem()
+ self.ps() * operand.e1em() * self.e1em()
- self.ps() * operand.e1ep() * self.e1ep()
+ self.ps() * operand.e2em() * self.e2em()
- self.ps() * operand.e2ep() * self.e2ep()
+ self.ps() * operand.epem() * self.epem()
- self.ps() * operand.m() * self.m()
+ self.ps() * operand.ps() * self.ps()
- self.ps() * operand.s() * self.s()
+ self.s() * operand.e1em() * self.e2ep()
- self.s() * operand.e1ep() * self.e2em()
- self.s() * operand.e2em() * self.e1ep()
+ self.s() * operand.e2ep() * self.e1em()
+ self.s() * operand.epem() * self.m()
+ self.s() * operand.m() * self.epem()
- self.s() * operand.ps() * self.s()
- self.s() * operand.s() * self.ps())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<PointPair<T>> for Motor<T> {
type Output = PointPair<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &PointPair<T>) -> Option<PointPair<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(PointPair::new_unchecked(
(self.e1em() * operand.e1em() * self.m()
+ self.e1em() * operand.e1ep() * self.ps()
+ self.e1em() * operand.e2em() * self.s()
+ self.e1em() * operand.e2ep() * self.epem()
- self.e1em() * operand.epem() * self.e2ep()
- self.e1em() * operand.m() * self.e1em()
- self.e1ep() * operand.e1em() * self.ps()
- self.e1ep() * operand.e1ep() * self.m()
- self.e1ep() * operand.e2em() * self.epem()
- self.e1ep() * operand.e2ep() * self.s()
+ self.e1ep() * operand.epem() * self.e2em()
+ self.e1ep() * operand.m() * self.e1ep()
- self.e2em() * operand.e1em() * self.s()
- self.e2em() * operand.e1ep() * self.epem()
+ self.e2em() * operand.e2em() * self.m()
+ self.e2em() * operand.e2ep() * self.ps()
+ self.e2em() * operand.epem() * self.e1ep()
- self.e2em() * operand.m() * self.e2em()
+ self.e2ep() * operand.e1em() * self.epem()
+ self.e2ep() * operand.e1ep() * self.s()
- self.e2ep() * operand.e2em() * self.ps()
- self.e2ep() * operand.e2ep() * self.m()
- self.e2ep() * operand.epem() * self.e1em()
+ self.e2ep() * operand.m() * self.e2ep()
+ self.epem() * operand.e1em() * self.e2ep()
- self.epem() * operand.e1ep() * self.e2em()
- self.epem() * operand.e2em() * self.e1ep()
+ self.epem() * operand.e2ep() * self.e1em()
+ self.epem() * operand.epem() * self.m()
+ self.epem() * operand.m() * self.epem()
+ self.m() * operand.e1em() * self.e1em()
- self.m() * operand.e1ep() * self.e1ep()
+ self.m() * operand.e2em() * self.e2em()
- self.m() * operand.e2ep() * self.e2ep()
+ self.m() * operand.epem() * self.epem()
- self.m() * operand.m() * self.m()
- self.ps() * operand.e1em() * self.e1ep()
+ self.ps() * operand.e1ep() * self.e1em()
- self.ps() * operand.e2em() * self.e2ep()
+ self.ps() * operand.e2ep() * self.e2em()
- self.ps() * operand.epem() * self.s()
+ self.ps() * operand.m() * self.ps()
- self.s() * operand.e1em() * self.e2em()
+ self.s() * operand.e1ep() * self.e2ep()
+ self.s() * operand.e2em() * self.e1em()
- self.s() * operand.e2ep() * self.e1ep()
- self.s() * operand.epem() * self.ps()
- self.s() * operand.m() * self.s())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e1ep()
- self.e1em() * operand.e1ep() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2ep()
- self.e1em() * operand.e2ep() * self.e2em()
+ self.e1em() * operand.epem() * self.s()
- self.e1em() * operand.m() * self.ps()
+ self.e1ep() * operand.e1em() * self.e1em()
- self.e1ep() * operand.e1ep() * self.e1ep()
+ self.e1ep() * operand.e2em() * self.e2em()
- self.e1ep() * operand.e2ep() * self.e2ep()
+ self.e1ep() * operand.epem() * self.epem()
- self.e1ep() * operand.m() * self.m()
- self.e2em() * operand.e1em() * self.e2ep()
+ self.e2em() * operand.e1ep() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1ep()
- self.e2em() * operand.e2ep() * self.e1em()
- self.e2em() * operand.epem() * self.m()
- self.e2em() * operand.m() * self.epem()
- self.e2ep() * operand.e1em() * self.e2em()
+ self.e2ep() * operand.e1ep() * self.e2ep()
+ self.e2ep() * operand.e2em() * self.e1em()
- self.e2ep() * operand.e2ep() * self.e1ep()
- self.e2ep() * operand.epem() * self.ps()
- self.e2ep() * operand.m() * self.s()
- self.epem() * operand.e1em() * self.s()
- self.epem() * operand.e1ep() * self.epem()
+ self.epem() * operand.e2em() * self.m()
+ self.epem() * operand.e2ep() * self.ps()
+ self.epem() * operand.epem() * self.e1ep()
- self.epem() * operand.m() * self.e2em()
+ self.m() * operand.e1em() * self.ps()
+ self.m() * operand.e1ep() * self.m()
+ self.m() * operand.e2em() * self.epem()
+ self.m() * operand.e2ep() * self.s()
- self.m() * operand.epem() * self.e2em()
- self.m() * operand.m() * self.e1ep()
+ self.ps() * operand.e1em() * self.m()
+ self.ps() * operand.e1ep() * self.ps()
+ self.ps() * operand.e2em() * self.s()
+ self.ps() * operand.e2ep() * self.epem()
- self.ps() * operand.epem() * self.e2ep()
- self.ps() * operand.m() * self.e1em()
- self.s() * operand.e1em() * self.epem()
- self.s() * operand.e1ep() * self.s()
+ self.s() * operand.e2em() * self.ps()
+ self.s() * operand.e2ep() * self.m()
+ self.s() * operand.epem() * self.e1em()
- self.s() * operand.m() * self.e2ep())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e2ep()
- self.e1em() * operand.e1ep() * self.e2em()
- self.e1em() * operand.e2em() * self.e1ep()
+ self.e1em() * operand.e2ep() * self.e1em()
+ self.e1em() * operand.epem() * self.m()
+ self.e1em() * operand.m() * self.epem()
+ self.e1ep() * operand.e1em() * self.e2em()
- self.e1ep() * operand.e1ep() * self.e2ep()
- self.e1ep() * operand.e2em() * self.e1em()
+ self.e1ep() * operand.e2ep() * self.e1ep()
+ self.e1ep() * operand.epem() * self.ps()
+ self.e1ep() * operand.m() * self.s()
+ self.e2em() * operand.e1em() * self.e1ep()
- self.e2em() * operand.e1ep() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2ep()
- self.e2em() * operand.e2ep() * self.e2em()
+ self.e2em() * operand.epem() * self.s()
- self.e2em() * operand.m() * self.ps()
+ self.e2ep() * operand.e1em() * self.e1em()
- self.e2ep() * operand.e1ep() * self.e1ep()
+ self.e2ep() * operand.e2em() * self.e2em()
- self.e2ep() * operand.e2ep() * self.e2ep()
+ self.e2ep() * operand.epem() * self.epem()
- self.e2ep() * operand.m() * self.m()
- self.epem() * operand.e1em() * self.m()
- self.epem() * operand.e1ep() * self.ps()
- self.epem() * operand.e2em() * self.s()
- self.epem() * operand.e2ep() * self.epem()
+ self.epem() * operand.epem() * self.e2ep()
+ self.epem() * operand.m() * self.e1em()
- self.m() * operand.e1em() * self.epem()
- self.m() * operand.e1ep() * self.s()
+ self.m() * operand.e2em() * self.ps()
+ self.m() * operand.e2ep() * self.m()
+ self.m() * operand.epem() * self.e1em()
- self.m() * operand.m() * self.e2ep()
- self.ps() * operand.e1em() * self.s()
- self.ps() * operand.e1ep() * self.epem()
+ self.ps() * operand.e2em() * self.m()
+ self.ps() * operand.e2ep() * self.ps()
+ self.ps() * operand.epem() * self.e1ep()
- self.ps() * operand.m() * self.e2em()
- self.s() * operand.e1em() * self.ps()
- self.s() * operand.e1ep() * self.m()
- self.s() * operand.e2em() * self.epem()
- self.s() * operand.e2ep() * self.s()
+ self.s() * operand.epem() * self.e2em()
+ self.s() * operand.m() * self.e1ep())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e1em()
- self.e1em() * operand.e1ep() * self.e1ep()
+ self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.e2ep() * self.e2ep()
+ self.e1em() * operand.epem() * self.epem()
- self.e1em() * operand.m() * self.m()
+ self.e1ep() * operand.e1em() * self.e1ep()
- self.e1ep() * operand.e1ep() * self.e1em()
+ self.e1ep() * operand.e2em() * self.e2ep()
- self.e1ep() * operand.e2ep() * self.e2em()
+ self.e1ep() * operand.epem() * self.s()
- self.e1ep() * operand.m() * self.ps()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e1ep() * self.e2ep()
+ self.e2em() * operand.e2em() * self.e1em()
- self.e2em() * operand.e2ep() * self.e1ep()
- self.e2em() * operand.epem() * self.ps()
- self.e2em() * operand.m() * self.s()
- self.e2ep() * operand.e1em() * self.e2ep()
+ self.e2ep() * operand.e1ep() * self.e2em()
+ self.e2ep() * operand.e2em() * self.e1ep()
- self.e2ep() * operand.e2ep() * self.e1em()
- self.e2ep() * operand.epem() * self.m()
- self.e2ep() * operand.m() * self.epem()
- self.epem() * operand.e1em() * self.epem()
- self.epem() * operand.e1ep() * self.s()
+ self.epem() * operand.e2em() * self.ps()
+ self.epem() * operand.e2ep() * self.m()
+ self.epem() * operand.epem() * self.e1em()
- self.epem() * operand.m() * self.e2ep()
+ self.m() * operand.e1em() * self.m()
+ self.m() * operand.e1ep() * self.ps()
+ self.m() * operand.e2em() * self.s()
+ self.m() * operand.e2ep() * self.epem()
- self.m() * operand.epem() * self.e2ep()
- self.m() * operand.m() * self.e1em()
+ self.ps() * operand.e1em() * self.ps()
+ self.ps() * operand.e1ep() * self.m()
+ self.ps() * operand.e2em() * self.epem()
+ self.ps() * operand.e2ep() * self.s()
- self.ps() * operand.epem() * self.e2em()
- self.ps() * operand.m() * self.e1ep()
- self.s() * operand.e1em() * self.s()
- self.s() * operand.e1ep() * self.epem()
+ self.s() * operand.e2em() * self.m()
+ self.s() * operand.e2ep() * self.ps()
+ self.s() * operand.epem() * self.e1ep()
- self.s() * operand.m() * self.e2em())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e2em()
- self.e1em() * operand.e1ep() * self.e2ep()
- self.e1em() * operand.e2em() * self.e1em()
+ self.e1em() * operand.e2ep() * self.e1ep()
+ self.e1em() * operand.epem() * self.ps()
+ self.e1em() * operand.m() * self.s()
+ self.e1ep() * operand.e1em() * self.e2ep()
- self.e1ep() * operand.e1ep() * self.e2em()
- self.e1ep() * operand.e2em() * self.e1ep()
+ self.e1ep() * operand.e2ep() * self.e1em()
+ self.e1ep() * operand.epem() * self.m()
+ self.e1ep() * operand.m() * self.epem()
+ self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e1ep() * self.e1ep()
+ self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.e2ep() * self.e2ep()
+ self.e2em() * operand.epem() * self.epem()
- self.e2em() * operand.m() * self.m()
+ self.e2ep() * operand.e1em() * self.e1ep()
- self.e2ep() * operand.e1ep() * self.e1em()
+ self.e2ep() * operand.e2em() * self.e2ep()
- self.e2ep() * operand.e2ep() * self.e2em()
+ self.e2ep() * operand.epem() * self.s()
- self.e2ep() * operand.m() * self.ps()
- self.epem() * operand.e1em() * self.ps()
- self.epem() * operand.e1ep() * self.m()
- self.epem() * operand.e2em() * self.epem()
- self.epem() * operand.e2ep() * self.s()
+ self.epem() * operand.epem() * self.e2em()
+ self.epem() * operand.m() * self.e1ep()
- self.m() * operand.e1em() * self.s()
- self.m() * operand.e1ep() * self.epem()
+ self.m() * operand.e2em() * self.m()
+ self.m() * operand.e2ep() * self.ps()
+ self.m() * operand.epem() * self.e1ep()
- self.m() * operand.m() * self.e2em()
- self.ps() * operand.e1em() * self.epem()
- self.ps() * operand.e1ep() * self.s()
+ self.ps() * operand.e2em() * self.ps()
+ self.ps() * operand.e2ep() * self.m()
+ self.ps() * operand.epem() * self.e1em()
- self.ps() * operand.m() * self.e2ep()
- self.s() * operand.e1em() * self.m()
- self.s() * operand.e1ep() * self.ps()
- self.s() * operand.e2em() * self.s()
- self.s() * operand.e2ep() * self.epem()
+ self.s() * operand.epem() * self.e2ep()
+ self.s() * operand.m() * self.e1em())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.epem() + self.e1em() * operand.e1ep() * self.s()
- self.e1em() * operand.e2em() * self.ps()
- self.e1em() * operand.e2ep() * self.m()
- self.e1em() * operand.epem() * self.e1em()
+ self.e1em() * operand.m() * self.e2ep()
- self.e1ep() * operand.e1em() * self.s()
- self.e1ep() * operand.e1ep() * self.epem()
+ self.e1ep() * operand.e2em() * self.m()
+ self.e1ep() * operand.e2ep() * self.ps()
+ self.e1ep() * operand.epem() * self.e1ep()
- self.e1ep() * operand.m() * self.e2em()
+ self.e2em() * operand.e1em() * self.ps()
+ self.e2em() * operand.e1ep() * self.m()
+ self.e2em() * operand.e2em() * self.epem()
+ self.e2em() * operand.e2ep() * self.s()
- self.e2em() * operand.epem() * self.e2em()
- self.e2em() * operand.m() * self.e1ep()
- self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.e1ep() * self.ps()
- self.e2ep() * operand.e2em() * self.s()
- self.e2ep() * operand.e2ep() * self.epem()
+ self.e2ep() * operand.epem() * self.e2ep()
+ self.e2ep() * operand.m() * self.e1em()
+ self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e1ep() * self.e1ep()
+ self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.e2ep() * self.e2ep()
+ self.epem() * operand.epem() * self.epem()
- self.epem() * operand.m() * self.m()
- self.m() * operand.e1em() * self.e2ep()
+ self.m() * operand.e1ep() * self.e2em()
+ self.m() * operand.e2em() * self.e1ep()
- self.m() * operand.e2ep() * self.e1em()
- self.m() * operand.epem() * self.m()
- self.m() * operand.m() * self.epem()
+ self.ps() * operand.e1em() * self.e2em()
- self.ps() * operand.e1ep() * self.e2ep()
- self.ps() * operand.e2em() * self.e1em()
+ self.ps() * operand.e2ep() * self.e1ep()
+ self.ps() * operand.epem() * self.ps()
+ self.ps() * operand.m() * self.s()
- self.s() * operand.e1em() * self.e1ep()
+ self.s() * operand.e1ep() * self.e1em()
- self.s() * operand.e2em() * self.e2ep()
+ self.s() * operand.e2ep() * self.e2em()
- self.s() * operand.epem() * self.s()
+ self.s() * operand.m() * self.ps())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Pseudoscalar<T>> for Motor<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Pseudoscalar<T>) -> Option<Pseudoscalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Pseudoscalar::new_unchecked(
(self.e1em() * operand.ps() * self.e1em() - self.e1ep() * operand.ps() * self.e1ep()
+ self.e2em() * operand.ps() * self.e2em()
- self.e2ep() * operand.ps() * self.e2ep()
+ self.epem() * operand.ps() * self.epem()
- self.m() * operand.ps() * self.m()
+ self.ps() * operand.ps() * self.ps()
- self.s() * operand.ps() * self.s())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<RoundPoint<T>> for Motor<T> {
type Output = RoundPoint<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &RoundPoint<T>) -> Option<RoundPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(RoundPoint::new_unchecked(
(self.e1em() * operand.em() * self.s()
+ self.e1em() * operand.ep() * self.epem()
+ self.e1em() * operand.x() * self.e1em()
+ self.e1em() * operand.y() * self.e2em()
- self.e1ep() * operand.em() * self.epem()
- self.e1ep() * operand.ep() * self.s()
- self.e1ep() * operand.x() * self.e1ep()
- self.e1ep() * operand.y() * self.e2ep()
- self.e2em() * operand.em() * self.m()
- self.e2em() * operand.ep() * self.ps()
- self.e2em() * operand.x() * self.e2em()
+ self.e2em() * operand.y() * self.e1em()
+ self.e2ep() * operand.em() * self.ps()
+ self.e2ep() * operand.ep() * self.m()
+ self.e2ep() * operand.x() * self.e2ep()
- self.e2ep() * operand.y() * self.e1ep()
- self.epem() * operand.em() * self.e1ep()
+ self.epem() * operand.ep() * self.e1em()
- self.epem() * operand.x() * self.epem()
+ self.epem() * operand.y() * self.ps()
- self.m() * operand.em() * self.e2em()
+ self.m() * operand.ep() * self.e2ep()
- self.m() * operand.x() * self.m()
- self.m() * operand.y() * self.s()
+ self.ps() * operand.em() * self.e2ep()
- self.ps() * operand.ep() * self.e2em()
+ self.ps() * operand.x() * self.ps()
+ self.ps() * operand.y() * self.epem()
+ self.s() * operand.em() * self.e1em()
- self.s() * operand.ep() * self.e1ep()
+ self.s() * operand.x() * self.s()
- self.s() * operand.y() * self.m())
* inv_norm_sq,
(self.e1em() * operand.em() * self.m()
+ self.e1em() * operand.ep() * self.ps()
+ self.e1em() * operand.x() * self.e2em()
- self.e1em() * operand.y() * self.e1em()
- self.e1ep() * operand.em() * self.ps()
- self.e1ep() * operand.ep() * self.m()
- self.e1ep() * operand.x() * self.e2ep()
+ self.e1ep() * operand.y() * self.e1ep()
+ self.e2em() * operand.em() * self.s()
+ self.e2em() * operand.ep() * self.epem()
+ self.e2em() * operand.x() * self.e1em()
+ self.e2em() * operand.y() * self.e2em()
- self.e2ep() * operand.em() * self.epem()
- self.e2ep() * operand.ep() * self.s()
- self.e2ep() * operand.x() * self.e1ep()
- self.e2ep() * operand.y() * self.e2ep()
- self.epem() * operand.em() * self.e2ep()
+ self.epem() * operand.ep() * self.e2em()
- self.epem() * operand.x() * self.ps()
- self.epem() * operand.y() * self.epem()
+ self.m() * operand.em() * self.e1em()
- self.m() * operand.ep() * self.e1ep()
+ self.m() * operand.x() * self.s()
- self.m() * operand.y() * self.m()
- self.ps() * operand.em() * self.e1ep()
+ self.ps() * operand.ep() * self.e1em()
- self.ps() * operand.x() * self.epem()
+ self.ps() * operand.y() * self.ps()
+ self.s() * operand.em() * self.e2em()
- self.s() * operand.ep() * self.e2ep()
+ self.s() * operand.x() * self.m()
+ self.s() * operand.y() * self.s())
* inv_norm_sq,
(self.e1em() * operand.em() * self.e1ep() - self.e1em() * operand.ep() * self.e1em()
+ self.e1em() * operand.x() * self.epem()
- self.e1em() * operand.y() * self.ps()
+ self.e1ep() * operand.em() * self.e1em()
- self.e1ep() * operand.ep() * self.e1ep()
+ self.e1ep() * operand.x() * self.s()
- self.e1ep() * operand.y() * self.m()
+ self.e2em() * operand.em() * self.e2ep()
- self.e2em() * operand.ep() * self.e2em()
+ self.e2em() * operand.x() * self.ps()
+ self.e2em() * operand.y() * self.epem()
+ self.e2ep() * operand.em() * self.e2em()
- self.e2ep() * operand.ep() * self.e2ep()
+ self.e2ep() * operand.x() * self.m()
+ self.e2ep() * operand.y() * self.s()
+ self.epem() * operand.em() * self.s()
+ self.epem() * operand.ep() * self.epem()
+ self.epem() * operand.x() * self.e1em()
+ self.epem() * operand.y() * self.e2em()
+ self.m() * operand.em() * self.ps()
+ self.m() * operand.ep() * self.m()
+ self.m() * operand.x() * self.e2ep()
- self.m() * operand.y() * self.e1ep()
+ self.ps() * operand.em() * self.m()
+ self.ps() * operand.ep() * self.ps()
+ self.ps() * operand.x() * self.e2em()
- self.ps() * operand.y() * self.e1em()
+ self.s() * operand.em() * self.epem()
+ self.s() * operand.ep() * self.s()
+ self.s() * operand.x() * self.e1ep()
+ self.s() * operand.y() * self.e2ep())
* inv_norm_sq,
(self.e1em() * operand.em() * self.e1em() - self.e1em() * operand.ep() * self.e1ep()
+ self.e1em() * operand.x() * self.s()
- self.e1em() * operand.y() * self.m()
+ self.e1ep() * operand.em() * self.e1ep()
- self.e1ep() * operand.ep() * self.e1em()
+ self.e1ep() * operand.x() * self.epem()
- self.e1ep() * operand.y() * self.ps()
+ self.e2em() * operand.em() * self.e2em()
- self.e2em() * operand.ep() * self.e2ep()
+ self.e2em() * operand.x() * self.m()
+ self.e2em() * operand.y() * self.s()
+ self.e2ep() * operand.em() * self.e2ep()
- self.e2ep() * operand.ep() * self.e2em()
+ self.e2ep() * operand.x() * self.ps()
+ self.e2ep() * operand.y() * self.epem()
+ self.epem() * operand.em() * self.epem()
+ self.epem() * operand.ep() * self.s()
+ self.epem() * operand.x() * self.e1ep()
+ self.epem() * operand.y() * self.e2ep()
+ self.m() * operand.em() * self.m()
+ self.m() * operand.ep() * self.ps()
+ self.m() * operand.x() * self.e2em()
- self.m() * operand.y() * self.e1em()
+ self.ps() * operand.em() * self.ps()
+ self.ps() * operand.ep() * self.m()
+ self.ps() * operand.x() * self.e2ep()
- self.ps() * operand.y() * self.e1ep()
+ self.s() * operand.em() * self.s()
+ self.s() * operand.ep() * self.epem()
+ self.s() * operand.x() * self.e1em()
+ self.s() * operand.y() * self.e2em())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Scalar<T>> for Motor<T> {
type Output = Scalar<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Scalar<T>) -> Option<Scalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Scalar::new_unchecked(
(self.e1em() * operand.s() * self.e1em() - self.e1ep() * operand.s() * self.e1ep()
+ self.e2em() * operand.s() * self.e2em()
- self.e2ep() * operand.s() * self.e2ep()
+ self.epem() * operand.s() * self.epem()
- self.m() * operand.s() * self.m()
+ self.ps() * operand.s() * self.ps()
- self.s() * operand.s() * self.s())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Circle<T>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Circle<T>) -> Option<Circle<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Circle::new_unchecked(
(-(self.e1em() * operand.e12em() * self.e1ep())
+ self.e1em() * operand.e1epem() * self.m()
+ self.e1em() * operand.w() * self.e1em()
- self.e1ep() * operand.e12em() * self.e1em()
+ self.e1ep() * operand.e2epem() * self.epem()
+ self.e1ep() * operand.w() * self.e1ep()
- self.e2em() * operand.e12em() * self.e2ep()
+ self.e2em() * operand.e2epem() * self.m()
+ self.e2em() * operand.w() * self.e2em()
- self.e2ep() * operand.e12em() * self.e2em()
- self.e2ep() * operand.e1epem() * self.epem()
+ self.e2ep() * operand.w() * self.e2ep()
- self.epem() * operand.e1epem() * self.e2ep()
+ self.epem() * operand.e2epem() * self.e1ep()
+ self.epem() * operand.w() * self.epem()
+ self.m() * operand.e1epem() * self.e1em()
+ self.m() * operand.e2epem() * self.e2em()
+ self.m() * operand.w() * self.m())
* inv_norm_sq,
(-(self.e1em() * operand.e12em() * self.e1em())
+ self.e1em() * operand.e2epem() * self.epem()
+ self.e1em() * operand.w() * self.e1ep()
- self.e1ep() * operand.e12em() * self.e1ep()
+ self.e1ep() * operand.e1epem() * self.m()
+ self.e1ep() * operand.w() * self.e1em()
- self.e2em() * operand.e12em() * self.e2em()
- self.e2em() * operand.e1epem() * self.epem()
+ self.e2em() * operand.w() * self.e2ep()
- self.e2ep() * operand.e12em() * self.e2ep()
+ self.e2ep() * operand.e2epem() * self.m()
+ self.e2ep() * operand.w() * self.e2em()
+ self.epem() * operand.e12em() * self.epem()
- self.epem() * operand.e1epem() * self.e2em()
+ self.epem() * operand.e2epem() * self.e1em()
+ self.m() * operand.e12em() * self.m()
+ self.m() * operand.e1epem() * self.e1ep()
+ self.m() * operand.e2epem() * self.e2ep())
* inv_norm_sq,
(-(self.e1em() * operand.e1epem() * self.e1em())
- self.e1em() * operand.e2epem() * self.e2em()
- self.e1em() * operand.w() * self.m()
+ self.e1ep() * operand.e12em() * self.m()
+ self.e1ep() * operand.e1epem() * self.e1ep()
+ self.e1ep() * operand.e2epem() * self.e2ep()
- self.e2em() * operand.e12em() * self.epem()
+ self.e2em() * operand.e1epem() * self.e2em()
- self.e2em() * operand.e2epem() * self.e1em()
- self.e2ep() * operand.e1epem() * self.e2ep()
+ self.e2ep() * operand.e2epem() * self.e1ep()
+ self.e2ep() * operand.w() * self.epem()
- self.epem() * operand.e12em() * self.e2em()
- self.epem() * operand.e1epem() * self.epem()
+ self.epem() * operand.w() * self.e2ep()
+ self.m() * operand.e12em() * self.e1ep()
- self.m() * operand.e1epem() * self.m()
- self.m() * operand.w() * self.e1em())
* inv_norm_sq,
(self.e1em() * operand.e12em() * self.epem()
- self.e1em() * operand.e1epem() * self.e2em()
+ self.e1em() * operand.e2epem() * self.e1em()
+ self.e1ep() * operand.e1epem() * self.e2ep()
- self.e1ep() * operand.e2epem() * self.e1ep()
- self.e1ep() * operand.w() * self.epem()
- self.e2em() * operand.e1epem() * self.e1em()
- self.e2em() * operand.e2epem() * self.e2em()
- self.e2em() * operand.w() * self.m()
+ self.e2ep() * operand.e12em() * self.m()
+ self.e2ep() * operand.e1epem() * self.e1ep()
+ self.e2ep() * operand.e2epem() * self.e2ep()
+ self.epem() * operand.e12em() * self.e1em()
- self.epem() * operand.e2epem() * self.epem()
- self.epem() * operand.w() * self.e1ep()
+ self.m() * operand.e12em() * self.e2ep()
- self.m() * operand.e2epem() * self.m()
- self.m() * operand.w() * self.e2em())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<FlatPoint<T>> for PointPair<T> {
type Output = FlatPoint<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &FlatPoint<T>) -> Option<FlatPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(FlatPoint::new_unchecked(
(self.e1em() * operand.e1em() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2em()
+ self.e1em() * operand.epem() * self.epem()
+ self.e1ep() * operand.e1em() * self.e1ep()
+ self.e1ep() * operand.e2em() * self.e2ep()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1em()
- self.e2ep() * operand.e1em() * self.e2ep()
+ self.e2ep() * operand.e2em() * self.e1ep()
- self.e2ep() * operand.epem() * self.m()
- self.epem() * operand.e1em() * self.epem()
+ self.epem() * operand.epem() * self.e1em()
+ self.m() * operand.e1em() * self.m()
- self.m() * operand.epem() * self.e2ep())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e2em()
- self.e1em() * operand.e2em() * self.e1em()
+ self.e1ep() * operand.e1em() * self.e2ep()
- self.e1ep() * operand.e2em() * self.e1ep()
+ self.e1ep() * operand.epem() * self.m()
+ self.e2em() * operand.e1em() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2em()
+ self.e2em() * operand.epem() * self.epem()
+ self.e2ep() * operand.e1em() * self.e1ep()
+ self.e2ep() * operand.e2em() * self.e2ep()
- self.epem() * operand.e2em() * self.epem()
+ self.epem() * operand.epem() * self.e2em()
+ self.m() * operand.e2em() * self.m()
+ self.m() * operand.epem() * self.e1ep())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.epem()
- self.e1em() * operand.epem() * self.e1em()
+ self.e1ep() * operand.e2em() * self.m()
+ self.e1ep() * operand.epem() * self.e1ep()
+ self.e2em() * operand.e2em() * self.epem()
- self.e2em() * operand.epem() * self.e2em()
- self.e2ep() * operand.e1em() * self.m()
+ self.e2ep() * operand.epem() * self.e2ep()
+ self.epem() * operand.e1em() * self.e1em()
+ self.epem() * operand.e2em() * self.e2em()
+ self.epem() * operand.epem() * self.epem()
- self.m() * operand.e1em() * self.e2ep()
+ self.m() * operand.e2em() * self.e1ep()
- self.m() * operand.epem() * self.m())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Line<T>> for PointPair<T> {
type Output = Line<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Line<T>) -> Option<Line<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Line::new_unchecked(
(self.e1em() * operand.d() * self.epem()
- self.e1em() * operand.nx() * self.e1em()
- self.e1ep() * operand.nx() * self.e1ep()
+ self.e1ep() * operand.ny() * self.m()
- self.e2em() * operand.nx() * self.e2em()
- self.e2em() * operand.ny() * self.epem()
+ self.e2ep() * operand.d() * self.m()
- self.e2ep() * operand.nx() * self.e2ep()
+ self.epem() * operand.d() * self.e1em()
+ self.epem() * operand.nx() * self.epem()
- self.epem() * operand.ny() * self.e2em()
+ self.m() * operand.d() * self.e2ep()
+ self.m() * operand.nx() * self.m()
+ self.m() * operand.ny() * self.e1ep())
* inv_norm_sq,
(-(self.e1em() * operand.d() * self.e2em()) - self.e1em() * operand.ny() * self.e1em()
+ self.e1ep() * operand.d() * self.e2ep()
+ self.e1ep() * operand.nx() * self.m()
+ self.e1ep() * operand.ny() * self.e1ep()
- self.e2em() * operand.d() * self.e1em()
- self.e2em() * operand.nx() * self.epem()
+ self.e2em() * operand.ny() * self.e2em()
+ self.e2ep() * operand.d() * self.e1ep()
- self.e2ep() * operand.ny() * self.e2ep()
- self.epem() * operand.nx() * self.e2em()
- self.epem() * operand.ny() * self.epem()
+ self.m() * operand.nx() * self.e1ep()
- self.m() * operand.ny() * self.m())
* inv_norm_sq,
(self.e1em() * operand.d() * self.e1em() + self.e1em() * operand.nx() * self.epem()
- self.e1em() * operand.ny() * self.e2em()
- self.e1ep() * operand.d() * self.e1ep()
+ self.e1ep() * operand.ny() * self.e2ep()
- self.e2em() * operand.d() * self.e2em()
- self.e2em() * operand.ny() * self.e1em()
+ self.e2ep() * operand.d() * self.e2ep()
+ self.e2ep() * operand.nx() * self.m()
+ self.e2ep() * operand.ny() * self.e1ep()
- self.epem() * operand.d() * self.epem()
+ self.epem() * operand.nx() * self.e1em()
- self.m() * operand.d() * self.m()
+ self.m() * operand.nx() * self.e2ep())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Motor<T>> for PointPair<T> {
type Output = Motor<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Motor<T>) -> Option<Motor<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Motor::new_unchecked(
(-(self.e1em() * operand.e1ep() * self.epem())
+ self.e1em() * operand.e2em() * self.m()
+ self.e1em() * operand.epem() * self.e1ep()
- self.e1em() * operand.m() * self.e2em()
- self.e1em() * operand.ps() * self.e2ep()
+ self.e1em() * operand.s() * self.e1em()
+ self.e1ep() * operand.e1em() * self.epem()
- self.e1ep() * operand.e2ep() * self.m()
- self.e1ep() * operand.epem() * self.e1em()
+ self.e1ep() * operand.m() * self.e2ep()
+ self.e1ep() * operand.ps() * self.e2em()
- self.e1ep() * operand.s() * self.e1ep()
- self.e2em() * operand.e1em() * self.m()
- self.e2em() * operand.e2ep() * self.epem()
+ self.e2em() * operand.epem() * self.e2ep()
+ self.e2em() * operand.m() * self.e1em()
+ self.e2em() * operand.ps() * self.e1ep()
+ self.e2em() * operand.s() * self.e2em()
+ self.e2ep() * operand.e1ep() * self.m()
+ self.e2ep() * operand.e2em() * self.epem()
- self.e2ep() * operand.epem() * self.e2em()
- self.e2ep() * operand.m() * self.e1ep()
- self.e2ep() * operand.ps() * self.e1em()
- self.e2ep() * operand.s() * self.e2ep()
- self.epem() * operand.e1em() * self.e1ep()
+ self.epem() * operand.e1ep() * self.e1em()
- self.epem() * operand.e2em() * self.e2ep()
+ self.epem() * operand.e2ep() * self.e2em()
- self.epem() * operand.ps() * self.m()
+ self.epem() * operand.s() * self.epem()
+ self.m() * operand.e1em() * self.e2em()
- self.m() * operand.e1ep() * self.e2ep()
- self.m() * operand.e2em() * self.e1em()
+ self.m() * operand.e2ep() * self.e1ep()
- self.m() * operand.ps() * self.epem()
- self.m() * operand.s() * self.m())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.m() + self.e1em() * operand.e2ep() * self.epem()
- self.e1em() * operand.epem() * self.e2ep()
- self.e1em() * operand.m() * self.e1em()
- self.e1em() * operand.ps() * self.e1ep()
- self.e1em() * operand.s() * self.e2em()
- self.e1ep() * operand.e1ep() * self.m()
- self.e1ep() * operand.e2em() * self.epem()
+ self.e1ep() * operand.epem() * self.e2em()
+ self.e1ep() * operand.m() * self.e1ep()
+ self.e1ep() * operand.ps() * self.e1em()
+ self.e1ep() * operand.s() * self.e2ep()
- self.e2em() * operand.e1ep() * self.epem()
+ self.e2em() * operand.e2em() * self.m()
+ self.e2em() * operand.epem() * self.e1ep()
- self.e2em() * operand.m() * self.e2em()
- self.e2em() * operand.ps() * self.e2ep()
+ self.e2em() * operand.s() * self.e1em()
+ self.e2ep() * operand.e1em() * self.epem()
- self.e2ep() * operand.e2ep() * self.m()
- self.e2ep() * operand.epem() * self.e1em()
+ self.e2ep() * operand.m() * self.e2ep()
+ self.e2ep() * operand.ps() * self.e2em()
- self.e2ep() * operand.s() * self.e1ep()
+ self.epem() * operand.e1em() * self.e2ep()
- self.epem() * operand.e1ep() * self.e2em()
- self.epem() * operand.e2em() * self.e1ep()
+ self.epem() * operand.e2ep() * self.e1em()
+ self.epem() * operand.epem() * self.m()
+ self.epem() * operand.m() * self.epem()
+ self.m() * operand.e1em() * self.e1em()
- self.m() * operand.e1ep() * self.e1ep()
+ self.m() * operand.e2em() * self.e2em()
- self.m() * operand.e2ep() * self.e2ep()
+ self.m() * operand.epem() * self.epem()
- self.m() * operand.m() * self.m())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e1ep()
- self.e1em() * operand.e1ep() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2ep()
- self.e1em() * operand.e2ep() * self.e2em()
+ self.e1em() * operand.ps() * self.m()
- self.e1em() * operand.s() * self.epem()
+ self.e1ep() * operand.e1em() * self.e1em()
- self.e1ep() * operand.e1ep() * self.e1ep()
+ self.e1ep() * operand.e2em() * self.e2em()
- self.e1ep() * operand.e2ep() * self.e2ep()
+ self.e1ep() * operand.epem() * self.epem()
- self.e1ep() * operand.m() * self.m()
- self.e2em() * operand.e1em() * self.e2ep()
+ self.e2em() * operand.e1ep() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1ep()
- self.e2em() * operand.e2ep() * self.e1em()
- self.e2em() * operand.epem() * self.m()
- self.e2em() * operand.m() * self.epem()
- self.e2ep() * operand.e1em() * self.e2em()
+ self.e2ep() * operand.e1ep() * self.e2ep()
+ self.e2ep() * operand.e2em() * self.e1em()
- self.e2ep() * operand.e2ep() * self.e1ep()
+ self.e2ep() * operand.ps() * self.epem()
+ self.e2ep() * operand.s() * self.m()
- self.epem() * operand.e1ep() * self.epem()
+ self.epem() * operand.e2em() * self.m()
+ self.epem() * operand.epem() * self.e1ep()
- self.epem() * operand.m() * self.e2em()
- self.epem() * operand.ps() * self.e2ep()
+ self.epem() * operand.s() * self.e1em()
+ self.m() * operand.e1ep() * self.m()
+ self.m() * operand.e2em() * self.epem()
- self.m() * operand.epem() * self.e2em()
- self.m() * operand.m() * self.e1ep()
- self.m() * operand.ps() * self.e1em()
- self.m() * operand.s() * self.e2ep())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e2ep()
- self.e1em() * operand.e1ep() * self.e2em()
- self.e1em() * operand.e2em() * self.e1ep()
+ self.e1em() * operand.e2ep() * self.e1em()
+ self.e1em() * operand.epem() * self.m()
+ self.e1em() * operand.m() * self.epem()
+ self.e1ep() * operand.e1em() * self.e2em()
- self.e1ep() * operand.e1ep() * self.e2ep()
- self.e1ep() * operand.e2em() * self.e1em()
+ self.e1ep() * operand.e2ep() * self.e1ep()
- self.e1ep() * operand.ps() * self.epem()
- self.e1ep() * operand.s() * self.m()
+ self.e2em() * operand.e1em() * self.e1ep()
- self.e2em() * operand.e1ep() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2ep()
- self.e2em() * operand.e2ep() * self.e2em()
+ self.e2em() * operand.ps() * self.m()
- self.e2em() * operand.s() * self.epem()
+ self.e2ep() * operand.e1em() * self.e1em()
- self.e2ep() * operand.e1ep() * self.e1ep()
+ self.e2ep() * operand.e2em() * self.e2em()
- self.e2ep() * operand.e2ep() * self.e2ep()
+ self.e2ep() * operand.epem() * self.epem()
- self.e2ep() * operand.m() * self.m()
- self.epem() * operand.e1em() * self.m()
- self.epem() * operand.e2ep() * self.epem()
+ self.epem() * operand.epem() * self.e2ep()
+ self.epem() * operand.m() * self.e1em()
+ self.epem() * operand.ps() * self.e1ep()
+ self.epem() * operand.s() * self.e2em()
- self.m() * operand.e1em() * self.epem()
+ self.m() * operand.e2ep() * self.m()
+ self.m() * operand.epem() * self.e1em()
- self.m() * operand.m() * self.e2ep()
- self.m() * operand.ps() * self.e2em()
+ self.m() * operand.s() * self.e1ep())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e1em()
- self.e1em() * operand.e1ep() * self.e1ep()
+ self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.e2ep() * self.e2ep()
+ self.e1em() * operand.epem() * self.epem()
- self.e1em() * operand.m() * self.m()
+ self.e1ep() * operand.e1em() * self.e1ep()
- self.e1ep() * operand.e1ep() * self.e1em()
+ self.e1ep() * operand.e2em() * self.e2ep()
- self.e1ep() * operand.e2ep() * self.e2em()
+ self.e1ep() * operand.ps() * self.m()
- self.e1ep() * operand.s() * self.epem()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e1ep() * self.e2ep()
+ self.e2em() * operand.e2em() * self.e1em()
- self.e2em() * operand.e2ep() * self.e1ep()
+ self.e2em() * operand.ps() * self.epem()
+ self.e2em() * operand.s() * self.m()
- self.e2ep() * operand.e1em() * self.e2ep()
+ self.e2ep() * operand.e1ep() * self.e2em()
+ self.e2ep() * operand.e2em() * self.e1ep()
- self.e2ep() * operand.e2ep() * self.e1em()
- self.e2ep() * operand.epem() * self.m()
- self.e2ep() * operand.m() * self.epem()
- self.epem() * operand.e1em() * self.epem()
+ self.epem() * operand.e2ep() * self.m()
+ self.epem() * operand.epem() * self.e1em()
- self.epem() * operand.m() * self.e2ep()
- self.epem() * operand.ps() * self.e2em()
+ self.epem() * operand.s() * self.e1ep()
+ self.m() * operand.e1em() * self.m()
+ self.m() * operand.e2ep() * self.epem()
- self.m() * operand.epem() * self.e2ep()
- self.m() * operand.m() * self.e1em()
- self.m() * operand.ps() * self.e1ep()
- self.m() * operand.s() * self.e2em())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e2em()
- self.e1em() * operand.e1ep() * self.e2ep()
- self.e1em() * operand.e2em() * self.e1em()
+ self.e1em() * operand.e2ep() * self.e1ep()
- self.e1em() * operand.ps() * self.epem()
- self.e1em() * operand.s() * self.m()
+ self.e1ep() * operand.e1em() * self.e2ep()
- self.e1ep() * operand.e1ep() * self.e2em()
- self.e1ep() * operand.e2em() * self.e1ep()
+ self.e1ep() * operand.e2ep() * self.e1em()
+ self.e1ep() * operand.epem() * self.m()
+ self.e1ep() * operand.m() * self.epem()
+ self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e1ep() * self.e1ep()
+ self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.e2ep() * self.e2ep()
+ self.e2em() * operand.epem() * self.epem()
- self.e2em() * operand.m() * self.m()
+ self.e2ep() * operand.e1em() * self.e1ep()
- self.e2ep() * operand.e1ep() * self.e1em()
+ self.e2ep() * operand.e2em() * self.e2ep()
- self.e2ep() * operand.e2ep() * self.e2em()
+ self.e2ep() * operand.ps() * self.m()
- self.e2ep() * operand.s() * self.epem()
- self.epem() * operand.e1ep() * self.m()
- self.epem() * operand.e2em() * self.epem()
+ self.epem() * operand.epem() * self.e2em()
+ self.epem() * operand.m() * self.e1ep()
+ self.epem() * operand.ps() * self.e1em()
+ self.epem() * operand.s() * self.e2ep()
- self.m() * operand.e1ep() * self.epem()
+ self.m() * operand.e2em() * self.m()
+ self.m() * operand.epem() * self.e1ep()
- self.m() * operand.m() * self.e2em()
- self.m() * operand.ps() * self.e2ep()
+ self.m() * operand.s() * self.e1em())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.epem()
- self.e1em() * operand.e2ep() * self.m()
- self.e1em() * operand.epem() * self.e1em()
+ self.e1em() * operand.m() * self.e2ep()
+ self.e1em() * operand.ps() * self.e2em()
- self.e1em() * operand.s() * self.e1ep()
- self.e1ep() * operand.e1ep() * self.epem()
+ self.e1ep() * operand.e2em() * self.m()
+ self.e1ep() * operand.epem() * self.e1ep()
- self.e1ep() * operand.m() * self.e2em()
- self.e1ep() * operand.ps() * self.e2ep()
+ self.e1ep() * operand.s() * self.e1em()
+ self.e2em() * operand.e1ep() * self.m()
+ self.e2em() * operand.e2em() * self.epem()
- self.e2em() * operand.epem() * self.e2em()
- self.e2em() * operand.m() * self.e1ep()
- self.e2em() * operand.ps() * self.e1em()
- self.e2em() * operand.s() * self.e2ep()
- self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.e2ep() * self.epem()
+ self.e2ep() * operand.epem() * self.e2ep()
+ self.e2ep() * operand.m() * self.e1em()
+ self.e2ep() * operand.ps() * self.e1ep()
+ self.e2ep() * operand.s() * self.e2em()
+ self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e1ep() * self.e1ep()
+ self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.e2ep() * self.e2ep()
+ self.epem() * operand.epem() * self.epem()
- self.epem() * operand.m() * self.m()
- self.m() * operand.e1em() * self.e2ep()
+ self.m() * operand.e1ep() * self.e2em()
+ self.m() * operand.e2em() * self.e1ep()
- self.m() * operand.e2ep() * self.e1em()
- self.m() * operand.epem() * self.m()
- self.m() * operand.m() * self.epem())
* inv_norm_sq,
(-(self.e1em() * operand.e1ep() * self.m())
- self.e1em() * operand.e2em() * self.epem()
+ self.e1em() * operand.epem() * self.e2em()
+ self.e1em() * operand.m() * self.e1ep()
+ self.e1em() * operand.ps() * self.e1em()
+ self.e1em() * operand.s() * self.e2ep()
+ self.e1ep() * operand.e1em() * self.m()
+ self.e1ep() * operand.e2ep() * self.epem()
- self.e1ep() * operand.epem() * self.e2ep()
- self.e1ep() * operand.m() * self.e1em()
- self.e1ep() * operand.ps() * self.e1ep()
- self.e1ep() * operand.s() * self.e2em()
+ self.e2em() * operand.e1em() * self.epem()
- self.e2em() * operand.e2ep() * self.m()
- self.e2em() * operand.epem() * self.e1em()
+ self.e2em() * operand.m() * self.e2ep()
+ self.e2em() * operand.ps() * self.e2em()
- self.e2em() * operand.s() * self.e1ep()
- self.e2ep() * operand.e1ep() * self.epem()
+ self.e2ep() * operand.e2em() * self.m()
+ self.e2ep() * operand.epem() * self.e1ep()
- self.e2ep() * operand.m() * self.e2em()
- self.e2ep() * operand.ps() * self.e2ep()
+ self.e2ep() * operand.s() * self.e1em()
- self.epem() * operand.e1em() * self.e2em()
+ self.epem() * operand.e1ep() * self.e2ep()
+ self.epem() * operand.e2em() * self.e1em()
- self.epem() * operand.e2ep() * self.e1ep()
+ self.epem() * operand.ps() * self.epem()
+ self.epem() * operand.s() * self.m()
- self.m() * operand.e1em() * self.e1ep()
+ self.m() * operand.e1ep() * self.e1em()
- self.m() * operand.e2em() * self.e2ep()
+ self.m() * operand.e2ep() * self.e2em()
- self.m() * operand.ps() * self.m()
+ self.m() * operand.s() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<PointPair<T>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &PointPair<T>) -> Option<PointPair<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(PointPair::new_unchecked(
(self.e1em() * operand.e1em() * self.m() + self.e1em() * operand.e2ep() * self.epem()
- self.e1em() * operand.epem() * self.e2ep()
- self.e1em() * operand.m() * self.e1em()
- self.e1ep() * operand.e1ep() * self.m()
- self.e1ep() * operand.e2em() * self.epem()
+ self.e1ep() * operand.epem() * self.e2em()
+ self.e1ep() * operand.m() * self.e1ep()
- self.e2em() * operand.e1ep() * self.epem()
+ self.e2em() * operand.e2em() * self.m()
+ self.e2em() * operand.epem() * self.e1ep()
- self.e2em() * operand.m() * self.e2em()
+ self.e2ep() * operand.e1em() * self.epem()
- self.e2ep() * operand.e2ep() * self.m()
- self.e2ep() * operand.epem() * self.e1em()
+ self.e2ep() * operand.m() * self.e2ep()
+ self.epem() * operand.e1em() * self.e2ep()
- self.epem() * operand.e1ep() * self.e2em()
- self.epem() * operand.e2em() * self.e1ep()
+ self.epem() * operand.e2ep() * self.e1em()
+ self.epem() * operand.epem() * self.m()
+ self.epem() * operand.m() * self.epem()
+ self.m() * operand.e1em() * self.e1em()
- self.m() * operand.e1ep() * self.e1ep()
+ self.m() * operand.e2em() * self.e2em()
- self.m() * operand.e2ep() * self.e2ep()
+ self.m() * operand.epem() * self.epem()
- self.m() * operand.m() * self.m())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e1ep()
- self.e1em() * operand.e1ep() * self.e1em()
+ self.e1em() * operand.e2em() * self.e2ep()
- self.e1em() * operand.e2ep() * self.e2em()
+ self.e1ep() * operand.e1em() * self.e1em()
- self.e1ep() * operand.e1ep() * self.e1ep()
+ self.e1ep() * operand.e2em() * self.e2em()
- self.e1ep() * operand.e2ep() * self.e2ep()
+ self.e1ep() * operand.epem() * self.epem()
- self.e1ep() * operand.m() * self.m()
- self.e2em() * operand.e1em() * self.e2ep()
+ self.e2em() * operand.e1ep() * self.e2em()
+ self.e2em() * operand.e2em() * self.e1ep()
- self.e2em() * operand.e2ep() * self.e1em()
- self.e2em() * operand.epem() * self.m()
- self.e2em() * operand.m() * self.epem()
- self.e2ep() * operand.e1em() * self.e2em()
+ self.e2ep() * operand.e1ep() * self.e2ep()
+ self.e2ep() * operand.e2em() * self.e1em()
- self.e2ep() * operand.e2ep() * self.e1ep()
- self.epem() * operand.e1ep() * self.epem()
+ self.epem() * operand.e2em() * self.m()
+ self.epem() * operand.epem() * self.e1ep()
- self.epem() * operand.m() * self.e2em()
+ self.m() * operand.e1ep() * self.m()
+ self.m() * operand.e2em() * self.epem()
- self.m() * operand.epem() * self.e2em()
- self.m() * operand.m() * self.e1ep())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e2ep()
- self.e1em() * operand.e1ep() * self.e2em()
- self.e1em() * operand.e2em() * self.e1ep()
+ self.e1em() * operand.e2ep() * self.e1em()
+ self.e1em() * operand.epem() * self.m()
+ self.e1em() * operand.m() * self.epem()
+ self.e1ep() * operand.e1em() * self.e2em()
- self.e1ep() * operand.e1ep() * self.e2ep()
- self.e1ep() * operand.e2em() * self.e1em()
+ self.e1ep() * operand.e2ep() * self.e1ep()
+ self.e2em() * operand.e1em() * self.e1ep()
- self.e2em() * operand.e1ep() * self.e1em()
+ self.e2em() * operand.e2em() * self.e2ep()
- self.e2em() * operand.e2ep() * self.e2em()
+ self.e2ep() * operand.e1em() * self.e1em()
- self.e2ep() * operand.e1ep() * self.e1ep()
+ self.e2ep() * operand.e2em() * self.e2em()
- self.e2ep() * operand.e2ep() * self.e2ep()
+ self.e2ep() * operand.epem() * self.epem()
- self.e2ep() * operand.m() * self.m()
- self.epem() * operand.e1em() * self.m()
- self.epem() * operand.e2ep() * self.epem()
+ self.epem() * operand.epem() * self.e2ep()
+ self.epem() * operand.m() * self.e1em()
- self.m() * operand.e1em() * self.epem()
+ self.m() * operand.e2ep() * self.m()
+ self.m() * operand.epem() * self.e1em()
- self.m() * operand.m() * self.e2ep())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e1em()
- self.e1em() * operand.e1ep() * self.e1ep()
+ self.e1em() * operand.e2em() * self.e2em()
- self.e1em() * operand.e2ep() * self.e2ep()
+ self.e1em() * operand.epem() * self.epem()
- self.e1em() * operand.m() * self.m()
+ self.e1ep() * operand.e1em() * self.e1ep()
- self.e1ep() * operand.e1ep() * self.e1em()
+ self.e1ep() * operand.e2em() * self.e2ep()
- self.e1ep() * operand.e2ep() * self.e2em()
- self.e2em() * operand.e1em() * self.e2em()
+ self.e2em() * operand.e1ep() * self.e2ep()
+ self.e2em() * operand.e2em() * self.e1em()
- self.e2em() * operand.e2ep() * self.e1ep()
- self.e2ep() * operand.e1em() * self.e2ep()
+ self.e2ep() * operand.e1ep() * self.e2em()
+ self.e2ep() * operand.e2em() * self.e1ep()
- self.e2ep() * operand.e2ep() * self.e1em()
- self.e2ep() * operand.epem() * self.m()
- self.e2ep() * operand.m() * self.epem()
- self.epem() * operand.e1em() * self.epem()
+ self.epem() * operand.e2ep() * self.m()
+ self.epem() * operand.epem() * self.e1em()
- self.epem() * operand.m() * self.e2ep()
+ self.m() * operand.e1em() * self.m()
+ self.m() * operand.e2ep() * self.epem()
- self.m() * operand.epem() * self.e2ep()
- self.m() * operand.m() * self.e1em())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.e2em()
- self.e1em() * operand.e1ep() * self.e2ep()
- self.e1em() * operand.e2em() * self.e1em()
+ self.e1em() * operand.e2ep() * self.e1ep()
+ self.e1ep() * operand.e1em() * self.e2ep()
- self.e1ep() * operand.e1ep() * self.e2em()
- self.e1ep() * operand.e2em() * self.e1ep()
+ self.e1ep() * operand.e2ep() * self.e1em()
+ self.e1ep() * operand.epem() * self.m()
+ self.e1ep() * operand.m() * self.epem()
+ self.e2em() * operand.e1em() * self.e1em()
- self.e2em() * operand.e1ep() * self.e1ep()
+ self.e2em() * operand.e2em() * self.e2em()
- self.e2em() * operand.e2ep() * self.e2ep()
+ self.e2em() * operand.epem() * self.epem()
- self.e2em() * operand.m() * self.m()
+ self.e2ep() * operand.e1em() * self.e1ep()
- self.e2ep() * operand.e1ep() * self.e1em()
+ self.e2ep() * operand.e2em() * self.e2ep()
- self.e2ep() * operand.e2ep() * self.e2em()
- self.epem() * operand.e1ep() * self.m()
- self.epem() * operand.e2em() * self.epem()
+ self.epem() * operand.epem() * self.e2em()
+ self.epem() * operand.m() * self.e1ep()
- self.m() * operand.e1ep() * self.epem()
+ self.m() * operand.e2em() * self.m()
+ self.m() * operand.epem() * self.e1ep()
- self.m() * operand.m() * self.e2em())
* inv_norm_sq,
(self.e1em() * operand.e1em() * self.epem()
- self.e1em() * operand.e2ep() * self.m()
- self.e1em() * operand.epem() * self.e1em()
+ self.e1em() * operand.m() * self.e2ep()
- self.e1ep() * operand.e1ep() * self.epem()
+ self.e1ep() * operand.e2em() * self.m()
+ self.e1ep() * operand.epem() * self.e1ep()
- self.e1ep() * operand.m() * self.e2em()
+ self.e2em() * operand.e1ep() * self.m()
+ self.e2em() * operand.e2em() * self.epem()
- self.e2em() * operand.epem() * self.e2em()
- self.e2em() * operand.m() * self.e1ep()
- self.e2ep() * operand.e1em() * self.m()
- self.e2ep() * operand.e2ep() * self.epem()
+ self.e2ep() * operand.epem() * self.e2ep()
+ self.e2ep() * operand.m() * self.e1em()
+ self.epem() * operand.e1em() * self.e1em()
- self.epem() * operand.e1ep() * self.e1ep()
+ self.epem() * operand.e2em() * self.e2em()
- self.epem() * operand.e2ep() * self.e2ep()
+ self.epem() * operand.epem() * self.epem()
- self.epem() * operand.m() * self.m()
- self.m() * operand.e1em() * self.e2ep()
+ self.m() * operand.e1ep() * self.e2em()
+ self.m() * operand.e2em() * self.e1ep()
- self.m() * operand.e2ep() * self.e1em()
- self.m() * operand.epem() * self.m()
- self.m() * operand.m() * self.epem())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Pseudoscalar<T>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Pseudoscalar<T>) -> Option<Pseudoscalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Pseudoscalar::new_unchecked(
(self.e1em() * operand.ps() * self.e1em() - self.e1ep() * operand.ps() * self.e1ep()
+ self.e2em() * operand.ps() * self.e2em()
- self.e2ep() * operand.ps() * self.e2ep()
+ self.epem() * operand.ps() * self.epem()
- self.m() * operand.ps() * self.m())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<RoundPoint<T>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &RoundPoint<T>) -> Option<RoundPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(RoundPoint::new_unchecked(
(self.e1em() * operand.ep() * self.epem()
+ self.e1em() * operand.x() * self.e1em()
+ self.e1em() * operand.y() * self.e2em()
- self.e1ep() * operand.em() * self.epem()
- self.e1ep() * operand.x() * self.e1ep()
- self.e1ep() * operand.y() * self.e2ep()
- self.e2em() * operand.em() * self.m()
- self.e2em() * operand.x() * self.e2em()
+ self.e2em() * operand.y() * self.e1em()
+ self.e2ep() * operand.ep() * self.m()
+ self.e2ep() * operand.x() * self.e2ep()
- self.e2ep() * operand.y() * self.e1ep()
- self.epem() * operand.em() * self.e1ep()
+ self.epem() * operand.ep() * self.e1em()
- self.epem() * operand.x() * self.epem()
- self.m() * operand.em() * self.e2em()
+ self.m() * operand.ep() * self.e2ep()
- self.m() * operand.x() * self.m())
* inv_norm_sq,
(self.e1em() * operand.em() * self.m() + self.e1em() * operand.x() * self.e2em()
- self.e1em() * operand.y() * self.e1em()
- self.e1ep() * operand.ep() * self.m()
- self.e1ep() * operand.x() * self.e2ep()
+ self.e1ep() * operand.y() * self.e1ep()
+ self.e2em() * operand.ep() * self.epem()
+ self.e2em() * operand.x() * self.e1em()
+ self.e2em() * operand.y() * self.e2em()
- self.e2ep() * operand.em() * self.epem()
- self.e2ep() * operand.x() * self.e1ep()
- self.e2ep() * operand.y() * self.e2ep()
- self.epem() * operand.em() * self.e2ep()
+ self.epem() * operand.ep() * self.e2em()
- self.epem() * operand.y() * self.epem()
+ self.m() * operand.em() * self.e1em()
- self.m() * operand.ep() * self.e1ep()
- self.m() * operand.y() * self.m())
* inv_norm_sq,
(self.e1em() * operand.em() * self.e1ep() - self.e1em() * operand.ep() * self.e1em()
+ self.e1em() * operand.x() * self.epem()
+ self.e1ep() * operand.em() * self.e1em()
- self.e1ep() * operand.ep() * self.e1ep()
- self.e1ep() * operand.y() * self.m()
+ self.e2em() * operand.em() * self.e2ep()
- self.e2em() * operand.ep() * self.e2em()
+ self.e2em() * operand.y() * self.epem()
+ self.e2ep() * operand.em() * self.e2em()
- self.e2ep() * operand.ep() * self.e2ep()
+ self.e2ep() * operand.x() * self.m()
+ self.epem() * operand.ep() * self.epem()
+ self.epem() * operand.x() * self.e1em()
+ self.epem() * operand.y() * self.e2em()
+ self.m() * operand.ep() * self.m()
+ self.m() * operand.x() * self.e2ep()
- self.m() * operand.y() * self.e1ep())
* inv_norm_sq,
(self.e1em() * operand.em() * self.e1em()
- self.e1em() * operand.ep() * self.e1ep()
- self.e1em() * operand.y() * self.m()
+ self.e1ep() * operand.em() * self.e1ep()
- self.e1ep() * operand.ep() * self.e1em()
+ self.e1ep() * operand.x() * self.epem()
+ self.e2em() * operand.em() * self.e2em()
- self.e2em() * operand.ep() * self.e2ep()
+ self.e2em() * operand.x() * self.m()
+ self.e2ep() * operand.em() * self.e2ep()
- self.e2ep() * operand.ep() * self.e2em()
+ self.e2ep() * operand.y() * self.epem()
+ self.epem() * operand.em() * self.epem()
+ self.epem() * operand.x() * self.e1ep()
+ self.epem() * operand.y() * self.e2ep()
+ self.m() * operand.em() * self.m()
+ self.m() * operand.x() * self.e2em()
- self.m() * operand.y() * self.e1em())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Scalar<T>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Scalar<T>) -> Option<Scalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Scalar::new_unchecked(
(self.e1em() * operand.s() * self.e1em() - self.e1ep() * operand.s() * self.e1ep()
+ self.e2em() * operand.s() * self.e2em()
- self.e2ep() * operand.s() * self.e2ep()
+ self.epem() * operand.s() * self.epem()
- self.m() * operand.s() * self.m())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Circle<T>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Circle<T>) -> Option<Circle<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Circle::new_unchecked(
(self.ps() * operand.w() * self.ps()) * inv_norm_sq,
(self.ps() * operand.e12em() * self.ps()) * inv_norm_sq,
(self.ps() * operand.e1epem() * self.ps()) * inv_norm_sq,
(self.ps() * operand.e2epem() * self.ps()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<FlatPoint<T>> for Pseudoscalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &FlatPoint<T>) -> Option<FlatPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(FlatPoint::new_unchecked(
(self.ps() * operand.e1em() * self.ps()) * inv_norm_sq,
(self.ps() * operand.e2em() * self.ps()) * inv_norm_sq,
(self.ps() * operand.epem() * self.ps()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Line<T>> for Pseudoscalar<T> {
type Output = Line<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Line<T>) -> Option<Line<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Line::new_unchecked(
(self.ps() * operand.nx() * self.ps()) * inv_norm_sq,
(self.ps() * operand.ny() * self.ps()) * inv_norm_sq,
(self.ps() * operand.d() * self.ps()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Motor<T>> for Pseudoscalar<T> {
type Output = Motor<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Motor<T>) -> Option<Motor<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Motor::new_unchecked(
(self.ps() * operand.s() * self.ps()) * inv_norm_sq,
(self.ps() * operand.m() * self.ps()) * inv_norm_sq,
(self.ps() * operand.e1ep() * self.ps()) * inv_norm_sq,
(self.ps() * operand.e2ep() * self.ps()) * inv_norm_sq,
(self.ps() * operand.e1em() * self.ps()) * inv_norm_sq,
(self.ps() * operand.e2em() * self.ps()) * inv_norm_sq,
(self.ps() * operand.epem() * self.ps()) * inv_norm_sq,
(self.ps() * operand.ps() * self.ps()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<PointPair<T>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &PointPair<T>) -> Option<PointPair<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(PointPair::new_unchecked(
(self.ps() * operand.m() * self.ps()) * inv_norm_sq,
(self.ps() * operand.e1ep() * self.ps()) * inv_norm_sq,
(self.ps() * operand.e2ep() * self.ps()) * inv_norm_sq,
(self.ps() * operand.e1em() * self.ps()) * inv_norm_sq,
(self.ps() * operand.e2em() * self.ps()) * inv_norm_sq,
(self.ps() * operand.epem() * self.ps()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Pseudoscalar<T>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Pseudoscalar<T>) -> Option<Pseudoscalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Pseudoscalar::new_unchecked(
(self.ps() * operand.ps() * self.ps()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<RoundPoint<T>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &RoundPoint<T>) -> Option<RoundPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(RoundPoint::new_unchecked(
(self.ps() * operand.x() * self.ps()) * inv_norm_sq,
(self.ps() * operand.y() * self.ps()) * inv_norm_sq,
(self.ps() * operand.ep() * self.ps()) * inv_norm_sq,
(self.ps() * operand.em() * self.ps()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Scalar<T>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Scalar<T>) -> Option<Scalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Scalar::new_unchecked(
(self.ps() * operand.s() * self.ps()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Circle<T>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Circle<T>) -> Option<Circle<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Circle::new_unchecked(
(-(self.em() * operand.e12em() * self.ep()) + self.em() * operand.e1epem() * self.y()
- self.em() * operand.e2epem() * self.x()
+ self.em() * operand.w() * self.em()
- self.ep() * operand.e12em() * self.em()
+ self.ep() * operand.w() * self.ep()
- self.x() * operand.e2epem() * self.em()
+ self.x() * operand.w() * self.x()
+ self.y() * operand.e1epem() * self.em()
+ self.y() * operand.w() * self.y())
* inv_norm_sq,
(-(self.em() * operand.e12em() * self.em()) + self.em() * operand.w() * self.ep()
- self.ep() * operand.e12em() * self.ep()
+ self.ep() * operand.e1epem() * self.y()
- self.ep() * operand.e2epem() * self.x()
+ self.ep() * operand.w() * self.em()
+ self.x() * operand.e12em() * self.x()
- self.x() * operand.e2epem() * self.ep()
+ self.y() * operand.e12em() * self.y()
+ self.y() * operand.e1epem() * self.ep())
* inv_norm_sq,
(-(self.em() * operand.e1epem() * self.em()) - self.em() * operand.w() * self.y()
+ self.ep() * operand.e12em() * self.y()
+ self.ep() * operand.e1epem() * self.ep()
+ self.x() * operand.e1epem() * self.x()
+ self.x() * operand.e2epem() * self.y()
+ self.y() * operand.e12em() * self.ep()
- self.y() * operand.e1epem() * self.y()
+ self.y() * operand.e2epem() * self.x()
- self.y() * operand.w() * self.em())
* inv_norm_sq,
(-(self.em() * operand.e2epem() * self.em()) + self.em() * operand.w() * self.x()
- self.ep() * operand.e12em() * self.x()
+ self.ep() * operand.e2epem() * self.ep()
- self.x() * operand.e12em() * self.ep()
+ self.x() * operand.e1epem() * self.y()
- self.x() * operand.e2epem() * self.x()
+ self.x() * operand.w() * self.em()
+ self.y() * operand.e1epem() * self.x()
+ self.y() * operand.e2epem() * self.y())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<FlatPoint<T>> for RoundPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &FlatPoint<T>) -> Option<FlatPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(FlatPoint::new_unchecked(
(-(self.em() * operand.e1em() * self.em()) - self.ep() * operand.e1em() * self.ep()
+ self.ep() * operand.epem() * self.x()
+ self.x() * operand.e1em() * self.x()
+ self.x() * operand.e2em() * self.y()
+ self.x() * operand.epem() * self.ep()
- self.y() * operand.e1em() * self.y()
+ self.y() * operand.e2em() * self.x())
* inv_norm_sq,
(-(self.em() * operand.e2em() * self.em()) - self.ep() * operand.e2em() * self.ep()
+ self.ep() * operand.epem() * self.y()
+ self.x() * operand.e1em() * self.y()
- self.x() * operand.e2em() * self.x()
+ self.y() * operand.e1em() * self.x()
+ self.y() * operand.e2em() * self.y()
+ self.y() * operand.epem() * self.ep())
* inv_norm_sq,
(-(self.em() * operand.epem() * self.em())
+ self.ep() * operand.e1em() * self.x()
+ self.ep() * operand.e2em() * self.y()
+ self.ep() * operand.epem() * self.ep()
+ self.x() * operand.e1em() * self.ep()
- self.x() * operand.epem() * self.x()
+ self.y() * operand.e2em() * self.ep()
- self.y() * operand.epem() * self.y())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Line<T>> for RoundPoint<T> {
type Output = Line<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Line<T>) -> Option<Line<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Line::new_unchecked(
(-(self.em() * operand.nx() * self.em())
- self.ep() * operand.d() * self.x()
- self.ep() * operand.nx() * self.ep()
+ self.ep() * operand.ny() * self.y()
- self.x() * operand.d() * self.ep()
+ self.x() * operand.nx() * self.x()
+ self.y() * operand.nx() * self.y()
+ self.y() * operand.ny() * self.ep())
* inv_norm_sq,
(-(self.em() * operand.ny() * self.em())
+ self.ep() * operand.nx() * self.y()
+ self.ep() * operand.ny() * self.ep()
+ self.x() * operand.d() * self.y()
+ self.x() * operand.ny() * self.x()
+ self.y() * operand.d() * self.x()
+ self.y() * operand.nx() * self.ep()
- self.y() * operand.ny() * self.y())
* inv_norm_sq,
(-(self.em() * operand.d() * self.em()) + self.ep() * operand.d() * self.ep()
- self.ep() * operand.nx() * self.x()
- self.x() * operand.d() * self.x()
- self.x() * operand.nx() * self.ep()
+ self.x() * operand.ny() * self.y()
+ self.y() * operand.d() * self.y()
+ self.y() * operand.ny() * self.x())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Motor<T>> for RoundPoint<T> {
type Output = Motor<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Motor<T>) -> Option<Motor<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Motor::new_unchecked(
(self.em() * operand.e1em() * self.x()
+ self.em() * operand.e2em() * self.y()
+ self.em() * operand.epem() * self.ep()
+ self.em() * operand.s() * self.em()
- self.ep() * operand.e1ep() * self.x()
- self.ep() * operand.e2ep() * self.y()
- self.ep() * operand.epem() * self.em()
- self.ep() * operand.s() * self.ep()
- self.x() * operand.e1em() * self.em()
+ self.x() * operand.e1ep() * self.ep()
+ self.x() * operand.m() * self.y()
- self.x() * operand.s() * self.x()
- self.y() * operand.e2em() * self.em()
+ self.y() * operand.e2ep() * self.ep()
- self.y() * operand.m() * self.x()
- self.y() * operand.s() * self.y())
* inv_norm_sq,
(-(self.em() * operand.e1em() * self.y())
+ self.em() * operand.e2em() * self.x()
+ self.em() * operand.m() * self.em()
+ self.em() * operand.ps() * self.ep()
+ self.ep() * operand.e1ep() * self.y()
- self.ep() * operand.e2ep() * self.x()
- self.ep() * operand.m() * self.ep()
- self.ep() * operand.ps() * self.em()
+ self.x() * operand.e2em() * self.em()
- self.x() * operand.e2ep() * self.ep()
+ self.x() * operand.m() * self.x()
+ self.x() * operand.s() * self.y()
- self.y() * operand.e1em() * self.em()
+ self.y() * operand.e1ep() * self.ep()
+ self.y() * operand.m() * self.y()
- self.y() * operand.s() * self.x())
* inv_norm_sq,
(-(self.em() * operand.e1em() * self.ep())
+ self.em() * operand.e1ep() * self.em()
+ self.em() * operand.epem() * self.x()
- self.em() * operand.ps() * self.y()
- self.ep() * operand.e1em() * self.em()
+ self.ep() * operand.e1ep() * self.ep()
+ self.ep() * operand.m() * self.y()
- self.ep() * operand.s() * self.x()
+ self.x() * operand.e1ep() * self.x()
+ self.x() * operand.e2ep() * self.y()
+ self.x() * operand.epem() * self.em()
+ self.x() * operand.s() * self.ep()
- self.y() * operand.e1ep() * self.y()
+ self.y() * operand.e2ep() * self.x()
+ self.y() * operand.m() * self.ep()
+ self.y() * operand.ps() * self.em())
* inv_norm_sq,
(-(self.em() * operand.e2em() * self.ep())
+ self.em() * operand.e2ep() * self.em()
+ self.em() * operand.epem() * self.y()
+ self.em() * operand.ps() * self.x()
- self.ep() * operand.e2em() * self.em()
+ self.ep() * operand.e2ep() * self.ep()
- self.ep() * operand.m() * self.x()
- self.ep() * operand.s() * self.y()
+ self.x() * operand.e1ep() * self.y()
- self.x() * operand.e2ep() * self.x()
- self.x() * operand.m() * self.ep()
- self.x() * operand.ps() * self.em()
+ self.y() * operand.e1ep() * self.x()
+ self.y() * operand.e2ep() * self.y()
+ self.y() * operand.epem() * self.em()
+ self.y() * operand.s() * self.ep())
* inv_norm_sq,
(-(self.em() * operand.e1em() * self.em())
+ self.em() * operand.e1ep() * self.ep()
+ self.em() * operand.m() * self.y()
- self.em() * operand.s() * self.x()
- self.ep() * operand.e1em() * self.ep()
+ self.ep() * operand.e1ep() * self.em()
+ self.ep() * operand.epem() * self.x()
- self.ep() * operand.ps() * self.y()
+ self.x() * operand.e1em() * self.x()
+ self.x() * operand.e2em() * self.y()
+ self.x() * operand.epem() * self.ep()
+ self.x() * operand.s() * self.em()
- self.y() * operand.e1em() * self.y()
+ self.y() * operand.e2em() * self.x()
+ self.y() * operand.m() * self.em()
+ self.y() * operand.ps() * self.ep())
* inv_norm_sq,
(-(self.em() * operand.e2em() * self.em()) + self.em() * operand.e2ep() * self.ep()
- self.em() * operand.m() * self.x()
- self.em() * operand.s() * self.y()
- self.ep() * operand.e2em() * self.ep()
+ self.ep() * operand.e2ep() * self.em()
+ self.ep() * operand.epem() * self.y()
+ self.ep() * operand.ps() * self.x()
+ self.x() * operand.e1em() * self.y()
- self.x() * operand.e2em() * self.x()
- self.x() * operand.m() * self.em()
- self.x() * operand.ps() * self.ep()
+ self.y() * operand.e1em() * self.x()
+ self.y() * operand.e2em() * self.y()
+ self.y() * operand.epem() * self.ep()
+ self.y() * operand.s() * self.em())
* inv_norm_sq,
(-(self.em() * operand.e1ep() * self.x())
- self.em() * operand.e2ep() * self.y()
- self.em() * operand.epem() * self.em()
- self.em() * operand.s() * self.ep()
+ self.ep() * operand.e1em() * self.x()
+ self.ep() * operand.e2em() * self.y()
+ self.ep() * operand.epem() * self.ep()
+ self.ep() * operand.s() * self.em()
+ self.x() * operand.e1em() * self.ep()
- self.x() * operand.e1ep() * self.em()
- self.x() * operand.epem() * self.x()
+ self.x() * operand.ps() * self.y()
+ self.y() * operand.e2em() * self.ep()
- self.y() * operand.e2ep() * self.em()
- self.y() * operand.epem() * self.y()
- self.y() * operand.ps() * self.x())
* inv_norm_sq,
(self.em() * operand.e1ep() * self.y()
- self.em() * operand.e2ep() * self.x()
- self.em() * operand.m() * self.ep()
- self.em() * operand.ps() * self.em()
- self.ep() * operand.e1em() * self.y()
+ self.ep() * operand.e2em() * self.x()
+ self.ep() * operand.m() * self.em()
+ self.ep() * operand.ps() * self.ep()
- self.x() * operand.e2em() * self.ep()
+ self.x() * operand.e2ep() * self.em()
+ self.x() * operand.epem() * self.y()
+ self.x() * operand.ps() * self.x()
+ self.y() * operand.e1em() * self.ep()
- self.y() * operand.e1ep() * self.em()
- self.y() * operand.epem() * self.x()
+ self.y() * operand.ps() * self.y())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<PointPair<T>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &PointPair<T>) -> Option<PointPair<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(PointPair::new_unchecked(
(-(self.em() * operand.e1em() * self.y())
+ self.em() * operand.e2em() * self.x()
+ self.em() * operand.m() * self.em()
+ self.ep() * operand.e1ep() * self.y()
- self.ep() * operand.e2ep() * self.x()
- self.ep() * operand.m() * self.ep()
+ self.x() * operand.e2em() * self.em()
- self.x() * operand.e2ep() * self.ep()
+ self.x() * operand.m() * self.x()
- self.y() * operand.e1em() * self.em()
+ self.y() * operand.e1ep() * self.ep()
+ self.y() * operand.m() * self.y())
* inv_norm_sq,
(-(self.em() * operand.e1em() * self.ep())
+ self.em() * operand.e1ep() * self.em()
+ self.em() * operand.epem() * self.x()
- self.ep() * operand.e1em() * self.em()
+ self.ep() * operand.e1ep() * self.ep()
+ self.ep() * operand.m() * self.y()
+ self.x() * operand.e1ep() * self.x()
+ self.x() * operand.e2ep() * self.y()
+ self.x() * operand.epem() * self.em()
- self.y() * operand.e1ep() * self.y()
+ self.y() * operand.e2ep() * self.x()
+ self.y() * operand.m() * self.ep())
* inv_norm_sq,
(-(self.em() * operand.e2em() * self.ep())
+ self.em() * operand.e2ep() * self.em()
+ self.em() * operand.epem() * self.y()
- self.ep() * operand.e2em() * self.em()
+ self.ep() * operand.e2ep() * self.ep()
- self.ep() * operand.m() * self.x()
+ self.x() * operand.e1ep() * self.y()
- self.x() * operand.e2ep() * self.x()
- self.x() * operand.m() * self.ep()
+ self.y() * operand.e1ep() * self.x()
+ self.y() * operand.e2ep() * self.y()
+ self.y() * operand.epem() * self.em())
* inv_norm_sq,
(-(self.em() * operand.e1em() * self.em())
+ self.em() * operand.e1ep() * self.ep()
+ self.em() * operand.m() * self.y()
- self.ep() * operand.e1em() * self.ep()
+ self.ep() * operand.e1ep() * self.em()
+ self.ep() * operand.epem() * self.x()
+ self.x() * operand.e1em() * self.x()
+ self.x() * operand.e2em() * self.y()
+ self.x() * operand.epem() * self.ep()
- self.y() * operand.e1em() * self.y()
+ self.y() * operand.e2em() * self.x()
+ self.y() * operand.m() * self.em())
* inv_norm_sq,
(-(self.em() * operand.e2em() * self.em()) + self.em() * operand.e2ep() * self.ep()
- self.em() * operand.m() * self.x()
- self.ep() * operand.e2em() * self.ep()
+ self.ep() * operand.e2ep() * self.em()
+ self.ep() * operand.epem() * self.y()
+ self.x() * operand.e1em() * self.y()
- self.x() * operand.e2em() * self.x()
- self.x() * operand.m() * self.em()
+ self.y() * operand.e1em() * self.x()
+ self.y() * operand.e2em() * self.y()
+ self.y() * operand.epem() * self.ep())
* inv_norm_sq,
(-(self.em() * operand.e1ep() * self.x())
- self.em() * operand.e2ep() * self.y()
- self.em() * operand.epem() * self.em()
+ self.ep() * operand.e1em() * self.x()
+ self.ep() * operand.e2em() * self.y()
+ self.ep() * operand.epem() * self.ep()
+ self.x() * operand.e1em() * self.ep()
- self.x() * operand.e1ep() * self.em()
- self.x() * operand.epem() * self.x()
+ self.y() * operand.e2em() * self.ep()
- self.y() * operand.e2ep() * self.em()
- self.y() * operand.epem() * self.y())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Pseudoscalar<T>> for RoundPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Pseudoscalar<T>) -> Option<Pseudoscalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Pseudoscalar::new_unchecked(
(-(self.em() * operand.ps() * self.em())
+ self.ep() * operand.ps() * self.ep()
+ self.x() * operand.ps() * self.x()
+ self.y() * operand.ps() * self.y())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<RoundPoint<T>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &RoundPoint<T>) -> Option<RoundPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(RoundPoint::new_unchecked(
(-(self.em() * operand.em() * self.x())
+ self.em() * operand.x() * self.em()
+ self.ep() * operand.ep() * self.x()
- self.ep() * operand.x() * self.ep()
- self.x() * operand.em() * self.em()
+ self.x() * operand.ep() * self.ep()
+ self.x() * operand.x() * self.x()
+ self.x() * operand.y() * self.y()
- self.y() * operand.x() * self.y()
+ self.y() * operand.y() * self.x())
* inv_norm_sq,
(-(self.em() * operand.em() * self.y())
+ self.em() * operand.y() * self.em()
+ self.ep() * operand.ep() * self.y()
- self.ep() * operand.y() * self.ep()
+ self.x() * operand.x() * self.y()
- self.x() * operand.y() * self.x()
- self.y() * operand.em() * self.em()
+ self.y() * operand.ep() * self.ep()
+ self.y() * operand.x() * self.x()
+ self.y() * operand.y() * self.y())
* inv_norm_sq,
(-(self.em() * operand.em() * self.ep()) + self.em() * operand.ep() * self.em()
- self.ep() * operand.em() * self.em()
+ self.ep() * operand.ep() * self.ep()
+ self.ep() * operand.x() * self.x()
+ self.ep() * operand.y() * self.y()
- self.x() * operand.ep() * self.x()
+ self.x() * operand.x() * self.ep()
- self.y() * operand.ep() * self.y()
+ self.y() * operand.y() * self.ep())
* inv_norm_sq,
(-(self.em() * operand.em() * self.em())
+ self.em() * operand.ep() * self.ep()
+ self.em() * operand.x() * self.x()
+ self.em() * operand.y() * self.y()
- self.ep() * operand.em() * self.ep()
+ self.ep() * operand.ep() * self.em()
- self.x() * operand.em() * self.x()
+ self.x() * operand.x() * self.em()
- self.y() * operand.em() * self.y()
+ self.y() * operand.y() * self.em())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Scalar<T>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Scalar<T>) -> Option<Scalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Scalar::new_unchecked(
(self.em() * operand.s() * self.em()
- self.ep() * operand.s() * self.ep()
- self.x() * operand.s() * self.x()
- self.y() * operand.s() * self.y())
* inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Circle<T>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Circle<T>) -> Option<Circle<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Circle::new_unchecked(
(self.s() * operand.w() * self.s()) * inv_norm_sq,
(self.s() * operand.e12em() * self.s()) * inv_norm_sq,
(self.s() * operand.e1epem() * self.s()) * inv_norm_sq,
(self.s() * operand.e2epem() * self.s()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<FlatPoint<T>> for Scalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &FlatPoint<T>) -> Option<FlatPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(FlatPoint::new_unchecked(
(-(self.s() * operand.e1em() * self.s())) * inv_norm_sq,
(-(self.s() * operand.e2em() * self.s())) * inv_norm_sq,
(-(self.s() * operand.epem() * self.s())) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Line<T>> for Scalar<T> {
type Output = Line<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Line<T>) -> Option<Line<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Line::new_unchecked(
(self.s() * operand.nx() * self.s()) * inv_norm_sq,
(self.s() * operand.ny() * self.s()) * inv_norm_sq,
(self.s() * operand.d() * self.s()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Motor<T>> for Scalar<T> {
type Output = Motor<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Motor<T>) -> Option<Motor<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Motor::new_unchecked(
(-(self.s() * operand.s() * self.s())) * inv_norm_sq,
(-(self.s() * operand.m() * self.s())) * inv_norm_sq,
(-(self.s() * operand.e1ep() * self.s())) * inv_norm_sq,
(-(self.s() * operand.e2ep() * self.s())) * inv_norm_sq,
(-(self.s() * operand.e1em() * self.s())) * inv_norm_sq,
(-(self.s() * operand.e2em() * self.s())) * inv_norm_sq,
(-(self.s() * operand.epem() * self.s())) * inv_norm_sq,
(-(self.s() * operand.ps() * self.s())) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<PointPair<T>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &PointPair<T>) -> Option<PointPair<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(PointPair::new_unchecked(
(-(self.s() * operand.m() * self.s())) * inv_norm_sq,
(-(self.s() * operand.e1ep() * self.s())) * inv_norm_sq,
(-(self.s() * operand.e2ep() * self.s())) * inv_norm_sq,
(-(self.s() * operand.e1em() * self.s())) * inv_norm_sq,
(-(self.s() * operand.e2em() * self.s())) * inv_norm_sq,
(-(self.s() * operand.epem() * self.s())) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Pseudoscalar<T>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Pseudoscalar<T>) -> Option<Pseudoscalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Pseudoscalar::new_unchecked(
(-(self.s() * operand.ps() * self.s())) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<RoundPoint<T>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &RoundPoint<T>) -> Option<RoundPoint<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(RoundPoint::new_unchecked(
(self.s() * operand.x() * self.s()) * inv_norm_sq,
(self.s() * operand.y() * self.s()) * inv_norm_sq,
(self.s() * operand.ep() * self.s()) * inv_norm_sq,
(self.s() * operand.em() * self.s()) * inv_norm_sq,
))
}
}
#[allow(unused_variables)]
impl<T: Float> InverseAntisandwich<Scalar<T>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn try_inverse_antisandwich(&self, operand: &Scalar<T>) -> Option<Scalar<T>> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Scalar::new_unchecked(
(-(self.s() * operand.s() * self.s())) * inv_norm_sq,
))
}
}
impl<T: Float> Versor<Pseudoscalar<T>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn compose(&self, other: &Pseudoscalar<T>) -> RoundPoint<T> {
*self * *other
}
}
impl<T: Float> Versor<Scalar<T>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn compose(&self, other: &Scalar<T>) -> Circle<T> {
*self * *other
}
}
impl<T: Float> Versor<Motor<T>> for FlatPoint<T> {
type Output = Motor<T>;
#[inline]
fn compose(&self, other: &Motor<T>) -> Motor<T> {
*self * *other
}
}
impl<T: Float> Versor<PointPair<T>> for FlatPoint<T> {
type Output = Motor<T>;
#[inline]
fn compose(&self, other: &PointPair<T>) -> Motor<T> {
*self * *other
}
}
impl<T: Float> Versor<Scalar<T>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn compose(&self, other: &Scalar<T>) -> FlatPoint<T> {
*self * *other
}
}
impl<T: Float> Versor<Scalar<T>> for Line<T> {
type Output = Line<T>;
#[inline]
fn compose(&self, other: &Scalar<T>) -> Line<T> {
*self * *other
}
}
impl<T: Float> Versor<FlatPoint<T>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn compose(&self, other: &FlatPoint<T>) -> Motor<T> {
*self * *other
}
}
impl<T: Float> Versor<Motor<T>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn compose(&self, other: &Motor<T>) -> Motor<T> {
*self * *other
}
}
impl<T: Float> Versor<PointPair<T>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn compose(&self, other: &PointPair<T>) -> Motor<T> {
*self * *other
}
}
impl<T: Float> Versor<Pseudoscalar<T>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn compose(&self, other: &Pseudoscalar<T>) -> Motor<T> {
*self * *other
}
}
impl<T: Float> Versor<Scalar<T>> for Motor<T> {
type Output = Motor<T>;
#[inline]
fn compose(&self, other: &Scalar<T>) -> Motor<T> {
*self * *other
}
}
impl<T: Float> Versor<FlatPoint<T>> for PointPair<T> {
type Output = Motor<T>;
#[inline]
fn compose(&self, other: &FlatPoint<T>) -> Motor<T> {
*self * *other
}
}
impl<T: Float> Versor<Motor<T>> for PointPair<T> {
type Output = Motor<T>;
#[inline]
fn compose(&self, other: &Motor<T>) -> Motor<T> {
*self * *other
}
}
impl<T: Float> Versor<PointPair<T>> for PointPair<T> {
type Output = Motor<T>;
#[inline]
fn compose(&self, other: &PointPair<T>) -> Motor<T> {
*self * *other
}
}
impl<T: Float> Versor<Pseudoscalar<T>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn compose(&self, other: &Pseudoscalar<T>) -> PointPair<T> {
*self * *other
}
}
impl<T: Float> Versor<Scalar<T>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn compose(&self, other: &Scalar<T>) -> PointPair<T> {
*self * *other
}
}
impl<T: Float> Versor<Circle<T>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn compose(&self, other: &Circle<T>) -> RoundPoint<T> {
*self * *other
}
}
impl<T: Float> Versor<Motor<T>> for Pseudoscalar<T> {
type Output = Motor<T>;
#[inline]
fn compose(&self, other: &Motor<T>) -> Motor<T> {
*self * *other
}
}
impl<T: Float> Versor<PointPair<T>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn compose(&self, other: &PointPair<T>) -> PointPair<T> {
*self * *other
}
}
impl<T: Float> Versor<Pseudoscalar<T>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn compose(&self, other: &Pseudoscalar<T>) -> Scalar<T> {
*self * *other
}
}
impl<T: Float> Versor<RoundPoint<T>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn compose(&self, other: &RoundPoint<T>) -> Circle<T> {
*self * *other
}
}
impl<T: Float> Versor<Scalar<T>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn compose(&self, other: &Scalar<T>) -> Pseudoscalar<T> {
*self * *other
}
}
impl<T: Float> Versor<Pseudoscalar<T>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn compose(&self, other: &Pseudoscalar<T>) -> Circle<T> {
*self * *other
}
}
impl<T: Float> Versor<Scalar<T>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn compose(&self, other: &Scalar<T>) -> RoundPoint<T> {
*self * *other
}
}
impl<T: Float> Versor<Circle<T>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn compose(&self, other: &Circle<T>) -> Circle<T> {
*self * *other
}
}
impl<T: Float> Versor<FlatPoint<T>> for Scalar<T> {
type Output = FlatPoint<T>;
#[inline]
fn compose(&self, other: &FlatPoint<T>) -> FlatPoint<T> {
*self * *other
}
}
impl<T: Float> Versor<Line<T>> for Scalar<T> {
type Output = Line<T>;
#[inline]
fn compose(&self, other: &Line<T>) -> Line<T> {
*self * *other
}
}
impl<T: Float> Versor<Motor<T>> for Scalar<T> {
type Output = Motor<T>;
#[inline]
fn compose(&self, other: &Motor<T>) -> Motor<T> {
*self * *other
}
}
impl<T: Float> Versor<PointPair<T>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn compose(&self, other: &PointPair<T>) -> PointPair<T> {
*self * *other
}
}
impl<T: Float> Versor<Pseudoscalar<T>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn compose(&self, other: &Pseudoscalar<T>) -> Pseudoscalar<T> {
*self * *other
}
}
impl<T: Float> Versor<RoundPoint<T>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn compose(&self, other: &RoundPoint<T>) -> RoundPoint<T> {
*self * *other
}
}
impl<T: Float> Versor<Scalar<T>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn compose(&self, other: &Scalar<T>) -> Scalar<T> {
*self * *other
}
}
impl<T: Float> ScalarProduct<Circle<T>> for Circle<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Circle<T>) -> T {
-(self.w() * rhs.w())
+ self.e12em() * rhs.e12em()
+ self.e1epem() * rhs.e1epem()
+ self.e2epem() * rhs.e2epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Circle<T>> for Unit<Circle<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Circle<T>) -> T {
-(rhs.w() * self.as_inner().w())
+ rhs.e12em() * self.as_inner().e12em()
+ rhs.e1epem() * self.as_inner().e1epem()
+ rhs.e2epem() * self.as_inner().e2epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<Circle<T>>> for Circle<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<Circle<T>>) -> T {
-(rhs.as_inner().w() * self.w())
+ rhs.as_inner().e12em() * self.e12em()
+ rhs.as_inner().e1epem() * self.e1epem()
+ rhs.as_inner().e2epem() * self.e2epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<Circle<T>>> for Unit<Circle<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<Circle<T>>) -> T {
-(rhs.as_inner().w() * self.as_inner().w())
+ rhs.as_inner().e12em() * self.as_inner().e12em()
+ rhs.as_inner().e1epem() * self.as_inner().e1epem()
+ rhs.as_inner().e2epem() * self.as_inner().e2epem()
}
}
impl<T: Float> ScalarProduct<Line<T>> for Circle<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Line<T>) -> T {
self.e12em() * rhs.nx() + self.e1epem() * rhs.ny() + self.e2epem() * rhs.d()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Line<T>> for Unit<Circle<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Line<T>) -> T {
rhs.d() * self.as_inner().e2epem()
+ rhs.nx() * self.as_inner().e12em()
+ rhs.ny() * self.as_inner().e1epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<Line<T>>> for Circle<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<Line<T>>) -> T {
rhs.as_inner().d() * self.e2epem()
+ rhs.as_inner().nx() * self.e12em()
+ rhs.as_inner().ny() * self.e1epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<Line<T>>> for Unit<Circle<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<Line<T>>) -> T {
rhs.as_inner().d() * self.as_inner().e2epem()
+ rhs.as_inner().nx() * self.as_inner().e12em()
+ rhs.as_inner().ny() * self.as_inner().e1epem()
}
}
impl<T: Float> ScalarProduct<FlatPoint<T>> for FlatPoint<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &FlatPoint<T>) -> T {
self.e1em() * rhs.e1em() + self.e2em() * rhs.e2em() + self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<FlatPoint<T>> for Unit<FlatPoint<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &FlatPoint<T>) -> T {
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<FlatPoint<T>>> for FlatPoint<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<FlatPoint<T>>) -> T {
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<FlatPoint<T>>> for Unit<FlatPoint<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<FlatPoint<T>>) -> T {
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem()
}
}
impl<T: Float> ScalarProduct<PointPair<T>> for FlatPoint<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &PointPair<T>) -> T {
self.e1em() * rhs.e1em() + self.e2em() * rhs.e2em() + self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<PointPair<T>> for Unit<FlatPoint<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &PointPair<T>) -> T {
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<PointPair<T>>> for FlatPoint<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<PointPair<T>>) -> T {
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<PointPair<T>>> for Unit<FlatPoint<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<PointPair<T>>) -> T {
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem()
}
}
impl<T: Float> ScalarProduct<Circle<T>> for Line<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Circle<T>) -> T {
self.nx() * rhs.e12em() + self.ny() * rhs.e1epem() + self.d() * rhs.e2epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Circle<T>> for Unit<Line<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Circle<T>) -> T {
rhs.e12em() * self.as_inner().nx()
+ rhs.e1epem() * self.as_inner().ny()
+ rhs.e2epem() * self.as_inner().d()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<Circle<T>>> for Line<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<Circle<T>>) -> T {
rhs.as_inner().e12em() * self.nx()
+ rhs.as_inner().e1epem() * self.ny()
+ rhs.as_inner().e2epem() * self.d()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<Circle<T>>> for Unit<Line<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<Circle<T>>) -> T {
rhs.as_inner().e12em() * self.as_inner().nx()
+ rhs.as_inner().e1epem() * self.as_inner().ny()
+ rhs.as_inner().e2epem() * self.as_inner().d()
}
}
impl<T: Float> ScalarProduct<Line<T>> for Line<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Line<T>) -> T {
self.nx() * rhs.nx() + self.ny() * rhs.ny() + self.d() * rhs.d()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Line<T>> for Unit<Line<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Line<T>) -> T {
rhs.d() * self.as_inner().d()
+ rhs.nx() * self.as_inner().nx()
+ rhs.ny() * self.as_inner().ny()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<Line<T>>> for Line<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<Line<T>>) -> T {
rhs.as_inner().d() * self.d()
+ rhs.as_inner().nx() * self.nx()
+ rhs.as_inner().ny() * self.ny()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<Line<T>>> for Unit<Line<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<Line<T>>) -> T {
rhs.as_inner().d() * self.as_inner().d()
+ rhs.as_inner().nx() * self.as_inner().nx()
+ rhs.as_inner().ny() * self.as_inner().ny()
}
}
impl<T: Float> ScalarProduct<FlatPoint<T>> for PointPair<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &FlatPoint<T>) -> T {
self.e1em() * rhs.e1em() + self.e2em() * rhs.e2em() + self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<FlatPoint<T>> for Unit<PointPair<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &FlatPoint<T>) -> T {
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<FlatPoint<T>>> for PointPair<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<FlatPoint<T>>) -> T {
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<FlatPoint<T>>> for Unit<PointPair<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<FlatPoint<T>>) -> T {
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem()
}
}
impl<T: Float> ScalarProduct<PointPair<T>> for PointPair<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &PointPair<T>) -> T {
-(self.m() * rhs.m()) - self.e1ep() * rhs.e1ep() - self.e2ep() * rhs.e2ep()
+ self.e1em() * rhs.e1em()
+ self.e2em() * rhs.e2em()
+ self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<PointPair<T>> for Unit<PointPair<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &PointPair<T>) -> T {
-(rhs.e1ep() * self.as_inner().e1ep())
+ -(rhs.e2ep() * self.as_inner().e2ep())
+ -(rhs.m() * self.as_inner().m())
+ rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<PointPair<T>>> for PointPair<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<PointPair<T>>) -> T {
-(rhs.as_inner().e1ep() * self.e1ep())
+ -(rhs.as_inner().e2ep() * self.e2ep())
+ -(rhs.as_inner().m() * self.m())
+ rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<PointPair<T>>> for Unit<PointPair<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<PointPair<T>>) -> T {
-(rhs.as_inner().e1ep() * self.as_inner().e1ep())
+ -(rhs.as_inner().e2ep() * self.as_inner().e2ep())
+ -(rhs.as_inner().m() * self.as_inner().m())
+ rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem()
}
}
impl<T: Float> ScalarProduct<Pseudoscalar<T>> for Pseudoscalar<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Pseudoscalar<T>) -> T {
-(self.ps() * rhs.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Pseudoscalar<T>> for Unit<Pseudoscalar<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Pseudoscalar<T>) -> T {
-(rhs.ps() * self.as_inner().ps())
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<Pseudoscalar<T>>> for Pseudoscalar<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<Pseudoscalar<T>>) -> T {
-(rhs.as_inner().ps() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<Pseudoscalar<T>>> for Unit<Pseudoscalar<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<Pseudoscalar<T>>) -> T {
-(rhs.as_inner().ps() * self.as_inner().ps())
}
}
impl<T: Float> ScalarProduct<RoundPoint<T>> for RoundPoint<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &RoundPoint<T>) -> T {
self.x() * rhs.x() + self.y() * rhs.y() + self.ep() * rhs.ep() - self.em() * rhs.em()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<RoundPoint<T>> for Unit<RoundPoint<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &RoundPoint<T>) -> T {
-(rhs.em() * self.as_inner().em())
+ rhs.ep() * self.as_inner().ep()
+ rhs.x() * self.as_inner().x()
+ rhs.y() * self.as_inner().y()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<RoundPoint<T>>> for RoundPoint<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<RoundPoint<T>>) -> T {
-(rhs.as_inner().em() * self.em())
+ rhs.as_inner().ep() * self.ep()
+ rhs.as_inner().x() * self.x()
+ rhs.as_inner().y() * self.y()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<RoundPoint<T>>> for Unit<RoundPoint<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<RoundPoint<T>>) -> T {
-(rhs.as_inner().em() * self.as_inner().em())
+ rhs.as_inner().ep() * self.as_inner().ep()
+ rhs.as_inner().x() * self.as_inner().x()
+ rhs.as_inner().y() * self.as_inner().y()
}
}
impl<T: Float> ScalarProduct<Scalar<T>> for Scalar<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Scalar<T>) -> T {
self.s() * rhs.s()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Scalar<T>> for Unit<Scalar<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Scalar<T>) -> T {
rhs.s() * self.as_inner().s()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<Scalar<T>>> for Scalar<T> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<Scalar<T>>) -> T {
rhs.as_inner().s() * self.s()
}
}
#[allow(unused_variables)]
impl<T: Float> ScalarProduct<Unit<Scalar<T>>> for Unit<Scalar<T>> {
type Scalar = T;
#[inline]
fn scalar_product(&self, rhs: &Unit<Scalar<T>>) -> T {
rhs.as_inner().s() * self.as_inner().s()
}
}
#[doc = "Bulk contraction of [`Circle`] with [`Circle`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<Circle<T>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e12em() * self.e12em())
+ -(rhs.e1epem() * self.e1epem())
+ -(rhs.e2epem() * self.e2epem())
+ rhs.w() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Circle<T>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e12em() * self.as_inner().e12em())
+ -(rhs.e1epem() * self.as_inner().e1epem())
+ -(rhs.e2epem() * self.as_inner().e2epem())
+ rhs.w() * self.as_inner().w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Circle<T>>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e12em() * self.e12em())
+ -(rhs.as_inner().e1epem() * self.e1epem())
+ -(rhs.as_inner().e2epem() * self.e2epem())
+ rhs.as_inner().w() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Circle<T>>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e12em() * self.as_inner().e12em())
+ -(rhs.as_inner().e1epem() * self.as_inner().e1epem())
+ -(rhs.as_inner().e2epem() * self.as_inner().e2epem())
+ rhs.as_inner().w() * self.as_inner().w(),
)
}
}
#[doc = "Bulk contraction of [`Circle`] with [`Line`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<Line<T>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.d() * self.e2epem()) + -(rhs.nx() * self.e12em()) + -(rhs.ny() * self.e1epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Line<T>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.d() * self.as_inner().e2epem())
+ -(rhs.nx() * self.as_inner().e12em())
+ -(rhs.ny() * self.as_inner().e1epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Line<T>>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().d() * self.e2epem())
+ -(rhs.as_inner().nx() * self.e12em())
+ -(rhs.as_inner().ny() * self.e1epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Line<T>>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().d() * self.as_inner().e2epem())
+ -(rhs.as_inner().nx() * self.as_inner().e12em())
+ -(rhs.as_inner().ny() * self.as_inner().e1epem()),
)
}
}
#[doc = "Bulk contraction of [`Circle`] with [`PointPair`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<PointPair<T>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e2ep() * self.w()) + rhs.e2em() * self.e12em() + rhs.epem() * self.e1epem(),
-(rhs.e1em() * self.e12em()) + rhs.e1ep() * self.w() + rhs.epem() * self.e2epem(),
-(rhs.e1em() * self.e1epem()) + -(rhs.e2em() * self.e2epem()) + -(rhs.m() * self.w()),
-(rhs.e1ep() * self.e1epem())
+ -(rhs.e2ep() * self.e2epem())
+ -(rhs.m() * self.e12em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<PointPair<T>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e2ep() * self.as_inner().w())
+ rhs.e2em() * self.as_inner().e12em()
+ rhs.epem() * self.as_inner().e1epem(),
-(rhs.e1em() * self.as_inner().e12em())
+ rhs.e1ep() * self.as_inner().w()
+ rhs.epem() * self.as_inner().e2epem(),
-(rhs.e1em() * self.as_inner().e1epem())
+ -(rhs.e2em() * self.as_inner().e2epem())
+ -(rhs.m() * self.as_inner().w()),
-(rhs.e1ep() * self.as_inner().e1epem())
+ -(rhs.e2ep() * self.as_inner().e2epem())
+ -(rhs.m() * self.as_inner().e12em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<PointPair<T>>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e2ep() * self.w())
+ rhs.as_inner().e2em() * self.e12em()
+ rhs.as_inner().epem() * self.e1epem(),
-(rhs.as_inner().e1em() * self.e12em())
+ rhs.as_inner().e1ep() * self.w()
+ rhs.as_inner().epem() * self.e2epem(),
-(rhs.as_inner().e1em() * self.e1epem())
+ -(rhs.as_inner().e2em() * self.e2epem())
+ -(rhs.as_inner().m() * self.w()),
-(rhs.as_inner().e1ep() * self.e1epem())
+ -(rhs.as_inner().e2ep() * self.e2epem())
+ -(rhs.as_inner().m() * self.e12em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<PointPair<T>>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e2ep() * self.as_inner().w())
+ rhs.as_inner().e2em() * self.as_inner().e12em()
+ rhs.as_inner().epem() * self.as_inner().e1epem(),
-(rhs.as_inner().e1em() * self.as_inner().e12em())
+ rhs.as_inner().e1ep() * self.as_inner().w()
+ rhs.as_inner().epem() * self.as_inner().e2epem(),
-(rhs.as_inner().e1em() * self.as_inner().e1epem())
+ -(rhs.as_inner().e2em() * self.as_inner().e2epem())
+ -(rhs.as_inner().m() * self.as_inner().w()),
-(rhs.as_inner().e1ep() * self.as_inner().e1epem())
+ -(rhs.as_inner().e2ep() * self.as_inner().e2epem())
+ -(rhs.as_inner().m() * self.as_inner().e12em()),
)
}
}
#[doc = "Bulk contraction of [`Circle`] with [`RoundPoint`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<RoundPoint<T>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn bulk_contract(&self, rhs: &RoundPoint<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.em() * self.e12em()) + rhs.ep() * self.w(),
-(rhs.em() * self.e1epem()) + -(rhs.y() * self.w()),
-(rhs.em() * self.e2epem()) + rhs.x() * self.w(),
-(rhs.ep() * self.e1epem()) + -(rhs.y() * self.e12em()),
-(rhs.ep() * self.e2epem()) + rhs.x() * self.e12em(),
rhs.x() * self.e1epem() + rhs.y() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<RoundPoint<T>> for Unit<Circle<T>> {
type Output = PointPair<T>;
#[inline]
fn bulk_contract(&self, rhs: &RoundPoint<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.em() * self.as_inner().e12em()) + rhs.ep() * self.as_inner().w(),
-(rhs.em() * self.as_inner().e1epem()) + -(rhs.y() * self.as_inner().w()),
-(rhs.em() * self.as_inner().e2epem()) + rhs.x() * self.as_inner().w(),
-(rhs.ep() * self.as_inner().e1epem()) + -(rhs.y() * self.as_inner().e12em()),
-(rhs.ep() * self.as_inner().e2epem()) + rhs.x() * self.as_inner().e12em(),
rhs.x() * self.as_inner().e1epem() + rhs.y() * self.as_inner().e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<RoundPoint<T>>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<RoundPoint<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().em() * self.e12em()) + rhs.as_inner().ep() * self.w(),
-(rhs.as_inner().em() * self.e1epem()) + -(rhs.as_inner().y() * self.w()),
-(rhs.as_inner().em() * self.e2epem()) + rhs.as_inner().x() * self.w(),
-(rhs.as_inner().ep() * self.e1epem()) + -(rhs.as_inner().y() * self.e12em()),
-(rhs.as_inner().ep() * self.e2epem()) + rhs.as_inner().x() * self.e12em(),
rhs.as_inner().x() * self.e1epem() + rhs.as_inner().y() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<RoundPoint<T>>> for Unit<Circle<T>> {
type Output = PointPair<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<RoundPoint<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().em() * self.as_inner().e12em())
+ rhs.as_inner().ep() * self.as_inner().w(),
-(rhs.as_inner().em() * self.as_inner().e1epem())
+ -(rhs.as_inner().y() * self.as_inner().w()),
-(rhs.as_inner().em() * self.as_inner().e2epem())
+ rhs.as_inner().x() * self.as_inner().w(),
-(rhs.as_inner().ep() * self.as_inner().e1epem())
+ -(rhs.as_inner().y() * self.as_inner().e12em()),
-(rhs.as_inner().ep() * self.as_inner().e2epem())
+ rhs.as_inner().x() * self.as_inner().e12em(),
rhs.as_inner().x() * self.as_inner().e1epem()
+ rhs.as_inner().y() * self.as_inner().e2epem(),
)
}
}
#[doc = "Bulk contraction of [`Circle`] with [`Scalar`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<Scalar<T>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn bulk_contract(&self, rhs: &Scalar<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.s() * self.w()),
-(rhs.s() * self.e12em()),
-(rhs.s() * self.e1epem()),
-(rhs.s() * self.e2epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Scalar<T>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn bulk_contract(&self, rhs: &Scalar<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.s() * self.as_inner().w()),
-(rhs.s() * self.as_inner().e12em()),
-(rhs.s() * self.as_inner().e1epem()),
-(rhs.s() * self.as_inner().e2epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Scalar<T>>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Scalar<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().s() * self.w()),
-(rhs.as_inner().s() * self.e12em()),
-(rhs.as_inner().s() * self.e1epem()),
-(rhs.as_inner().s() * self.e2epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Scalar<T>>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Scalar<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().s() * self.as_inner().w()),
-(rhs.as_inner().s() * self.as_inner().e12em()),
-(rhs.as_inner().s() * self.as_inner().e1epem()),
-(rhs.as_inner().s() * self.as_inner().e2epem()),
)
}
}
#[doc = "Bulk contraction of [`FlatPoint`] with [`FlatPoint`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<FlatPoint<T>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1em() * self.e1em()) + -(rhs.e2em() * self.e2em()) + -(rhs.epem() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<FlatPoint<T>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1em() * self.as_inner().e1em())
+ -(rhs.e2em() * self.as_inner().e2em())
+ -(rhs.epem() * self.as_inner().epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<FlatPoint<T>>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1em() * self.e1em())
+ -(rhs.as_inner().e2em() * self.e2em())
+ -(rhs.as_inner().epem() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<FlatPoint<T>>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1em() * self.as_inner().e1em())
+ -(rhs.as_inner().e2em() * self.as_inner().e2em())
+ -(rhs.as_inner().epem() * self.as_inner().epem()),
)
}
}
#[doc = "Bulk contraction of [`FlatPoint`] with [`PointPair`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<PointPair<T>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1em() * self.e1em()) + -(rhs.e2em() * self.e2em()) + -(rhs.epem() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<PointPair<T>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1em() * self.as_inner().e1em())
+ -(rhs.e2em() * self.as_inner().e2em())
+ -(rhs.epem() * self.as_inner().epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<PointPair<T>>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1em() * self.e1em())
+ -(rhs.as_inner().e2em() * self.e2em())
+ -(rhs.as_inner().epem() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<PointPair<T>>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1em() * self.as_inner().e1em())
+ -(rhs.as_inner().e2em() * self.as_inner().e2em())
+ -(rhs.as_inner().epem() * self.as_inner().epem()),
)
}
}
#[doc = "Bulk contraction of [`FlatPoint`] with [`RoundPoint`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<RoundPoint<T>> for FlatPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.em() * self.e1em()),
-(rhs.em() * self.e2em()),
-(rhs.em() * self.epem()),
-(rhs.ep() * self.epem()) + -(rhs.x() * self.e1em()) + -(rhs.y() * self.e2em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<RoundPoint<T>> for Unit<FlatPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.em() * self.as_inner().e1em()),
-(rhs.em() * self.as_inner().e2em()),
-(rhs.em() * self.as_inner().epem()),
-(rhs.ep() * self.as_inner().epem())
+ -(rhs.x() * self.as_inner().e1em())
+ -(rhs.y() * self.as_inner().e2em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<RoundPoint<T>>> for FlatPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().em() * self.e1em()),
-(rhs.as_inner().em() * self.e2em()),
-(rhs.as_inner().em() * self.epem()),
-(rhs.as_inner().ep() * self.epem())
+ -(rhs.as_inner().x() * self.e1em())
+ -(rhs.as_inner().y() * self.e2em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<RoundPoint<T>>> for Unit<FlatPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().em() * self.as_inner().e1em()),
-(rhs.as_inner().em() * self.as_inner().e2em()),
-(rhs.as_inner().em() * self.as_inner().epem()),
-(rhs.as_inner().ep() * self.as_inner().epem())
+ -(rhs.as_inner().x() * self.as_inner().e1em())
+ -(rhs.as_inner().y() * self.as_inner().e2em()),
)
}
}
#[doc = "Bulk contraction of [`FlatPoint`] with [`Scalar`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<Scalar<T>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Scalar<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.s() * self.e1em(),
rhs.s() * self.e2em(),
rhs.s() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Scalar<T>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Scalar<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.s() * self.as_inner().e1em(),
rhs.s() * self.as_inner().e2em(),
rhs.s() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Scalar<T>>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Scalar<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.as_inner().s() * self.e1em(),
rhs.as_inner().s() * self.e2em(),
rhs.as_inner().s() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Scalar<T>>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Scalar<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.as_inner().s() * self.as_inner().e1em(),
rhs.as_inner().s() * self.as_inner().e2em(),
rhs.as_inner().s() * self.as_inner().epem(),
)
}
}
#[doc = "Bulk contraction of [`Line`] with [`Circle`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<Circle<T>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e12em() * self.nx()) + -(rhs.e1epem() * self.ny()) + -(rhs.e2epem() * self.d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Circle<T>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e12em() * self.as_inner().nx())
+ -(rhs.e1epem() * self.as_inner().ny())
+ -(rhs.e2epem() * self.as_inner().d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Circle<T>>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e12em() * self.nx())
+ -(rhs.as_inner().e1epem() * self.ny())
+ -(rhs.as_inner().e2epem() * self.d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Circle<T>>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e12em() * self.as_inner().nx())
+ -(rhs.as_inner().e1epem() * self.as_inner().ny())
+ -(rhs.as_inner().e2epem() * self.as_inner().d()),
)
}
}
#[doc = "Bulk contraction of [`Line`] with [`Line`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<Line<T>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.d() * self.d()) + -(rhs.nx() * self.nx()) + -(rhs.ny() * self.ny()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Line<T>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.d() * self.as_inner().d())
+ -(rhs.nx() * self.as_inner().nx())
+ -(rhs.ny() * self.as_inner().ny()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Line<T>>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().d() * self.d())
+ -(rhs.as_inner().nx() * self.nx())
+ -(rhs.as_inner().ny() * self.ny()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Line<T>>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().d() * self.as_inner().d())
+ -(rhs.as_inner().nx() * self.as_inner().nx())
+ -(rhs.as_inner().ny() * self.as_inner().ny()),
)
}
}
#[doc = "Bulk contraction of [`Line`] with [`PointPair`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<PointPair<T>> for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.e2em() * self.nx() + rhs.epem() * self.ny(),
-(rhs.e1em() * self.nx()) + rhs.epem() * self.d(),
-(rhs.e1em() * self.ny()) + -(rhs.e2em() * self.d()),
-(rhs.e1ep() * self.ny()) + -(rhs.e2ep() * self.d()) + -(rhs.m() * self.nx()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<PointPair<T>> for Unit<Line<T>> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.e2em() * self.as_inner().nx() + rhs.epem() * self.as_inner().ny(),
-(rhs.e1em() * self.as_inner().nx()) + rhs.epem() * self.as_inner().d(),
-(rhs.e1em() * self.as_inner().ny()) + -(rhs.e2em() * self.as_inner().d()),
-(rhs.e1ep() * self.as_inner().ny())
+ -(rhs.e2ep() * self.as_inner().d())
+ -(rhs.m() * self.as_inner().nx()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<PointPair<T>>> for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().e2em() * self.nx() + rhs.as_inner().epem() * self.ny(),
-(rhs.as_inner().e1em() * self.nx()) + rhs.as_inner().epem() * self.d(),
-(rhs.as_inner().e1em() * self.ny()) + -(rhs.as_inner().e2em() * self.d()),
-(rhs.as_inner().e1ep() * self.ny())
+ -(rhs.as_inner().e2ep() * self.d())
+ -(rhs.as_inner().m() * self.nx()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<PointPair<T>>> for Unit<Line<T>> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().e2em() * self.as_inner().nx()
+ rhs.as_inner().epem() * self.as_inner().ny(),
-(rhs.as_inner().e1em() * self.as_inner().nx())
+ rhs.as_inner().epem() * self.as_inner().d(),
-(rhs.as_inner().e1em() * self.as_inner().ny())
+ -(rhs.as_inner().e2em() * self.as_inner().d()),
-(rhs.as_inner().e1ep() * self.as_inner().ny())
+ -(rhs.as_inner().e2ep() * self.as_inner().d())
+ -(rhs.as_inner().m() * self.as_inner().nx()),
)
}
}
#[doc = "Bulk contraction of [`Line`] with [`RoundPoint`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<RoundPoint<T>> for Line<T> {
type Output = PointPair<T>;
#[inline]
fn bulk_contract(&self, rhs: &RoundPoint<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.em() * self.nx()),
-(rhs.em() * self.ny()),
-(rhs.em() * self.d()),
-(rhs.ep() * self.ny()) + -(rhs.y() * self.nx()),
-(rhs.ep() * self.d()) + rhs.x() * self.nx(),
rhs.x() * self.ny() + rhs.y() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<RoundPoint<T>> for Unit<Line<T>> {
type Output = PointPair<T>;
#[inline]
fn bulk_contract(&self, rhs: &RoundPoint<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.em() * self.as_inner().nx()),
-(rhs.em() * self.as_inner().ny()),
-(rhs.em() * self.as_inner().d()),
-(rhs.ep() * self.as_inner().ny()) + -(rhs.y() * self.as_inner().nx()),
-(rhs.ep() * self.as_inner().d()) + rhs.x() * self.as_inner().nx(),
rhs.x() * self.as_inner().ny() + rhs.y() * self.as_inner().d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<RoundPoint<T>>> for Line<T> {
type Output = PointPair<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<RoundPoint<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().em() * self.nx()),
-(rhs.as_inner().em() * self.ny()),
-(rhs.as_inner().em() * self.d()),
-(rhs.as_inner().ep() * self.ny()) + -(rhs.as_inner().y() * self.nx()),
-(rhs.as_inner().ep() * self.d()) + rhs.as_inner().x() * self.nx(),
rhs.as_inner().x() * self.ny() + rhs.as_inner().y() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<RoundPoint<T>>> for Unit<Line<T>> {
type Output = PointPair<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<RoundPoint<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().em() * self.as_inner().nx()),
-(rhs.as_inner().em() * self.as_inner().ny()),
-(rhs.as_inner().em() * self.as_inner().d()),
-(rhs.as_inner().ep() * self.as_inner().ny())
+ -(rhs.as_inner().y() * self.as_inner().nx()),
-(rhs.as_inner().ep() * self.as_inner().d())
+ rhs.as_inner().x() * self.as_inner().nx(),
rhs.as_inner().x() * self.as_inner().ny() + rhs.as_inner().y() * self.as_inner().d(),
)
}
}
#[doc = "Bulk contraction of [`Line`] with [`Scalar`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<Scalar<T>> for Line<T> {
type Output = Line<T>;
#[inline]
fn bulk_contract(&self, rhs: &Scalar<T>) -> Line<T> {
Line::new_unchecked(
-(rhs.s() * self.nx()),
-(rhs.s() * self.ny()),
-(rhs.s() * self.d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Scalar<T>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn bulk_contract(&self, rhs: &Scalar<T>) -> Line<T> {
Line::new_unchecked(
-(rhs.s() * self.as_inner().nx()),
-(rhs.s() * self.as_inner().ny()),
-(rhs.s() * self.as_inner().d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Scalar<T>>> for Line<T> {
type Output = Line<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Scalar<T>>) -> Line<T> {
Line::new_unchecked(
-(rhs.as_inner().s() * self.nx()),
-(rhs.as_inner().s() * self.ny()),
-(rhs.as_inner().s() * self.d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Scalar<T>>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Scalar<T>>) -> Line<T> {
Line::new_unchecked(
-(rhs.as_inner().s() * self.as_inner().nx()),
-(rhs.as_inner().s() * self.as_inner().ny()),
-(rhs.as_inner().s() * self.as_inner().d()),
)
}
}
#[doc = "Bulk contraction of [`PointPair`] with [`FlatPoint`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<FlatPoint<T>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1em() * self.e1em()) + -(rhs.e2em() * self.e2em()) + -(rhs.epem() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<FlatPoint<T>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1em() * self.as_inner().e1em())
+ -(rhs.e2em() * self.as_inner().e2em())
+ -(rhs.epem() * self.as_inner().epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<FlatPoint<T>>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1em() * self.e1em())
+ -(rhs.as_inner().e2em() * self.e2em())
+ -(rhs.as_inner().epem() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<FlatPoint<T>>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1em() * self.as_inner().e1em())
+ -(rhs.as_inner().e2em() * self.as_inner().e2em())
+ -(rhs.as_inner().epem() * self.as_inner().epem()),
)
}
}
#[doc = "Bulk contraction of [`PointPair`] with [`PointPair`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<PointPair<T>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1em() * self.e1em())
+ -(rhs.e2em() * self.e2em())
+ -(rhs.epem() * self.epem())
+ rhs.e1ep() * self.e1ep()
+ rhs.e2ep() * self.e2ep()
+ rhs.m() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<PointPair<T>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1em() * self.as_inner().e1em())
+ -(rhs.e2em() * self.as_inner().e2em())
+ -(rhs.epem() * self.as_inner().epem())
+ rhs.e1ep() * self.as_inner().e1ep()
+ rhs.e2ep() * self.as_inner().e2ep()
+ rhs.m() * self.as_inner().m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<PointPair<T>>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1em() * self.e1em())
+ -(rhs.as_inner().e2em() * self.e2em())
+ -(rhs.as_inner().epem() * self.epem())
+ rhs.as_inner().e1ep() * self.e1ep()
+ rhs.as_inner().e2ep() * self.e2ep()
+ rhs.as_inner().m() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<PointPair<T>>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1em() * self.as_inner().e1em())
+ -(rhs.as_inner().e2em() * self.as_inner().e2em())
+ -(rhs.as_inner().epem() * self.as_inner().epem())
+ rhs.as_inner().e1ep() * self.as_inner().e1ep()
+ rhs.as_inner().e2ep() * self.as_inner().e2ep()
+ rhs.as_inner().m() * self.as_inner().m(),
)
}
}
#[doc = "Bulk contraction of [`PointPair`] with [`RoundPoint`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<RoundPoint<T>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.em() * self.e1em()) + rhs.ep() * self.e1ep() + rhs.y() * self.m(),
-(rhs.em() * self.e2em()) + -(rhs.x() * self.m()) + rhs.ep() * self.e2ep(),
-(rhs.em() * self.epem()) + -(rhs.x() * self.e1ep()) + -(rhs.y() * self.e2ep()),
-(rhs.ep() * self.epem()) + -(rhs.x() * self.e1em()) + -(rhs.y() * self.e2em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<RoundPoint<T>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.em() * self.as_inner().e1em())
+ rhs.ep() * self.as_inner().e1ep()
+ rhs.y() * self.as_inner().m(),
-(rhs.em() * self.as_inner().e2em())
+ -(rhs.x() * self.as_inner().m())
+ rhs.ep() * self.as_inner().e2ep(),
-(rhs.em() * self.as_inner().epem())
+ -(rhs.x() * self.as_inner().e1ep())
+ -(rhs.y() * self.as_inner().e2ep()),
-(rhs.ep() * self.as_inner().epem())
+ -(rhs.x() * self.as_inner().e1em())
+ -(rhs.y() * self.as_inner().e2em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<RoundPoint<T>>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().em() * self.e1em())
+ rhs.as_inner().ep() * self.e1ep()
+ rhs.as_inner().y() * self.m(),
-(rhs.as_inner().em() * self.e2em())
+ -(rhs.as_inner().x() * self.m())
+ rhs.as_inner().ep() * self.e2ep(),
-(rhs.as_inner().em() * self.epem())
+ -(rhs.as_inner().x() * self.e1ep())
+ -(rhs.as_inner().y() * self.e2ep()),
-(rhs.as_inner().ep() * self.epem())
+ -(rhs.as_inner().x() * self.e1em())
+ -(rhs.as_inner().y() * self.e2em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<RoundPoint<T>>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().em() * self.as_inner().e1em())
+ rhs.as_inner().ep() * self.as_inner().e1ep()
+ rhs.as_inner().y() * self.as_inner().m(),
-(rhs.as_inner().em() * self.as_inner().e2em())
+ -(rhs.as_inner().x() * self.as_inner().m())
+ rhs.as_inner().ep() * self.as_inner().e2ep(),
-(rhs.as_inner().em() * self.as_inner().epem())
+ -(rhs.as_inner().x() * self.as_inner().e1ep())
+ -(rhs.as_inner().y() * self.as_inner().e2ep()),
-(rhs.as_inner().ep() * self.as_inner().epem())
+ -(rhs.as_inner().x() * self.as_inner().e1em())
+ -(rhs.as_inner().y() * self.as_inner().e2em()),
)
}
}
#[doc = "Bulk contraction of [`PointPair`] with [`Scalar`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<Scalar<T>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn bulk_contract(&self, rhs: &Scalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.s() * self.m(),
rhs.s() * self.e1ep(),
rhs.s() * self.e2ep(),
rhs.s() * self.e1em(),
rhs.s() * self.e2em(),
rhs.s() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Scalar<T>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn bulk_contract(&self, rhs: &Scalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.s() * self.as_inner().m(),
rhs.s() * self.as_inner().e1ep(),
rhs.s() * self.as_inner().e2ep(),
rhs.s() * self.as_inner().e1em(),
rhs.s() * self.as_inner().e2em(),
rhs.s() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Scalar<T>>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Scalar<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().s() * self.m(),
rhs.as_inner().s() * self.e1ep(),
rhs.as_inner().s() * self.e2ep(),
rhs.as_inner().s() * self.e1em(),
rhs.as_inner().s() * self.e2em(),
rhs.as_inner().s() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Scalar<T>>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Scalar<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().s() * self.as_inner().m(),
rhs.as_inner().s() * self.as_inner().e1ep(),
rhs.as_inner().s() * self.as_inner().e2ep(),
rhs.as_inner().s() * self.as_inner().e1em(),
rhs.as_inner().s() * self.as_inner().e2em(),
rhs.as_inner().s() * self.as_inner().epem(),
)
}
}
#[doc = "Bulk contraction of [`Pseudoscalar`] with [`Circle`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<Circle<T>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Circle<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e2epem() * self.ps()),
rhs.e1epem() * self.ps(),
-(rhs.e12em() * self.ps()),
-(rhs.w() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Circle<T>> for Unit<Pseudoscalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Circle<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e2epem() * self.as_inner().ps()),
rhs.e1epem() * self.as_inner().ps(),
-(rhs.e12em() * self.as_inner().ps()),
-(rhs.w() * self.as_inner().ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Circle<T>>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Circle<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e2epem() * self.ps()),
rhs.as_inner().e1epem() * self.ps(),
-(rhs.as_inner().e12em() * self.ps()),
-(rhs.as_inner().w() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Circle<T>>> for Unit<Pseudoscalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Circle<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e2epem() * self.as_inner().ps()),
rhs.as_inner().e1epem() * self.as_inner().ps(),
-(rhs.as_inner().e12em() * self.as_inner().ps()),
-(rhs.as_inner().w() * self.as_inner().ps()),
)
}
}
#[doc = "Bulk contraction of [`Pseudoscalar`] with [`PointPair`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<PointPair<T>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn bulk_contract(&self, rhs: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.epem() * self.ps()),
rhs.e2em() * self.ps(),
-(rhs.e1em() * self.ps()),
rhs.e2ep() * self.ps(),
-(rhs.e1ep() * self.ps()),
rhs.m() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<PointPair<T>> for Unit<Pseudoscalar<T>> {
type Output = PointPair<T>;
#[inline]
fn bulk_contract(&self, rhs: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.epem() * self.as_inner().ps()),
rhs.e2em() * self.as_inner().ps(),
-(rhs.e1em() * self.as_inner().ps()),
rhs.e2ep() * self.as_inner().ps(),
-(rhs.e1ep() * self.as_inner().ps()),
rhs.m() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<PointPair<T>>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().epem() * self.ps()),
rhs.as_inner().e2em() * self.ps(),
-(rhs.as_inner().e1em() * self.ps()),
rhs.as_inner().e2ep() * self.ps(),
-(rhs.as_inner().e1ep() * self.ps()),
rhs.as_inner().m() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<PointPair<T>>> for Unit<Pseudoscalar<T>> {
type Output = PointPair<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().epem() * self.as_inner().ps()),
rhs.as_inner().e2em() * self.as_inner().ps(),
-(rhs.as_inner().e1em() * self.as_inner().ps()),
rhs.as_inner().e2ep() * self.as_inner().ps(),
-(rhs.as_inner().e1ep() * self.as_inner().ps()),
rhs.as_inner().m() * self.as_inner().ps(),
)
}
}
#[doc = "Bulk contraction of [`Pseudoscalar`] with [`Pseudoscalar`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<Pseudoscalar<T>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Pseudoscalar<T>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.ps() * self.ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Pseudoscalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Pseudoscalar<T>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.ps() * self.as_inner().ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Pseudoscalar<T>>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Pseudoscalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.as_inner().ps() * self.ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Pseudoscalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Pseudoscalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.as_inner().ps() * self.as_inner().ps()))
}
}
#[doc = "Bulk contraction of [`Pseudoscalar`] with [`RoundPoint`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<RoundPoint<T>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn bulk_contract(&self, rhs: &RoundPoint<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.em() * self.ps()),
-(rhs.ep() * self.ps()),
rhs.y() * self.ps(),
-(rhs.x() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<RoundPoint<T>> for Unit<Pseudoscalar<T>> {
type Output = Circle<T>;
#[inline]
fn bulk_contract(&self, rhs: &RoundPoint<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.em() * self.as_inner().ps()),
-(rhs.ep() * self.as_inner().ps()),
rhs.y() * self.as_inner().ps(),
-(rhs.x() * self.as_inner().ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<RoundPoint<T>>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<RoundPoint<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().em() * self.ps()),
-(rhs.as_inner().ep() * self.ps()),
rhs.as_inner().y() * self.ps(),
-(rhs.as_inner().x() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<RoundPoint<T>>> for Unit<Pseudoscalar<T>> {
type Output = Circle<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<RoundPoint<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().em() * self.as_inner().ps()),
-(rhs.as_inner().ep() * self.as_inner().ps()),
rhs.as_inner().y() * self.as_inner().ps(),
-(rhs.as_inner().x() * self.as_inner().ps()),
)
}
}
#[doc = "Bulk contraction of [`Pseudoscalar`] with [`Scalar`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<Scalar<T>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Scalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.s() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Scalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Scalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.s() * self.as_inner().ps())
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Scalar<T>>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Scalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.as_inner().s() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Scalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Scalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.as_inner().s() * self.as_inner().ps())
}
}
#[doc = "Bulk contraction of [`RoundPoint`] with [`RoundPoint`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<RoundPoint<T>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &RoundPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.em() * self.em())
+ rhs.ep() * self.ep()
+ rhs.x() * self.x()
+ rhs.y() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<RoundPoint<T>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &RoundPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.em() * self.as_inner().em())
+ rhs.ep() * self.as_inner().ep()
+ rhs.x() * self.as_inner().x()
+ rhs.y() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<RoundPoint<T>>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<RoundPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().em() * self.em())
+ rhs.as_inner().ep() * self.ep()
+ rhs.as_inner().x() * self.x()
+ rhs.as_inner().y() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<RoundPoint<T>>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<RoundPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().em() * self.as_inner().em())
+ rhs.as_inner().ep() * self.as_inner().ep()
+ rhs.as_inner().x() * self.as_inner().x()
+ rhs.as_inner().y() * self.as_inner().y(),
)
}
}
#[doc = "Bulk contraction of [`RoundPoint`] with [`Scalar`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<Scalar<T>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Scalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.s() * self.x()),
-(rhs.s() * self.y()),
-(rhs.s() * self.ep()),
-(rhs.s() * self.em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Scalar<T>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Scalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.s() * self.as_inner().x()),
-(rhs.s() * self.as_inner().y()),
-(rhs.s() * self.as_inner().ep()),
-(rhs.s() * self.as_inner().em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Scalar<T>>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Scalar<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().s() * self.x()),
-(rhs.as_inner().s() * self.y()),
-(rhs.as_inner().s() * self.ep()),
-(rhs.as_inner().s() * self.em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Scalar<T>>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Scalar<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().s() * self.as_inner().x()),
-(rhs.as_inner().s() * self.as_inner().y()),
-(rhs.as_inner().s() * self.as_inner().ep()),
-(rhs.as_inner().s() * self.as_inner().em()),
)
}
}
#[doc = "Bulk contraction of [`Scalar`] with [`Scalar`].\n\nThe bulk contraction extracts the Euclidean (non-degenerate) component\nof the interior product. In PGA, this isolates the finite/spatial part."]
impl<T: Float> BulkContract<Scalar<T>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.s() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Scalar<T>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.s() * self.as_inner().s())
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Scalar<T>>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(rhs.as_inner().s() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> BulkContract<Unit<Scalar<T>>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_contract(&self, rhs: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(rhs.as_inner().s() * self.as_inner().s())
}
}
#[doc = "Weight contraction of [`Circle`] with [`Circle`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<Circle<T>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.w() * self.w())
+ rhs.e12em() * self.e12em()
+ rhs.e1epem() * self.e1epem()
+ rhs.e2epem() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Circle<T>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.w() * self.as_inner().w())
+ rhs.e12em() * self.as_inner().e12em()
+ rhs.e1epem() * self.as_inner().e1epem()
+ rhs.e2epem() * self.as_inner().e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Circle<T>>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().w() * self.w())
+ rhs.as_inner().e12em() * self.e12em()
+ rhs.as_inner().e1epem() * self.e1epem()
+ rhs.as_inner().e2epem() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Circle<T>>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().w() * self.as_inner().w())
+ rhs.as_inner().e12em() * self.as_inner().e12em()
+ rhs.as_inner().e1epem() * self.as_inner().e1epem()
+ rhs.as_inner().e2epem() * self.as_inner().e2epem(),
)
}
}
#[doc = "Weight contraction of [`Circle`] with [`Line`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<Line<T>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.d() * self.e2epem() + rhs.nx() * self.e12em() + rhs.ny() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Line<T>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.d() * self.as_inner().e2epem()
+ rhs.nx() * self.as_inner().e12em()
+ rhs.ny() * self.as_inner().e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Line<T>>> for Circle<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().d() * self.e2epem()
+ rhs.as_inner().nx() * self.e12em()
+ rhs.as_inner().ny() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Line<T>>> for Unit<Circle<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().d() * self.as_inner().e2epem()
+ rhs.as_inner().nx() * self.as_inner().e12em()
+ rhs.as_inner().ny() * self.as_inner().e1epem(),
)
}
}
#[doc = "Weight contraction of [`Circle`] with [`PointPair`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<PointPair<T>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e2em() * self.e12em()) + -(rhs.epem() * self.e1epem()) + rhs.e2ep() * self.w(),
-(rhs.e1ep() * self.w()) + -(rhs.epem() * self.e2epem()) + rhs.e1em() * self.e12em(),
rhs.e1em() * self.e1epem() + rhs.e2em() * self.e2epem() + rhs.m() * self.w(),
rhs.e1ep() * self.e1epem() + rhs.e2ep() * self.e2epem() + rhs.m() * self.e12em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<PointPair<T>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e2em() * self.as_inner().e12em())
+ -(rhs.epem() * self.as_inner().e1epem())
+ rhs.e2ep() * self.as_inner().w(),
-(rhs.e1ep() * self.as_inner().w())
+ -(rhs.epem() * self.as_inner().e2epem())
+ rhs.e1em() * self.as_inner().e12em(),
rhs.e1em() * self.as_inner().e1epem()
+ rhs.e2em() * self.as_inner().e2epem()
+ rhs.m() * self.as_inner().w(),
rhs.e1ep() * self.as_inner().e1epem()
+ rhs.e2ep() * self.as_inner().e2epem()
+ rhs.m() * self.as_inner().e12em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<PointPair<T>>> for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e2em() * self.e12em())
+ -(rhs.as_inner().epem() * self.e1epem())
+ rhs.as_inner().e2ep() * self.w(),
-(rhs.as_inner().e1ep() * self.w())
+ -(rhs.as_inner().epem() * self.e2epem())
+ rhs.as_inner().e1em() * self.e12em(),
rhs.as_inner().e1em() * self.e1epem()
+ rhs.as_inner().e2em() * self.e2epem()
+ rhs.as_inner().m() * self.w(),
rhs.as_inner().e1ep() * self.e1epem()
+ rhs.as_inner().e2ep() * self.e2epem()
+ rhs.as_inner().m() * self.e12em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<PointPair<T>>> for Unit<Circle<T>> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e2em() * self.as_inner().e12em())
+ -(rhs.as_inner().epem() * self.as_inner().e1epem())
+ rhs.as_inner().e2ep() * self.as_inner().w(),
-(rhs.as_inner().e1ep() * self.as_inner().w())
+ -(rhs.as_inner().epem() * self.as_inner().e2epem())
+ rhs.as_inner().e1em() * self.as_inner().e12em(),
rhs.as_inner().e1em() * self.as_inner().e1epem()
+ rhs.as_inner().e2em() * self.as_inner().e2epem()
+ rhs.as_inner().m() * self.as_inner().w(),
rhs.as_inner().e1ep() * self.as_inner().e1epem()
+ rhs.as_inner().e2ep() * self.as_inner().e2epem()
+ rhs.as_inner().m() * self.as_inner().e12em(),
)
}
}
#[doc = "Weight contraction of [`Circle`] with [`RoundPoint`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<RoundPoint<T>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn weight_contract(&self, rhs: &RoundPoint<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.ep() * self.w()) + rhs.em() * self.e12em(),
rhs.em() * self.e1epem() + rhs.y() * self.w(),
-(rhs.x() * self.w()) + rhs.em() * self.e2epem(),
rhs.ep() * self.e1epem() + rhs.y() * self.e12em(),
-(rhs.x() * self.e12em()) + rhs.ep() * self.e2epem(),
-(rhs.x() * self.e1epem()) + -(rhs.y() * self.e2epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<RoundPoint<T>> for Unit<Circle<T>> {
type Output = PointPair<T>;
#[inline]
fn weight_contract(&self, rhs: &RoundPoint<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.ep() * self.as_inner().w()) + rhs.em() * self.as_inner().e12em(),
rhs.em() * self.as_inner().e1epem() + rhs.y() * self.as_inner().w(),
-(rhs.x() * self.as_inner().w()) + rhs.em() * self.as_inner().e2epem(),
rhs.ep() * self.as_inner().e1epem() + rhs.y() * self.as_inner().e12em(),
-(rhs.x() * self.as_inner().e12em()) + rhs.ep() * self.as_inner().e2epem(),
-(rhs.x() * self.as_inner().e1epem()) + -(rhs.y() * self.as_inner().e2epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<RoundPoint<T>>> for Circle<T> {
type Output = PointPair<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<RoundPoint<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().ep() * self.w()) + rhs.as_inner().em() * self.e12em(),
rhs.as_inner().em() * self.e1epem() + rhs.as_inner().y() * self.w(),
-(rhs.as_inner().x() * self.w()) + rhs.as_inner().em() * self.e2epem(),
rhs.as_inner().ep() * self.e1epem() + rhs.as_inner().y() * self.e12em(),
-(rhs.as_inner().x() * self.e12em()) + rhs.as_inner().ep() * self.e2epem(),
-(rhs.as_inner().x() * self.e1epem()) + -(rhs.as_inner().y() * self.e2epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<RoundPoint<T>>> for Unit<Circle<T>> {
type Output = PointPair<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<RoundPoint<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().ep() * self.as_inner().w())
+ rhs.as_inner().em() * self.as_inner().e12em(),
rhs.as_inner().em() * self.as_inner().e1epem()
+ rhs.as_inner().y() * self.as_inner().w(),
-(rhs.as_inner().x() * self.as_inner().w())
+ rhs.as_inner().em() * self.as_inner().e2epem(),
rhs.as_inner().ep() * self.as_inner().e1epem()
+ rhs.as_inner().y() * self.as_inner().e12em(),
-(rhs.as_inner().x() * self.as_inner().e12em())
+ rhs.as_inner().ep() * self.as_inner().e2epem(),
-(rhs.as_inner().x() * self.as_inner().e1epem())
+ -(rhs.as_inner().y() * self.as_inner().e2epem()),
)
}
}
#[doc = "Weight contraction of [`Circle`] with [`Scalar`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<Scalar<T>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn weight_contract(&self, rhs: &Scalar<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.s() * self.w(),
rhs.s() * self.e12em(),
rhs.s() * self.e1epem(),
rhs.s() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Scalar<T>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn weight_contract(&self, rhs: &Scalar<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.s() * self.as_inner().w(),
rhs.s() * self.as_inner().e12em(),
rhs.s() * self.as_inner().e1epem(),
rhs.s() * self.as_inner().e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Scalar<T>>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Scalar<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().s() * self.w(),
rhs.as_inner().s() * self.e12em(),
rhs.as_inner().s() * self.e1epem(),
rhs.as_inner().s() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Scalar<T>>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Scalar<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().s() * self.as_inner().w(),
rhs.as_inner().s() * self.as_inner().e12em(),
rhs.as_inner().s() * self.as_inner().e1epem(),
rhs.as_inner().s() * self.as_inner().e2epem(),
)
}
}
#[doc = "Weight contraction of [`FlatPoint`] with [`FlatPoint`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<FlatPoint<T>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.e1em() + rhs.e2em() * self.e2em() + rhs.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<FlatPoint<T>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<FlatPoint<T>>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<FlatPoint<T>>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Weight contraction of [`FlatPoint`] with [`PointPair`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<PointPair<T>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.e1em() + rhs.e2em() * self.e2em() + rhs.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<PointPair<T>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<PointPair<T>>> for FlatPoint<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<PointPair<T>>> for Unit<FlatPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Weight contraction of [`FlatPoint`] with [`RoundPoint`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<RoundPoint<T>> for FlatPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.em() * self.e1em(),
rhs.em() * self.e2em(),
rhs.em() * self.epem(),
rhs.ep() * self.epem() + rhs.x() * self.e1em() + rhs.y() * self.e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<RoundPoint<T>> for Unit<FlatPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.em() * self.as_inner().e1em(),
rhs.em() * self.as_inner().e2em(),
rhs.em() * self.as_inner().epem(),
rhs.ep() * self.as_inner().epem()
+ rhs.x() * self.as_inner().e1em()
+ rhs.y() * self.as_inner().e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<RoundPoint<T>>> for FlatPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().em() * self.e1em(),
rhs.as_inner().em() * self.e2em(),
rhs.as_inner().em() * self.epem(),
rhs.as_inner().ep() * self.epem()
+ rhs.as_inner().x() * self.e1em()
+ rhs.as_inner().y() * self.e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<RoundPoint<T>>> for Unit<FlatPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().em() * self.as_inner().e1em(),
rhs.as_inner().em() * self.as_inner().e2em(),
rhs.as_inner().em() * self.as_inner().epem(),
rhs.as_inner().ep() * self.as_inner().epem()
+ rhs.as_inner().x() * self.as_inner().e1em()
+ rhs.as_inner().y() * self.as_inner().e2em(),
)
}
}
#[doc = "Weight contraction of [`FlatPoint`] with [`Scalar`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<Scalar<T>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Scalar<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(rhs.s() * self.e1em()),
-(rhs.s() * self.e2em()),
-(rhs.s() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Scalar<T>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Scalar<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(rhs.s() * self.as_inner().e1em()),
-(rhs.s() * self.as_inner().e2em()),
-(rhs.s() * self.as_inner().epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Scalar<T>>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Scalar<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(rhs.as_inner().s() * self.e1em()),
-(rhs.as_inner().s() * self.e2em()),
-(rhs.as_inner().s() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Scalar<T>>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Scalar<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(rhs.as_inner().s() * self.as_inner().e1em()),
-(rhs.as_inner().s() * self.as_inner().e2em()),
-(rhs.as_inner().s() * self.as_inner().epem()),
)
}
}
#[doc = "Weight contraction of [`Line`] with [`Circle`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<Circle<T>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e12em() * self.nx() + rhs.e1epem() * self.ny() + rhs.e2epem() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Circle<T>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Circle<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e12em() * self.as_inner().nx()
+ rhs.e1epem() * self.as_inner().ny()
+ rhs.e2epem() * self.as_inner().d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Circle<T>>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e12em() * self.nx()
+ rhs.as_inner().e1epem() * self.ny()
+ rhs.as_inner().e2epem() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Circle<T>>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Circle<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e12em() * self.as_inner().nx()
+ rhs.as_inner().e1epem() * self.as_inner().ny()
+ rhs.as_inner().e2epem() * self.as_inner().d(),
)
}
}
#[doc = "Weight contraction of [`Line`] with [`Line`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<Line<T>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.d() * self.d() + rhs.nx() * self.nx() + rhs.ny() * self.ny())
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Line<T>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Line<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.d() * self.as_inner().d()
+ rhs.nx() * self.as_inner().nx()
+ rhs.ny() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Line<T>>> for Line<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().d() * self.d()
+ rhs.as_inner().nx() * self.nx()
+ rhs.as_inner().ny() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Line<T>>> for Unit<Line<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Line<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().d() * self.as_inner().d()
+ rhs.as_inner().nx() * self.as_inner().nx()
+ rhs.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[doc = "Weight contraction of [`Line`] with [`PointPair`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<PointPair<T>> for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e2em() * self.nx()) + -(rhs.epem() * self.ny()),
-(rhs.epem() * self.d()) + rhs.e1em() * self.nx(),
rhs.e1em() * self.ny() + rhs.e2em() * self.d(),
rhs.e1ep() * self.ny() + rhs.e2ep() * self.d() + rhs.m() * self.nx(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<PointPair<T>> for Unit<Line<T>> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &PointPair<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e2em() * self.as_inner().nx()) + -(rhs.epem() * self.as_inner().ny()),
-(rhs.epem() * self.as_inner().d()) + rhs.e1em() * self.as_inner().nx(),
rhs.e1em() * self.as_inner().ny() + rhs.e2em() * self.as_inner().d(),
rhs.e1ep() * self.as_inner().ny()
+ rhs.e2ep() * self.as_inner().d()
+ rhs.m() * self.as_inner().nx(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<PointPair<T>>> for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e2em() * self.nx()) + -(rhs.as_inner().epem() * self.ny()),
-(rhs.as_inner().epem() * self.d()) + rhs.as_inner().e1em() * self.nx(),
rhs.as_inner().e1em() * self.ny() + rhs.as_inner().e2em() * self.d(),
rhs.as_inner().e1ep() * self.ny()
+ rhs.as_inner().e2ep() * self.d()
+ rhs.as_inner().m() * self.nx(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<PointPair<T>>> for Unit<Line<T>> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<PointPair<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e2em() * self.as_inner().nx())
+ -(rhs.as_inner().epem() * self.as_inner().ny()),
-(rhs.as_inner().epem() * self.as_inner().d())
+ rhs.as_inner().e1em() * self.as_inner().nx(),
rhs.as_inner().e1em() * self.as_inner().ny()
+ rhs.as_inner().e2em() * self.as_inner().d(),
rhs.as_inner().e1ep() * self.as_inner().ny()
+ rhs.as_inner().e2ep() * self.as_inner().d()
+ rhs.as_inner().m() * self.as_inner().nx(),
)
}
}
#[doc = "Weight contraction of [`Line`] with [`RoundPoint`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<RoundPoint<T>> for Line<T> {
type Output = PointPair<T>;
#[inline]
fn weight_contract(&self, rhs: &RoundPoint<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.em() * self.nx(),
rhs.em() * self.ny(),
rhs.em() * self.d(),
rhs.ep() * self.ny() + rhs.y() * self.nx(),
-(rhs.x() * self.nx()) + rhs.ep() * self.d(),
-(rhs.x() * self.ny()) + -(rhs.y() * self.d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<RoundPoint<T>> for Unit<Line<T>> {
type Output = PointPair<T>;
#[inline]
fn weight_contract(&self, rhs: &RoundPoint<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.em() * self.as_inner().nx(),
rhs.em() * self.as_inner().ny(),
rhs.em() * self.as_inner().d(),
rhs.ep() * self.as_inner().ny() + rhs.y() * self.as_inner().nx(),
-(rhs.x() * self.as_inner().nx()) + rhs.ep() * self.as_inner().d(),
-(rhs.x() * self.as_inner().ny()) + -(rhs.y() * self.as_inner().d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<RoundPoint<T>>> for Line<T> {
type Output = PointPair<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<RoundPoint<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().em() * self.nx(),
rhs.as_inner().em() * self.ny(),
rhs.as_inner().em() * self.d(),
rhs.as_inner().ep() * self.ny() + rhs.as_inner().y() * self.nx(),
-(rhs.as_inner().x() * self.nx()) + rhs.as_inner().ep() * self.d(),
-(rhs.as_inner().x() * self.ny()) + -(rhs.as_inner().y() * self.d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<RoundPoint<T>>> for Unit<Line<T>> {
type Output = PointPair<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<RoundPoint<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().em() * self.as_inner().nx(),
rhs.as_inner().em() * self.as_inner().ny(),
rhs.as_inner().em() * self.as_inner().d(),
rhs.as_inner().ep() * self.as_inner().ny() + rhs.as_inner().y() * self.as_inner().nx(),
-(rhs.as_inner().x() * self.as_inner().nx())
+ rhs.as_inner().ep() * self.as_inner().d(),
-(rhs.as_inner().x() * self.as_inner().ny())
+ -(rhs.as_inner().y() * self.as_inner().d()),
)
}
}
#[doc = "Weight contraction of [`Line`] with [`Scalar`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<Scalar<T>> for Line<T> {
type Output = Line<T>;
#[inline]
fn weight_contract(&self, rhs: &Scalar<T>) -> Line<T> {
Line::new_unchecked(rhs.s() * self.nx(), rhs.s() * self.ny(), rhs.s() * self.d())
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Scalar<T>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn weight_contract(&self, rhs: &Scalar<T>) -> Line<T> {
Line::new_unchecked(
rhs.s() * self.as_inner().nx(),
rhs.s() * self.as_inner().ny(),
rhs.s() * self.as_inner().d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Scalar<T>>> for Line<T> {
type Output = Line<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Scalar<T>>) -> Line<T> {
Line::new_unchecked(
rhs.as_inner().s() * self.nx(),
rhs.as_inner().s() * self.ny(),
rhs.as_inner().s() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Scalar<T>>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Scalar<T>>) -> Line<T> {
Line::new_unchecked(
rhs.as_inner().s() * self.as_inner().nx(),
rhs.as_inner().s() * self.as_inner().ny(),
rhs.as_inner().s() * self.as_inner().d(),
)
}
}
#[doc = "Weight contraction of [`PointPair`] with [`FlatPoint`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<FlatPoint<T>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.e1em() + rhs.e2em() * self.e2em() + rhs.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<FlatPoint<T>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &FlatPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<FlatPoint<T>>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<FlatPoint<T>>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<FlatPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Weight contraction of [`PointPair`] with [`PointPair`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<PointPair<T>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1ep() * self.e1ep())
+ -(rhs.e2ep() * self.e2ep())
+ -(rhs.m() * self.m())
+ rhs.e1em() * self.e1em()
+ rhs.e2em() * self.e2em()
+ rhs.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<PointPair<T>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &PointPair<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.e1ep() * self.as_inner().e1ep())
+ -(rhs.e2ep() * self.as_inner().e2ep())
+ -(rhs.m() * self.as_inner().m())
+ rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<PointPair<T>>> for PointPair<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1ep() * self.e1ep())
+ -(rhs.as_inner().e2ep() * self.e2ep())
+ -(rhs.as_inner().m() * self.m())
+ rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<PointPair<T>>> for Unit<PointPair<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<PointPair<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().e1ep() * self.as_inner().e1ep())
+ -(rhs.as_inner().e2ep() * self.as_inner().e2ep())
+ -(rhs.as_inner().m() * self.as_inner().m())
+ rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Weight contraction of [`PointPair`] with [`RoundPoint`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<RoundPoint<T>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.ep() * self.e1ep()) + -(rhs.y() * self.m()) + rhs.em() * self.e1em(),
-(rhs.ep() * self.e2ep()) + rhs.em() * self.e2em() + rhs.x() * self.m(),
rhs.em() * self.epem() + rhs.x() * self.e1ep() + rhs.y() * self.e2ep(),
rhs.ep() * self.epem() + rhs.x() * self.e1em() + rhs.y() * self.e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<RoundPoint<T>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &RoundPoint<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.ep() * self.as_inner().e1ep())
+ -(rhs.y() * self.as_inner().m())
+ rhs.em() * self.as_inner().e1em(),
-(rhs.ep() * self.as_inner().e2ep())
+ rhs.em() * self.as_inner().e2em()
+ rhs.x() * self.as_inner().m(),
rhs.em() * self.as_inner().epem()
+ rhs.x() * self.as_inner().e1ep()
+ rhs.y() * self.as_inner().e2ep(),
rhs.ep() * self.as_inner().epem()
+ rhs.x() * self.as_inner().e1em()
+ rhs.y() * self.as_inner().e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<RoundPoint<T>>> for PointPair<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().ep() * self.e1ep())
+ -(rhs.as_inner().y() * self.m())
+ rhs.as_inner().em() * self.e1em(),
-(rhs.as_inner().ep() * self.e2ep())
+ rhs.as_inner().em() * self.e2em()
+ rhs.as_inner().x() * self.m(),
rhs.as_inner().em() * self.epem()
+ rhs.as_inner().x() * self.e1ep()
+ rhs.as_inner().y() * self.e2ep(),
rhs.as_inner().ep() * self.epem()
+ rhs.as_inner().x() * self.e1em()
+ rhs.as_inner().y() * self.e2em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<RoundPoint<T>>> for Unit<PointPair<T>> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<RoundPoint<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().ep() * self.as_inner().e1ep())
+ -(rhs.as_inner().y() * self.as_inner().m())
+ rhs.as_inner().em() * self.as_inner().e1em(),
-(rhs.as_inner().ep() * self.as_inner().e2ep())
+ rhs.as_inner().em() * self.as_inner().e2em()
+ rhs.as_inner().x() * self.as_inner().m(),
rhs.as_inner().em() * self.as_inner().epem()
+ rhs.as_inner().x() * self.as_inner().e1ep()
+ rhs.as_inner().y() * self.as_inner().e2ep(),
rhs.as_inner().ep() * self.as_inner().epem()
+ rhs.as_inner().x() * self.as_inner().e1em()
+ rhs.as_inner().y() * self.as_inner().e2em(),
)
}
}
#[doc = "Weight contraction of [`PointPair`] with [`Scalar`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<Scalar<T>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn weight_contract(&self, rhs: &Scalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.s() * self.m()),
-(rhs.s() * self.e1ep()),
-(rhs.s() * self.e2ep()),
-(rhs.s() * self.e1em()),
-(rhs.s() * self.e2em()),
-(rhs.s() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Scalar<T>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn weight_contract(&self, rhs: &Scalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.s() * self.as_inner().m()),
-(rhs.s() * self.as_inner().e1ep()),
-(rhs.s() * self.as_inner().e2ep()),
-(rhs.s() * self.as_inner().e1em()),
-(rhs.s() * self.as_inner().e2em()),
-(rhs.s() * self.as_inner().epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Scalar<T>>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Scalar<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().s() * self.m()),
-(rhs.as_inner().s() * self.e1ep()),
-(rhs.as_inner().s() * self.e2ep()),
-(rhs.as_inner().s() * self.e1em()),
-(rhs.as_inner().s() * self.e2em()),
-(rhs.as_inner().s() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Scalar<T>>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Scalar<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().s() * self.as_inner().m()),
-(rhs.as_inner().s() * self.as_inner().e1ep()),
-(rhs.as_inner().s() * self.as_inner().e2ep()),
-(rhs.as_inner().s() * self.as_inner().e1em()),
-(rhs.as_inner().s() * self.as_inner().e2em()),
-(rhs.as_inner().s() * self.as_inner().epem()),
)
}
}
#[doc = "Weight contraction of [`Pseudoscalar`] with [`Circle`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<Circle<T>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Circle<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.e2epem() * self.ps(),
-(rhs.e1epem() * self.ps()),
rhs.e12em() * self.ps(),
rhs.w() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Circle<T>> for Unit<Pseudoscalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Circle<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.e2epem() * self.as_inner().ps(),
-(rhs.e1epem() * self.as_inner().ps()),
rhs.e12em() * self.as_inner().ps(),
rhs.w() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Circle<T>>> for Pseudoscalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Circle<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().e2epem() * self.ps(),
-(rhs.as_inner().e1epem() * self.ps()),
rhs.as_inner().e12em() * self.ps(),
rhs.as_inner().w() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Circle<T>>> for Unit<Pseudoscalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Circle<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().e2epem() * self.as_inner().ps(),
-(rhs.as_inner().e1epem() * self.as_inner().ps()),
rhs.as_inner().e12em() * self.as_inner().ps(),
rhs.as_inner().w() * self.as_inner().ps(),
)
}
}
#[doc = "Weight contraction of [`Pseudoscalar`] with [`PointPair`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<PointPair<T>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn weight_contract(&self, rhs: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.epem() * self.ps(),
-(rhs.e2em() * self.ps()),
rhs.e1em() * self.ps(),
-(rhs.e2ep() * self.ps()),
rhs.e1ep() * self.ps(),
-(rhs.m() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<PointPair<T>> for Unit<Pseudoscalar<T>> {
type Output = PointPair<T>;
#[inline]
fn weight_contract(&self, rhs: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.epem() * self.as_inner().ps(),
-(rhs.e2em() * self.as_inner().ps()),
rhs.e1em() * self.as_inner().ps(),
-(rhs.e2ep() * self.as_inner().ps()),
rhs.e1ep() * self.as_inner().ps(),
-(rhs.m() * self.as_inner().ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<PointPair<T>>> for Pseudoscalar<T> {
type Output = PointPair<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().epem() * self.ps(),
-(rhs.as_inner().e2em() * self.ps()),
rhs.as_inner().e1em() * self.ps(),
-(rhs.as_inner().e2ep() * self.ps()),
rhs.as_inner().e1ep() * self.ps(),
-(rhs.as_inner().m() * self.ps()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<PointPair<T>>> for Unit<Pseudoscalar<T>> {
type Output = PointPair<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().epem() * self.as_inner().ps(),
-(rhs.as_inner().e2em() * self.as_inner().ps()),
rhs.as_inner().e1em() * self.as_inner().ps(),
-(rhs.as_inner().e2ep() * self.as_inner().ps()),
rhs.as_inner().e1ep() * self.as_inner().ps(),
-(rhs.as_inner().m() * self.as_inner().ps()),
)
}
}
#[doc = "Weight contraction of [`Pseudoscalar`] with [`Pseudoscalar`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<Pseudoscalar<T>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Pseudoscalar<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.ps() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Pseudoscalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Pseudoscalar<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.ps() * self.as_inner().ps())
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Pseudoscalar<T>>> for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Pseudoscalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(rhs.as_inner().ps() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Pseudoscalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Pseudoscalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(rhs.as_inner().ps() * self.as_inner().ps())
}
}
#[doc = "Weight contraction of [`Pseudoscalar`] with [`RoundPoint`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<RoundPoint<T>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn weight_contract(&self, rhs: &RoundPoint<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.em() * self.ps(),
rhs.ep() * self.ps(),
-(rhs.y() * self.ps()),
rhs.x() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<RoundPoint<T>> for Unit<Pseudoscalar<T>> {
type Output = Circle<T>;
#[inline]
fn weight_contract(&self, rhs: &RoundPoint<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.em() * self.as_inner().ps(),
rhs.ep() * self.as_inner().ps(),
-(rhs.y() * self.as_inner().ps()),
rhs.x() * self.as_inner().ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<RoundPoint<T>>> for Pseudoscalar<T> {
type Output = Circle<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<RoundPoint<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().em() * self.ps(),
rhs.as_inner().ep() * self.ps(),
-(rhs.as_inner().y() * self.ps()),
rhs.as_inner().x() * self.ps(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<RoundPoint<T>>> for Unit<Pseudoscalar<T>> {
type Output = Circle<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<RoundPoint<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().em() * self.as_inner().ps(),
rhs.as_inner().ep() * self.as_inner().ps(),
-(rhs.as_inner().y() * self.as_inner().ps()),
rhs.as_inner().x() * self.as_inner().ps(),
)
}
}
#[doc = "Weight contraction of [`Pseudoscalar`] with [`Scalar`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<Scalar<T>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Scalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(rhs.s() * self.ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Scalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Scalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(rhs.s() * self.as_inner().ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Scalar<T>>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Scalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(rhs.as_inner().s() * self.ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Scalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Scalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(rhs.as_inner().s() * self.as_inner().ps()))
}
}
#[doc = "Weight contraction of [`RoundPoint`] with [`RoundPoint`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<RoundPoint<T>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &RoundPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.ep() * self.ep())
+ -(rhs.x() * self.x())
+ -(rhs.y() * self.y())
+ rhs.em() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<RoundPoint<T>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &RoundPoint<T>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.ep() * self.as_inner().ep())
+ -(rhs.x() * self.as_inner().x())
+ -(rhs.y() * self.as_inner().y())
+ rhs.em() * self.as_inner().em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<RoundPoint<T>>> for RoundPoint<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<RoundPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().ep() * self.ep())
+ -(rhs.as_inner().x() * self.x())
+ -(rhs.as_inner().y() * self.y())
+ rhs.as_inner().em() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<RoundPoint<T>>> for Unit<RoundPoint<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<RoundPoint<T>>) -> Scalar<T> {
Scalar::new_unchecked(
-(rhs.as_inner().ep() * self.as_inner().ep())
+ -(rhs.as_inner().x() * self.as_inner().x())
+ -(rhs.as_inner().y() * self.as_inner().y())
+ rhs.as_inner().em() * self.as_inner().em(),
)
}
}
#[doc = "Weight contraction of [`RoundPoint`] with [`Scalar`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<Scalar<T>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Scalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.s() * self.x(),
rhs.s() * self.y(),
rhs.s() * self.ep(),
rhs.s() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Scalar<T>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Scalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.s() * self.as_inner().x(),
rhs.s() * self.as_inner().y(),
rhs.s() * self.as_inner().ep(),
rhs.s() * self.as_inner().em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Scalar<T>>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Scalar<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().s() * self.x(),
rhs.as_inner().s() * self.y(),
rhs.as_inner().s() * self.ep(),
rhs.as_inner().s() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Scalar<T>>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Scalar<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().s() * self.as_inner().x(),
rhs.as_inner().s() * self.as_inner().y(),
rhs.as_inner().s() * self.as_inner().ep(),
rhs.as_inner().s() * self.as_inner().em(),
)
}
}
#[doc = "Weight contraction of [`Scalar`] with [`Scalar`].\n\nThe weight contraction extracts the degenerate/ideal component of the\ninterior product. In PGA, this measures the 'weight' or projective part."]
impl<T: Float> WeightContract<Scalar<T>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.s() * self.s()))
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Scalar<T>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Scalar<T>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.s() * self.as_inner().s()))
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Scalar<T>>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.as_inner().s() * self.s()))
}
}
#[allow(unused_variables)]
impl<T: Float> WeightContract<Unit<Scalar<T>>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_contract(&self, rhs: &Unit<Scalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.as_inner().s() * self.as_inner().s()))
}
}
#[doc = "Bulk expansion of [`Circle`] with [`Circle`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Circle<T>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Circle<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e12em() * self.e12em())
+ -(rhs.e1epem() * self.e1epem())
+ -(rhs.e2epem() * self.e2epem())
+ rhs.w() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Circle<T>> for Unit<Circle<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Circle<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e12em() * self.as_inner().e12em())
+ -(rhs.e1epem() * self.as_inner().e1epem())
+ -(rhs.e2epem() * self.as_inner().e2epem())
+ rhs.w() * self.as_inner().w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Circle<T>>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Circle<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e12em() * self.e12em())
+ -(rhs.as_inner().e1epem() * self.e1epem())
+ -(rhs.as_inner().e2epem() * self.e2epem())
+ rhs.as_inner().w() * self.w(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Circle<T>>> for Unit<Circle<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Circle<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e12em() * self.as_inner().e12em())
+ -(rhs.as_inner().e1epem() * self.as_inner().e1epem())
+ -(rhs.as_inner().e2epem() * self.as_inner().e2epem())
+ rhs.as_inner().w() * self.as_inner().w(),
)
}
}
#[doc = "Bulk expansion of [`Circle`] with [`Line`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Line<T>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Line<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.d() * self.e2epem()) + -(rhs.nx() * self.e12em()) + -(rhs.ny() * self.e1epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Line<T>> for Unit<Circle<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Line<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.d() * self.as_inner().e2epem())
+ -(rhs.nx() * self.as_inner().e12em())
+ -(rhs.ny() * self.as_inner().e1epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Line<T>>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Line<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().d() * self.e2epem())
+ -(rhs.as_inner().nx() * self.e12em())
+ -(rhs.as_inner().ny() * self.e1epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Line<T>>> for Unit<Circle<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Line<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().d() * self.as_inner().e2epem())
+ -(rhs.as_inner().nx() * self.as_inner().e12em())
+ -(rhs.as_inner().ny() * self.as_inner().e1epem()),
)
}
}
#[doc = "Bulk expansion of [`Circle`] with [`Pseudoscalar`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Pseudoscalar<T>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Pseudoscalar<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.ps() * self.w()),
-(rhs.ps() * self.e12em()),
-(rhs.ps() * self.e1epem()),
-(rhs.ps() * self.e2epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Pseudoscalar<T>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Pseudoscalar<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.ps() * self.as_inner().w()),
-(rhs.ps() * self.as_inner().e12em()),
-(rhs.ps() * self.as_inner().e1epem()),
-(rhs.ps() * self.as_inner().e2epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Pseudoscalar<T>>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().ps() * self.w()),
-(rhs.as_inner().ps() * self.e12em()),
-(rhs.as_inner().ps() * self.e1epem()),
-(rhs.as_inner().ps() * self.e2epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Pseudoscalar<T>>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().ps() * self.as_inner().w()),
-(rhs.as_inner().ps() * self.as_inner().e12em()),
-(rhs.as_inner().ps() * self.as_inner().e1epem()),
-(rhs.as_inner().ps() * self.as_inner().e2epem()),
)
}
}
#[doc = "Bulk expansion of [`FlatPoint`] with [`Circle`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Circle<T>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn bulk_expand(&self, rhs: &Circle<T>) -> Line<T> {
Line::new_unchecked(
rhs.e1epem() * self.e1em() + rhs.e2epem() * self.e2em(),
-(rhs.e12em() * self.e1em()) + rhs.e2epem() * self.epem(),
-(rhs.e12em() * self.e2em()) + -(rhs.e1epem() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Circle<T>> for Unit<FlatPoint<T>> {
type Output = Line<T>;
#[inline]
fn bulk_expand(&self, rhs: &Circle<T>) -> Line<T> {
Line::new_unchecked(
rhs.e1epem() * self.as_inner().e1em() + rhs.e2epem() * self.as_inner().e2em(),
-(rhs.e12em() * self.as_inner().e1em()) + rhs.e2epem() * self.as_inner().epem(),
-(rhs.e12em() * self.as_inner().e2em()) + -(rhs.e1epem() * self.as_inner().epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Circle<T>>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Circle<T>>) -> Line<T> {
Line::new_unchecked(
rhs.as_inner().e1epem() * self.e1em() + rhs.as_inner().e2epem() * self.e2em(),
-(rhs.as_inner().e12em() * self.e1em()) + rhs.as_inner().e2epem() * self.epem(),
-(rhs.as_inner().e12em() * self.e2em()) + -(rhs.as_inner().e1epem() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Circle<T>>> for Unit<FlatPoint<T>> {
type Output = Line<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Circle<T>>) -> Line<T> {
Line::new_unchecked(
rhs.as_inner().e1epem() * self.as_inner().e1em()
+ rhs.as_inner().e2epem() * self.as_inner().e2em(),
-(rhs.as_inner().e12em() * self.as_inner().e1em())
+ rhs.as_inner().e2epem() * self.as_inner().epem(),
-(rhs.as_inner().e12em() * self.as_inner().e2em())
+ -(rhs.as_inner().e1epem() * self.as_inner().epem()),
)
}
}
#[doc = "Bulk expansion of [`FlatPoint`] with [`FlatPoint`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<FlatPoint<T>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &FlatPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e1em() * self.e1em()) + -(rhs.e2em() * self.e2em()) + -(rhs.epem() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<FlatPoint<T>> for Unit<FlatPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &FlatPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e1em() * self.as_inner().e1em())
+ -(rhs.e2em() * self.as_inner().e2em())
+ -(rhs.epem() * self.as_inner().epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<FlatPoint<T>>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<FlatPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e1em() * self.e1em())
+ -(rhs.as_inner().e2em() * self.e2em())
+ -(rhs.as_inner().epem() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<FlatPoint<T>>> for Unit<FlatPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<FlatPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e1em() * self.as_inner().e1em())
+ -(rhs.as_inner().e2em() * self.as_inner().e2em())
+ -(rhs.as_inner().epem() * self.as_inner().epem()),
)
}
}
#[doc = "Bulk expansion of [`FlatPoint`] with [`Line`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Line<T>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn bulk_expand(&self, rhs: &Line<T>) -> Line<T> {
Line::new_unchecked(
rhs.d() * self.e2em() + rhs.ny() * self.e1em(),
-(rhs.nx() * self.e1em()) + rhs.d() * self.epem(),
-(rhs.nx() * self.e2em()) + -(rhs.ny() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Line<T>> for Unit<FlatPoint<T>> {
type Output = Line<T>;
#[inline]
fn bulk_expand(&self, rhs: &Line<T>) -> Line<T> {
Line::new_unchecked(
rhs.d() * self.as_inner().e2em() + rhs.ny() * self.as_inner().e1em(),
-(rhs.nx() * self.as_inner().e1em()) + rhs.d() * self.as_inner().epem(),
-(rhs.nx() * self.as_inner().e2em()) + -(rhs.ny() * self.as_inner().epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Line<T>>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
rhs.as_inner().d() * self.e2em() + rhs.as_inner().ny() * self.e1em(),
-(rhs.as_inner().nx() * self.e1em()) + rhs.as_inner().d() * self.epem(),
-(rhs.as_inner().nx() * self.e2em()) + -(rhs.as_inner().ny() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Line<T>>> for Unit<FlatPoint<T>> {
type Output = Line<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
rhs.as_inner().d() * self.as_inner().e2em()
+ rhs.as_inner().ny() * self.as_inner().e1em(),
-(rhs.as_inner().nx() * self.as_inner().e1em())
+ rhs.as_inner().d() * self.as_inner().epem(),
-(rhs.as_inner().nx() * self.as_inner().e2em())
+ -(rhs.as_inner().ny() * self.as_inner().epem()),
)
}
}
#[doc = "Bulk expansion of [`FlatPoint`] with [`PointPair`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<PointPair<T>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &PointPair<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e1em() * self.e1em()) + -(rhs.e2em() * self.e2em()) + -(rhs.epem() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<PointPair<T>> for Unit<FlatPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &PointPair<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e1em() * self.as_inner().e1em())
+ -(rhs.e2em() * self.as_inner().e2em())
+ -(rhs.epem() * self.as_inner().epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<PointPair<T>>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<PointPair<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e1em() * self.e1em())
+ -(rhs.as_inner().e2em() * self.e2em())
+ -(rhs.as_inner().epem() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<PointPair<T>>> for Unit<FlatPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<PointPair<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e1em() * self.as_inner().e1em())
+ -(rhs.as_inner().e2em() * self.as_inner().e2em())
+ -(rhs.as_inner().epem() * self.as_inner().epem()),
)
}
}
#[doc = "Bulk expansion of [`FlatPoint`] with [`Pseudoscalar`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Pseudoscalar<T>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn bulk_expand(&self, rhs: &Pseudoscalar<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(rhs.ps() * self.e1em()),
-(rhs.ps() * self.e2em()),
-(rhs.ps() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Pseudoscalar<T>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn bulk_expand(&self, rhs: &Pseudoscalar<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(rhs.ps() * self.as_inner().e1em()),
-(rhs.ps() * self.as_inner().e2em()),
-(rhs.ps() * self.as_inner().epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Pseudoscalar<T>>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(rhs.as_inner().ps() * self.e1em()),
-(rhs.as_inner().ps() * self.e2em()),
-(rhs.as_inner().ps() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Pseudoscalar<T>>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
-(rhs.as_inner().ps() * self.as_inner().e1em()),
-(rhs.as_inner().ps() * self.as_inner().e2em()),
-(rhs.as_inner().ps() * self.as_inner().epem()),
)
}
}
#[doc = "Bulk expansion of [`Line`] with [`Circle`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Circle<T>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Circle<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e12em() * self.nx()) + -(rhs.e1epem() * self.ny()) + -(rhs.e2epem() * self.d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Circle<T>> for Unit<Line<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Circle<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e12em() * self.as_inner().nx())
+ -(rhs.e1epem() * self.as_inner().ny())
+ -(rhs.e2epem() * self.as_inner().d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Circle<T>>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Circle<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e12em() * self.nx())
+ -(rhs.as_inner().e1epem() * self.ny())
+ -(rhs.as_inner().e2epem() * self.d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Circle<T>>> for Unit<Line<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Circle<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e12em() * self.as_inner().nx())
+ -(rhs.as_inner().e1epem() * self.as_inner().ny())
+ -(rhs.as_inner().e2epem() * self.as_inner().d()),
)
}
}
#[doc = "Bulk expansion of [`Line`] with [`Line`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Line<T>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Line<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.d() * self.d()) + -(rhs.nx() * self.nx()) + -(rhs.ny() * self.ny()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Line<T>> for Unit<Line<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Line<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.d() * self.as_inner().d())
+ -(rhs.nx() * self.as_inner().nx())
+ -(rhs.ny() * self.as_inner().ny()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Line<T>>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Line<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().d() * self.d())
+ -(rhs.as_inner().nx() * self.nx())
+ -(rhs.as_inner().ny() * self.ny()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Line<T>>> for Unit<Line<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Line<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().d() * self.as_inner().d())
+ -(rhs.as_inner().nx() * self.as_inner().nx())
+ -(rhs.as_inner().ny() * self.as_inner().ny()),
)
}
}
#[doc = "Bulk expansion of [`Line`] with [`Pseudoscalar`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Pseudoscalar<T>> for Line<T> {
type Output = Line<T>;
#[inline]
fn bulk_expand(&self, rhs: &Pseudoscalar<T>) -> Line<T> {
Line::new_unchecked(
-(rhs.ps() * self.nx()),
-(rhs.ps() * self.ny()),
-(rhs.ps() * self.d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Pseudoscalar<T>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn bulk_expand(&self, rhs: &Pseudoscalar<T>) -> Line<T> {
Line::new_unchecked(
-(rhs.ps() * self.as_inner().nx()),
-(rhs.ps() * self.as_inner().ny()),
-(rhs.ps() * self.as_inner().d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Pseudoscalar<T>>> for Line<T> {
type Output = Line<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> Line<T> {
Line::new_unchecked(
-(rhs.as_inner().ps() * self.nx()),
-(rhs.as_inner().ps() * self.ny()),
-(rhs.as_inner().ps() * self.d()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Pseudoscalar<T>>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> Line<T> {
Line::new_unchecked(
-(rhs.as_inner().ps() * self.as_inner().nx()),
-(rhs.as_inner().ps() * self.as_inner().ny()),
-(rhs.as_inner().ps() * self.as_inner().d()),
)
}
}
#[doc = "Bulk expansion of [`PointPair`] with [`Circle`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Circle<T>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.e12em() * self.m() + rhs.e1epem() * self.e1ep() + rhs.e2epem() * self.e2ep(),
rhs.e1epem() * self.e1em() + rhs.e2epem() * self.e2em() + rhs.w() * self.m(),
-(rhs.e12em() * self.e1em()) + rhs.e2epem() * self.epem() + rhs.w() * self.e1ep(),
-(rhs.e12em() * self.e2em()) + -(rhs.e1epem() * self.epem()) + rhs.w() * self.e2ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Circle<T>> for Unit<PointPair<T>> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.e12em() * self.as_inner().m()
+ rhs.e1epem() * self.as_inner().e1ep()
+ rhs.e2epem() * self.as_inner().e2ep(),
rhs.e1epem() * self.as_inner().e1em()
+ rhs.e2epem() * self.as_inner().e2em()
+ rhs.w() * self.as_inner().m(),
-(rhs.e12em() * self.as_inner().e1em())
+ rhs.e2epem() * self.as_inner().epem()
+ rhs.w() * self.as_inner().e1ep(),
-(rhs.e12em() * self.as_inner().e2em())
+ -(rhs.e1epem() * self.as_inner().epem())
+ rhs.w() * self.as_inner().e2ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Circle<T>>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().e12em() * self.m()
+ rhs.as_inner().e1epem() * self.e1ep()
+ rhs.as_inner().e2epem() * self.e2ep(),
rhs.as_inner().e1epem() * self.e1em()
+ rhs.as_inner().e2epem() * self.e2em()
+ rhs.as_inner().w() * self.m(),
-(rhs.as_inner().e12em() * self.e1em())
+ rhs.as_inner().e2epem() * self.epem()
+ rhs.as_inner().w() * self.e1ep(),
-(rhs.as_inner().e12em() * self.e2em())
+ -(rhs.as_inner().e1epem() * self.epem())
+ rhs.as_inner().w() * self.e2ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Circle<T>>> for Unit<PointPair<T>> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().e12em() * self.as_inner().m()
+ rhs.as_inner().e1epem() * self.as_inner().e1ep()
+ rhs.as_inner().e2epem() * self.as_inner().e2ep(),
rhs.as_inner().e1epem() * self.as_inner().e1em()
+ rhs.as_inner().e2epem() * self.as_inner().e2em()
+ rhs.as_inner().w() * self.as_inner().m(),
-(rhs.as_inner().e12em() * self.as_inner().e1em())
+ rhs.as_inner().e2epem() * self.as_inner().epem()
+ rhs.as_inner().w() * self.as_inner().e1ep(),
-(rhs.as_inner().e12em() * self.as_inner().e2em())
+ -(rhs.as_inner().e1epem() * self.as_inner().epem())
+ rhs.as_inner().w() * self.as_inner().e2ep(),
)
}
}
#[doc = "Bulk expansion of [`PointPair`] with [`FlatPoint`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<FlatPoint<T>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &FlatPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e1em() * self.e1em()) + -(rhs.e2em() * self.e2em()) + -(rhs.epem() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<FlatPoint<T>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &FlatPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e1em() * self.as_inner().e1em())
+ -(rhs.e2em() * self.as_inner().e2em())
+ -(rhs.epem() * self.as_inner().epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<FlatPoint<T>>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<FlatPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e1em() * self.e1em())
+ -(rhs.as_inner().e2em() * self.e2em())
+ -(rhs.as_inner().epem() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<FlatPoint<T>>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<FlatPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e1em() * self.as_inner().e1em())
+ -(rhs.as_inner().e2em() * self.as_inner().e2em())
+ -(rhs.as_inner().epem() * self.as_inner().epem()),
)
}
}
#[doc = "Bulk expansion of [`PointPair`] with [`Line`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Line<T>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Line<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.d() * self.e2ep() + rhs.nx() * self.m() + rhs.ny() * self.e1ep(),
rhs.d() * self.e2em() + rhs.ny() * self.e1em(),
-(rhs.nx() * self.e1em()) + rhs.d() * self.epem(),
-(rhs.nx() * self.e2em()) + -(rhs.ny() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Line<T>> for Unit<PointPair<T>> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Line<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.d() * self.as_inner().e2ep()
+ rhs.nx() * self.as_inner().m()
+ rhs.ny() * self.as_inner().e1ep(),
rhs.d() * self.as_inner().e2em() + rhs.ny() * self.as_inner().e1em(),
-(rhs.nx() * self.as_inner().e1em()) + rhs.d() * self.as_inner().epem(),
-(rhs.nx() * self.as_inner().e2em()) + -(rhs.ny() * self.as_inner().epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Line<T>>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Line<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().d() * self.e2ep()
+ rhs.as_inner().nx() * self.m()
+ rhs.as_inner().ny() * self.e1ep(),
rhs.as_inner().d() * self.e2em() + rhs.as_inner().ny() * self.e1em(),
-(rhs.as_inner().nx() * self.e1em()) + rhs.as_inner().d() * self.epem(),
-(rhs.as_inner().nx() * self.e2em()) + -(rhs.as_inner().ny() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Line<T>>> for Unit<PointPair<T>> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Line<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().d() * self.as_inner().e2ep()
+ rhs.as_inner().nx() * self.as_inner().m()
+ rhs.as_inner().ny() * self.as_inner().e1ep(),
rhs.as_inner().d() * self.as_inner().e2em()
+ rhs.as_inner().ny() * self.as_inner().e1em(),
-(rhs.as_inner().nx() * self.as_inner().e1em())
+ rhs.as_inner().d() * self.as_inner().epem(),
-(rhs.as_inner().nx() * self.as_inner().e2em())
+ -(rhs.as_inner().ny() * self.as_inner().epem()),
)
}
}
#[doc = "Bulk expansion of [`PointPair`] with [`PointPair`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<PointPair<T>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &PointPair<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e1em() * self.e1em())
+ -(rhs.e2em() * self.e2em())
+ -(rhs.epem() * self.epem())
+ rhs.e1ep() * self.e1ep()
+ rhs.e2ep() * self.e2ep()
+ rhs.m() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<PointPair<T>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &PointPair<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e1em() * self.as_inner().e1em())
+ -(rhs.e2em() * self.as_inner().e2em())
+ -(rhs.epem() * self.as_inner().epem())
+ rhs.e1ep() * self.as_inner().e1ep()
+ rhs.e2ep() * self.as_inner().e2ep()
+ rhs.m() * self.as_inner().m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<PointPair<T>>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<PointPair<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e1em() * self.e1em())
+ -(rhs.as_inner().e2em() * self.e2em())
+ -(rhs.as_inner().epem() * self.epem())
+ rhs.as_inner().e1ep() * self.e1ep()
+ rhs.as_inner().e2ep() * self.e2ep()
+ rhs.as_inner().m() * self.m(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<PointPair<T>>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<PointPair<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e1em() * self.as_inner().e1em())
+ -(rhs.as_inner().e2em() * self.as_inner().e2em())
+ -(rhs.as_inner().epem() * self.as_inner().epem())
+ rhs.as_inner().e1ep() * self.as_inner().e1ep()
+ rhs.as_inner().e2ep() * self.as_inner().e2ep()
+ rhs.as_inner().m() * self.as_inner().m(),
)
}
}
#[doc = "Bulk expansion of [`PointPair`] with [`Pseudoscalar`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Pseudoscalar<T>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn bulk_expand(&self, rhs: &Pseudoscalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.ps() * self.m()),
-(rhs.ps() * self.e1ep()),
-(rhs.ps() * self.e2ep()),
-(rhs.ps() * self.e1em()),
-(rhs.ps() * self.e2em()),
-(rhs.ps() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Pseudoscalar<T>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn bulk_expand(&self, rhs: &Pseudoscalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.ps() * self.as_inner().m()),
-(rhs.ps() * self.as_inner().e1ep()),
-(rhs.ps() * self.as_inner().e2ep()),
-(rhs.ps() * self.as_inner().e1em()),
-(rhs.ps() * self.as_inner().e2em()),
-(rhs.ps() * self.as_inner().epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Pseudoscalar<T>>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().ps() * self.m()),
-(rhs.as_inner().ps() * self.e1ep()),
-(rhs.as_inner().ps() * self.e2ep()),
-(rhs.as_inner().ps() * self.e1em()),
-(rhs.as_inner().ps() * self.e2em()),
-(rhs.as_inner().ps() * self.epem()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Pseudoscalar<T>>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().ps() * self.as_inner().m()),
-(rhs.as_inner().ps() * self.as_inner().e1ep()),
-(rhs.as_inner().ps() * self.as_inner().e2ep()),
-(rhs.as_inner().ps() * self.as_inner().e1em()),
-(rhs.as_inner().ps() * self.as_inner().e2em()),
-(rhs.as_inner().ps() * self.as_inner().epem()),
)
}
}
#[doc = "Bulk expansion of [`Pseudoscalar`] with [`Pseudoscalar`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Pseudoscalar<T>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(rhs.ps() * self.ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Pseudoscalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(rhs.ps() * self.as_inner().ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Pseudoscalar<T>>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(rhs.as_inner().ps() * self.ps()))
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Pseudoscalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(rhs.as_inner().ps() * self.as_inner().ps()))
}
}
#[doc = "Bulk expansion of [`RoundPoint`] with [`Circle`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Circle<T>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn bulk_expand(&self, rhs: &Circle<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.e1epem() * self.x()) + -(rhs.e2epem() * self.y()),
-(rhs.e2epem() * self.ep()) + rhs.e12em() * self.x(),
rhs.e12em() * self.y() + rhs.e1epem() * self.ep(),
-(rhs.e2epem() * self.em()) + rhs.w() * self.x(),
rhs.e1epem() * self.em() + rhs.w() * self.y(),
-(rhs.e12em() * self.em()) + rhs.w() * self.ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Circle<T>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn bulk_expand(&self, rhs: &Circle<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.e1epem() * self.as_inner().x()) + -(rhs.e2epem() * self.as_inner().y()),
-(rhs.e2epem() * self.as_inner().ep()) + rhs.e12em() * self.as_inner().x(),
rhs.e12em() * self.as_inner().y() + rhs.e1epem() * self.as_inner().ep(),
-(rhs.e2epem() * self.as_inner().em()) + rhs.w() * self.as_inner().x(),
rhs.e1epem() * self.as_inner().em() + rhs.w() * self.as_inner().y(),
-(rhs.e12em() * self.as_inner().em()) + rhs.w() * self.as_inner().ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Circle<T>>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Circle<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().e1epem() * self.x()) + -(rhs.as_inner().e2epem() * self.y()),
-(rhs.as_inner().e2epem() * self.ep()) + rhs.as_inner().e12em() * self.x(),
rhs.as_inner().e12em() * self.y() + rhs.as_inner().e1epem() * self.ep(),
-(rhs.as_inner().e2epem() * self.em()) + rhs.as_inner().w() * self.x(),
rhs.as_inner().e1epem() * self.em() + rhs.as_inner().w() * self.y(),
-(rhs.as_inner().e12em() * self.em()) + rhs.as_inner().w() * self.ep(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Circle<T>>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Circle<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().e1epem() * self.as_inner().x())
+ -(rhs.as_inner().e2epem() * self.as_inner().y()),
-(rhs.as_inner().e2epem() * self.as_inner().ep())
+ rhs.as_inner().e12em() * self.as_inner().x(),
rhs.as_inner().e12em() * self.as_inner().y()
+ rhs.as_inner().e1epem() * self.as_inner().ep(),
-(rhs.as_inner().e2epem() * self.as_inner().em())
+ rhs.as_inner().w() * self.as_inner().x(),
rhs.as_inner().e1epem() * self.as_inner().em()
+ rhs.as_inner().w() * self.as_inner().y(),
-(rhs.as_inner().e12em() * self.as_inner().em())
+ rhs.as_inner().w() * self.as_inner().ep(),
)
}
}
#[doc = "Bulk expansion of [`RoundPoint`] with [`FlatPoint`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<FlatPoint<T>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &FlatPoint<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.e1em() * self.x()) + -(rhs.e2em() * self.y()) + -(rhs.epem() * self.ep()),
-(rhs.epem() * self.em()),
rhs.e2em() * self.em(),
-(rhs.e1em() * self.em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<FlatPoint<T>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &FlatPoint<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.e1em() * self.as_inner().x())
+ -(rhs.e2em() * self.as_inner().y())
+ -(rhs.epem() * self.as_inner().ep()),
-(rhs.epem() * self.as_inner().em()),
rhs.e2em() * self.as_inner().em(),
-(rhs.e1em() * self.as_inner().em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<FlatPoint<T>>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<FlatPoint<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().e1em() * self.x())
+ -(rhs.as_inner().e2em() * self.y())
+ -(rhs.as_inner().epem() * self.ep()),
-(rhs.as_inner().epem() * self.em()),
rhs.as_inner().e2em() * self.em(),
-(rhs.as_inner().e1em() * self.em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<FlatPoint<T>>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<FlatPoint<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().e1em() * self.as_inner().x())
+ -(rhs.as_inner().e2em() * self.as_inner().y())
+ -(rhs.as_inner().epem() * self.as_inner().ep()),
-(rhs.as_inner().epem() * self.as_inner().em()),
rhs.as_inner().e2em() * self.as_inner().em(),
-(rhs.as_inner().e1em() * self.as_inner().em()),
)
}
}
#[doc = "Bulk expansion of [`RoundPoint`] with [`Line`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Line<T>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn bulk_expand(&self, rhs: &Line<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.d() * self.y()) + -(rhs.ny() * self.x()),
-(rhs.d() * self.ep()) + rhs.nx() * self.x(),
rhs.nx() * self.y() + rhs.ny() * self.ep(),
-(rhs.d() * self.em()),
rhs.ny() * self.em(),
-(rhs.nx() * self.em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Line<T>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn bulk_expand(&self, rhs: &Line<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.d() * self.as_inner().y()) + -(rhs.ny() * self.as_inner().x()),
-(rhs.d() * self.as_inner().ep()) + rhs.nx() * self.as_inner().x(),
rhs.nx() * self.as_inner().y() + rhs.ny() * self.as_inner().ep(),
-(rhs.d() * self.as_inner().em()),
rhs.ny() * self.as_inner().em(),
-(rhs.nx() * self.as_inner().em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Line<T>>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Line<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().d() * self.y()) + -(rhs.as_inner().ny() * self.x()),
-(rhs.as_inner().d() * self.ep()) + rhs.as_inner().nx() * self.x(),
rhs.as_inner().nx() * self.y() + rhs.as_inner().ny() * self.ep(),
-(rhs.as_inner().d() * self.em()),
rhs.as_inner().ny() * self.em(),
-(rhs.as_inner().nx() * self.em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Line<T>>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Line<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().d() * self.as_inner().y())
+ -(rhs.as_inner().ny() * self.as_inner().x()),
-(rhs.as_inner().d() * self.as_inner().ep())
+ rhs.as_inner().nx() * self.as_inner().x(),
rhs.as_inner().nx() * self.as_inner().y() + rhs.as_inner().ny() * self.as_inner().ep(),
-(rhs.as_inner().d() * self.as_inner().em()),
rhs.as_inner().ny() * self.as_inner().em(),
-(rhs.as_inner().nx() * self.as_inner().em()),
)
}
}
#[doc = "Bulk expansion of [`RoundPoint`] with [`PointPair`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<PointPair<T>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &PointPair<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.e1em() * self.x()) + -(rhs.e2em() * self.y()) + -(rhs.epem() * self.ep()),
-(rhs.e1ep() * self.x()) + -(rhs.e2ep() * self.y()) + -(rhs.epem() * self.em()),
-(rhs.e2ep() * self.ep()) + rhs.e2em() * self.em() + rhs.m() * self.x(),
-(rhs.e1em() * self.em()) + rhs.e1ep() * self.ep() + rhs.m() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<PointPair<T>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &PointPair<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.e1em() * self.as_inner().x())
+ -(rhs.e2em() * self.as_inner().y())
+ -(rhs.epem() * self.as_inner().ep()),
-(rhs.e1ep() * self.as_inner().x())
+ -(rhs.e2ep() * self.as_inner().y())
+ -(rhs.epem() * self.as_inner().em()),
-(rhs.e2ep() * self.as_inner().ep())
+ rhs.e2em() * self.as_inner().em()
+ rhs.m() * self.as_inner().x(),
-(rhs.e1em() * self.as_inner().em())
+ rhs.e1ep() * self.as_inner().ep()
+ rhs.m() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<PointPair<T>>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<PointPair<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().e1em() * self.x())
+ -(rhs.as_inner().e2em() * self.y())
+ -(rhs.as_inner().epem() * self.ep()),
-(rhs.as_inner().e1ep() * self.x())
+ -(rhs.as_inner().e2ep() * self.y())
+ -(rhs.as_inner().epem() * self.em()),
-(rhs.as_inner().e2ep() * self.ep())
+ rhs.as_inner().e2em() * self.em()
+ rhs.as_inner().m() * self.x(),
-(rhs.as_inner().e1em() * self.em())
+ rhs.as_inner().e1ep() * self.ep()
+ rhs.as_inner().m() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<PointPair<T>>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<PointPair<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().e1em() * self.as_inner().x())
+ -(rhs.as_inner().e2em() * self.as_inner().y())
+ -(rhs.as_inner().epem() * self.as_inner().ep()),
-(rhs.as_inner().e1ep() * self.as_inner().x())
+ -(rhs.as_inner().e2ep() * self.as_inner().y())
+ -(rhs.as_inner().epem() * self.as_inner().em()),
-(rhs.as_inner().e2ep() * self.as_inner().ep())
+ rhs.as_inner().e2em() * self.as_inner().em()
+ rhs.as_inner().m() * self.as_inner().x(),
-(rhs.as_inner().e1em() * self.as_inner().em())
+ rhs.as_inner().e1ep() * self.as_inner().ep()
+ rhs.as_inner().m() * self.as_inner().y(),
)
}
}
#[doc = "Bulk expansion of [`RoundPoint`] with [`Pseudoscalar`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Pseudoscalar<T>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_expand(&self, rhs: &Pseudoscalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.ps() * self.x()),
-(rhs.ps() * self.y()),
-(rhs.ps() * self.ep()),
-(rhs.ps() * self.em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Pseudoscalar<T>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_expand(&self, rhs: &Pseudoscalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.ps() * self.as_inner().x()),
-(rhs.ps() * self.as_inner().y()),
-(rhs.ps() * self.as_inner().ep()),
-(rhs.ps() * self.as_inner().em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Pseudoscalar<T>>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().ps() * self.x()),
-(rhs.as_inner().ps() * self.y()),
-(rhs.as_inner().ps() * self.ep()),
-(rhs.as_inner().ps() * self.em()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Pseudoscalar<T>>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().ps() * self.as_inner().x()),
-(rhs.as_inner().ps() * self.as_inner().y()),
-(rhs.as_inner().ps() * self.as_inner().ep()),
-(rhs.as_inner().ps() * self.as_inner().em()),
)
}
}
#[doc = "Bulk expansion of [`RoundPoint`] with [`RoundPoint`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<RoundPoint<T>> for RoundPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &RoundPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.em() * self.em())
+ rhs.ep() * self.ep()
+ rhs.x() * self.x()
+ rhs.y() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<RoundPoint<T>> for Unit<RoundPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &RoundPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.em() * self.as_inner().em())
+ rhs.ep() * self.as_inner().ep()
+ rhs.x() * self.as_inner().x()
+ rhs.y() * self.as_inner().y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<RoundPoint<T>>> for RoundPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<RoundPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().em() * self.em())
+ rhs.as_inner().ep() * self.ep()
+ rhs.as_inner().x() * self.x()
+ rhs.as_inner().y() * self.y(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<RoundPoint<T>>> for Unit<RoundPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<RoundPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().em() * self.as_inner().em())
+ rhs.as_inner().ep() * self.as_inner().ep()
+ rhs.as_inner().x() * self.as_inner().x()
+ rhs.as_inner().y() * self.as_inner().y(),
)
}
}
#[doc = "Bulk expansion of [`Scalar`] with [`Circle`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Circle<T>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_expand(&self, rhs: &Circle<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.e2epem() * self.s(),
-(rhs.e1epem() * self.s()),
rhs.e12em() * self.s(),
rhs.w() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Circle<T>> for Unit<Scalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_expand(&self, rhs: &Circle<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.e2epem() * self.as_inner().s(),
-(rhs.e1epem() * self.as_inner().s()),
rhs.e12em() * self.as_inner().s(),
rhs.w() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Circle<T>>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Circle<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().e2epem() * self.s(),
-(rhs.as_inner().e1epem() * self.s()),
rhs.as_inner().e12em() * self.s(),
rhs.as_inner().w() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Circle<T>>> for Unit<Scalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Circle<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().e2epem() * self.as_inner().s(),
-(rhs.as_inner().e1epem() * self.as_inner().s()),
rhs.as_inner().e12em() * self.as_inner().s(),
rhs.as_inner().w() * self.as_inner().s(),
)
}
}
#[doc = "Bulk expansion of [`Scalar`] with [`PointPair`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<PointPair<T>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn bulk_expand(&self, rhs: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.epem() * self.s()),
rhs.e2em() * self.s(),
-(rhs.e1em() * self.s()),
rhs.e2ep() * self.s(),
-(rhs.e1ep() * self.s()),
rhs.m() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<PointPair<T>> for Unit<Scalar<T>> {
type Output = PointPair<T>;
#[inline]
fn bulk_expand(&self, rhs: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.epem() * self.as_inner().s()),
rhs.e2em() * self.as_inner().s(),
-(rhs.e1em() * self.as_inner().s()),
rhs.e2ep() * self.as_inner().s(),
-(rhs.e1ep() * self.as_inner().s()),
rhs.m() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<PointPair<T>>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().epem() * self.s()),
rhs.as_inner().e2em() * self.s(),
-(rhs.as_inner().e1em() * self.s()),
rhs.as_inner().e2ep() * self.s(),
-(rhs.as_inner().e1ep() * self.s()),
rhs.as_inner().m() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<PointPair<T>>> for Unit<Scalar<T>> {
type Output = PointPair<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
-(rhs.as_inner().epem() * self.as_inner().s()),
rhs.as_inner().e2em() * self.as_inner().s(),
-(rhs.as_inner().e1em() * self.as_inner().s()),
rhs.as_inner().e2ep() * self.as_inner().s(),
-(rhs.as_inner().e1ep() * self.as_inner().s()),
rhs.as_inner().m() * self.as_inner().s(),
)
}
}
#[doc = "Bulk expansion of [`Scalar`] with [`Pseudoscalar`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Pseudoscalar<T>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Pseudoscalar<T>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.ps() * self.s()))
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Pseudoscalar<T>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Pseudoscalar<T>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.ps() * self.as_inner().s()))
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Pseudoscalar<T>>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.as_inner().ps() * self.s()))
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Pseudoscalar<T>>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(-(rhs.as_inner().ps() * self.as_inner().s()))
}
}
#[doc = "Bulk expansion of [`Scalar`] with [`RoundPoint`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<RoundPoint<T>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &RoundPoint<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.em() * self.s(),
rhs.ep() * self.s(),
-(rhs.y() * self.s()),
rhs.x() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<RoundPoint<T>> for Unit<Scalar<T>> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &RoundPoint<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.em() * self.as_inner().s(),
rhs.ep() * self.as_inner().s(),
-(rhs.y() * self.as_inner().s()),
rhs.x() * self.as_inner().s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<RoundPoint<T>>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<RoundPoint<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().em() * self.s(),
rhs.as_inner().ep() * self.s(),
-(rhs.as_inner().y() * self.s()),
rhs.as_inner().x() * self.s(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<RoundPoint<T>>> for Unit<Scalar<T>> {
type Output = Circle<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<RoundPoint<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().em() * self.as_inner().s(),
rhs.as_inner().ep() * self.as_inner().s(),
-(rhs.as_inner().y() * self.as_inner().s()),
rhs.as_inner().x() * self.as_inner().s(),
)
}
}
#[doc = "Bulk expansion of [`Scalar`] with [`Scalar`].\n\nThe bulk expansion is the dual of bulk contraction, extracting the\nEuclidean component of the exterior product complement."]
impl<T: Float> BulkExpand<Scalar<T>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Scalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.s() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Scalar<T>> for Unit<Scalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Scalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.s() * self.as_inner().s())
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Scalar<T>>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Scalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.as_inner().s() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> BulkExpand<Unit<Scalar<T>>> for Unit<Scalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn bulk_expand(&self, rhs: &Unit<Scalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.as_inner().s() * self.as_inner().s())
}
}
#[doc = "Weight expansion of [`Circle`] with [`Circle`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Circle<T>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Circle<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.w() * self.w())
+ rhs.e12em() * self.e12em()
+ rhs.e1epem() * self.e1epem()
+ rhs.e2epem() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Circle<T>> for Unit<Circle<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Circle<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.w() * self.as_inner().w())
+ rhs.e12em() * self.as_inner().e12em()
+ rhs.e1epem() * self.as_inner().e1epem()
+ rhs.e2epem() * self.as_inner().e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Circle<T>>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Circle<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().w() * self.w())
+ rhs.as_inner().e12em() * self.e12em()
+ rhs.as_inner().e1epem() * self.e1epem()
+ rhs.as_inner().e2epem() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Circle<T>>> for Unit<Circle<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Circle<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().w() * self.as_inner().w())
+ rhs.as_inner().e12em() * self.as_inner().e12em()
+ rhs.as_inner().e1epem() * self.as_inner().e1epem()
+ rhs.as_inner().e2epem() * self.as_inner().e2epem(),
)
}
}
#[doc = "Weight expansion of [`Circle`] with [`Line`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Line<T>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Line<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.d() * self.e2epem() + rhs.nx() * self.e12em() + rhs.ny() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Line<T>> for Unit<Circle<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Line<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.d() * self.as_inner().e2epem()
+ rhs.nx() * self.as_inner().e12em()
+ rhs.ny() * self.as_inner().e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Line<T>>> for Circle<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Line<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.as_inner().d() * self.e2epem()
+ rhs.as_inner().nx() * self.e12em()
+ rhs.as_inner().ny() * self.e1epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Line<T>>> for Unit<Circle<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Line<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.as_inner().d() * self.as_inner().e2epem()
+ rhs.as_inner().nx() * self.as_inner().e12em()
+ rhs.as_inner().ny() * self.as_inner().e1epem(),
)
}
}
#[doc = "Weight expansion of [`Circle`] with [`Pseudoscalar`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Pseudoscalar<T>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Pseudoscalar<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.ps() * self.w(),
rhs.ps() * self.e12em(),
rhs.ps() * self.e1epem(),
rhs.ps() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Pseudoscalar<T>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Pseudoscalar<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.ps() * self.as_inner().w(),
rhs.ps() * self.as_inner().e12em(),
rhs.ps() * self.as_inner().e1epem(),
rhs.ps() * self.as_inner().e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Pseudoscalar<T>>> for Circle<T> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().ps() * self.w(),
rhs.as_inner().ps() * self.e12em(),
rhs.as_inner().ps() * self.e1epem(),
rhs.as_inner().ps() * self.e2epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Pseudoscalar<T>>> for Unit<Circle<T>> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().ps() * self.as_inner().w(),
rhs.as_inner().ps() * self.as_inner().e12em(),
rhs.as_inner().ps() * self.as_inner().e1epem(),
rhs.as_inner().ps() * self.as_inner().e2epem(),
)
}
}
#[doc = "Weight expansion of [`FlatPoint`] with [`Circle`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Circle<T>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn weight_expand(&self, rhs: &Circle<T>) -> Line<T> {
Line::new_unchecked(
-(rhs.e1epem() * self.e1em()) + -(rhs.e2epem() * self.e2em()),
-(rhs.e2epem() * self.epem()) + rhs.e12em() * self.e1em(),
rhs.e12em() * self.e2em() + rhs.e1epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Circle<T>> for Unit<FlatPoint<T>> {
type Output = Line<T>;
#[inline]
fn weight_expand(&self, rhs: &Circle<T>) -> Line<T> {
Line::new_unchecked(
-(rhs.e1epem() * self.as_inner().e1em()) + -(rhs.e2epem() * self.as_inner().e2em()),
-(rhs.e2epem() * self.as_inner().epem()) + rhs.e12em() * self.as_inner().e1em(),
rhs.e12em() * self.as_inner().e2em() + rhs.e1epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Circle<T>>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Circle<T>>) -> Line<T> {
Line::new_unchecked(
-(rhs.as_inner().e1epem() * self.e1em()) + -(rhs.as_inner().e2epem() * self.e2em()),
-(rhs.as_inner().e2epem() * self.epem()) + rhs.as_inner().e12em() * self.e1em(),
rhs.as_inner().e12em() * self.e2em() + rhs.as_inner().e1epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Circle<T>>> for Unit<FlatPoint<T>> {
type Output = Line<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Circle<T>>) -> Line<T> {
Line::new_unchecked(
-(rhs.as_inner().e1epem() * self.as_inner().e1em())
+ -(rhs.as_inner().e2epem() * self.as_inner().e2em()),
-(rhs.as_inner().e2epem() * self.as_inner().epem())
+ rhs.as_inner().e12em() * self.as_inner().e1em(),
rhs.as_inner().e12em() * self.as_inner().e2em()
+ rhs.as_inner().e1epem() * self.as_inner().epem(),
)
}
}
#[doc = "Weight expansion of [`FlatPoint`] with [`FlatPoint`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<FlatPoint<T>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &FlatPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.e1em() * self.e1em() + rhs.e2em() * self.e2em() + rhs.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<FlatPoint<T>> for Unit<FlatPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &FlatPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<FlatPoint<T>>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<FlatPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<FlatPoint<T>>> for Unit<FlatPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<FlatPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Weight expansion of [`FlatPoint`] with [`Line`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Line<T>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn weight_expand(&self, rhs: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(rhs.d() * self.e2em()) + -(rhs.ny() * self.e1em()),
-(rhs.d() * self.epem()) + rhs.nx() * self.e1em(),
rhs.nx() * self.e2em() + rhs.ny() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Line<T>> for Unit<FlatPoint<T>> {
type Output = Line<T>;
#[inline]
fn weight_expand(&self, rhs: &Line<T>) -> Line<T> {
Line::new_unchecked(
-(rhs.d() * self.as_inner().e2em()) + -(rhs.ny() * self.as_inner().e1em()),
-(rhs.d() * self.as_inner().epem()) + rhs.nx() * self.as_inner().e1em(),
rhs.nx() * self.as_inner().e2em() + rhs.ny() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Line<T>>> for FlatPoint<T> {
type Output = Line<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(rhs.as_inner().d() * self.e2em()) + -(rhs.as_inner().ny() * self.e1em()),
-(rhs.as_inner().d() * self.epem()) + rhs.as_inner().nx() * self.e1em(),
rhs.as_inner().nx() * self.e2em() + rhs.as_inner().ny() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Line<T>>> for Unit<FlatPoint<T>> {
type Output = Line<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Line<T>>) -> Line<T> {
Line::new_unchecked(
-(rhs.as_inner().d() * self.as_inner().e2em())
+ -(rhs.as_inner().ny() * self.as_inner().e1em()),
-(rhs.as_inner().d() * self.as_inner().epem())
+ rhs.as_inner().nx() * self.as_inner().e1em(),
rhs.as_inner().nx() * self.as_inner().e2em()
+ rhs.as_inner().ny() * self.as_inner().epem(),
)
}
}
#[doc = "Weight expansion of [`FlatPoint`] with [`PointPair`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<PointPair<T>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &PointPair<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.e1em() * self.e1em() + rhs.e2em() * self.e2em() + rhs.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<PointPair<T>> for Unit<FlatPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &PointPair<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<PointPair<T>>> for FlatPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<PointPair<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<PointPair<T>>> for Unit<FlatPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<PointPair<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Weight expansion of [`FlatPoint`] with [`Pseudoscalar`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Pseudoscalar<T>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn weight_expand(&self, rhs: &Pseudoscalar<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.ps() * self.e1em(),
rhs.ps() * self.e2em(),
rhs.ps() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Pseudoscalar<T>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn weight_expand(&self, rhs: &Pseudoscalar<T>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.ps() * self.as_inner().e1em(),
rhs.ps() * self.as_inner().e2em(),
rhs.ps() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Pseudoscalar<T>>> for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.as_inner().ps() * self.e1em(),
rhs.as_inner().ps() * self.e2em(),
rhs.as_inner().ps() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Pseudoscalar<T>>> for Unit<FlatPoint<T>> {
type Output = FlatPoint<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> FlatPoint<T> {
FlatPoint::new_unchecked(
rhs.as_inner().ps() * self.as_inner().e1em(),
rhs.as_inner().ps() * self.as_inner().e2em(),
rhs.as_inner().ps() * self.as_inner().epem(),
)
}
}
#[doc = "Weight expansion of [`Line`] with [`Circle`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Circle<T>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Circle<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.e12em() * self.nx() + rhs.e1epem() * self.ny() + rhs.e2epem() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Circle<T>> for Unit<Line<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Circle<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.e12em() * self.as_inner().nx()
+ rhs.e1epem() * self.as_inner().ny()
+ rhs.e2epem() * self.as_inner().d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Circle<T>>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Circle<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.as_inner().e12em() * self.nx()
+ rhs.as_inner().e1epem() * self.ny()
+ rhs.as_inner().e2epem() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Circle<T>>> for Unit<Line<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Circle<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.as_inner().e12em() * self.as_inner().nx()
+ rhs.as_inner().e1epem() * self.as_inner().ny()
+ rhs.as_inner().e2epem() * self.as_inner().d(),
)
}
}
#[doc = "Weight expansion of [`Line`] with [`Line`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Line<T>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Line<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.d() * self.d() + rhs.nx() * self.nx() + rhs.ny() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Line<T>> for Unit<Line<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Line<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.d() * self.as_inner().d()
+ rhs.nx() * self.as_inner().nx()
+ rhs.ny() * self.as_inner().ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Line<T>>> for Line<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Line<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.as_inner().d() * self.d()
+ rhs.as_inner().nx() * self.nx()
+ rhs.as_inner().ny() * self.ny(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Line<T>>> for Unit<Line<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Line<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.as_inner().d() * self.as_inner().d()
+ rhs.as_inner().nx() * self.as_inner().nx()
+ rhs.as_inner().ny() * self.as_inner().ny(),
)
}
}
#[doc = "Weight expansion of [`Line`] with [`Pseudoscalar`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Pseudoscalar<T>> for Line<T> {
type Output = Line<T>;
#[inline]
fn weight_expand(&self, rhs: &Pseudoscalar<T>) -> Line<T> {
Line::new_unchecked(
rhs.ps() * self.nx(),
rhs.ps() * self.ny(),
rhs.ps() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Pseudoscalar<T>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn weight_expand(&self, rhs: &Pseudoscalar<T>) -> Line<T> {
Line::new_unchecked(
rhs.ps() * self.as_inner().nx(),
rhs.ps() * self.as_inner().ny(),
rhs.ps() * self.as_inner().d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Pseudoscalar<T>>> for Line<T> {
type Output = Line<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> Line<T> {
Line::new_unchecked(
rhs.as_inner().ps() * self.nx(),
rhs.as_inner().ps() * self.ny(),
rhs.as_inner().ps() * self.d(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Pseudoscalar<T>>> for Unit<Line<T>> {
type Output = Line<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> Line<T> {
Line::new_unchecked(
rhs.as_inner().ps() * self.as_inner().nx(),
rhs.as_inner().ps() * self.as_inner().ny(),
rhs.as_inner().ps() * self.as_inner().d(),
)
}
}
#[doc = "Weight expansion of [`PointPair`] with [`Circle`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Circle<T>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.e12em() * self.m())
+ -(rhs.e1epem() * self.e1ep())
+ -(rhs.e2epem() * self.e2ep()),
-(rhs.e1epem() * self.e1em()) + -(rhs.e2epem() * self.e2em()) + -(rhs.w() * self.m()),
-(rhs.e2epem() * self.epem()) + -(rhs.w() * self.e1ep()) + rhs.e12em() * self.e1em(),
-(rhs.w() * self.e2ep()) + rhs.e12em() * self.e2em() + rhs.e1epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Circle<T>> for Unit<PointPair<T>> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Circle<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.e12em() * self.as_inner().m())
+ -(rhs.e1epem() * self.as_inner().e1ep())
+ -(rhs.e2epem() * self.as_inner().e2ep()),
-(rhs.e1epem() * self.as_inner().e1em())
+ -(rhs.e2epem() * self.as_inner().e2em())
+ -(rhs.w() * self.as_inner().m()),
-(rhs.e2epem() * self.as_inner().epem())
+ -(rhs.w() * self.as_inner().e1ep())
+ rhs.e12em() * self.as_inner().e1em(),
-(rhs.w() * self.as_inner().e2ep())
+ rhs.e12em() * self.as_inner().e2em()
+ rhs.e1epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Circle<T>>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().e12em() * self.m())
+ -(rhs.as_inner().e1epem() * self.e1ep())
+ -(rhs.as_inner().e2epem() * self.e2ep()),
-(rhs.as_inner().e1epem() * self.e1em())
+ -(rhs.as_inner().e2epem() * self.e2em())
+ -(rhs.as_inner().w() * self.m()),
-(rhs.as_inner().e2epem() * self.epem())
+ -(rhs.as_inner().w() * self.e1ep())
+ rhs.as_inner().e12em() * self.e1em(),
-(rhs.as_inner().w() * self.e2ep())
+ rhs.as_inner().e12em() * self.e2em()
+ rhs.as_inner().e1epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Circle<T>>> for Unit<PointPair<T>> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Circle<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().e12em() * self.as_inner().m())
+ -(rhs.as_inner().e1epem() * self.as_inner().e1ep())
+ -(rhs.as_inner().e2epem() * self.as_inner().e2ep()),
-(rhs.as_inner().e1epem() * self.as_inner().e1em())
+ -(rhs.as_inner().e2epem() * self.as_inner().e2em())
+ -(rhs.as_inner().w() * self.as_inner().m()),
-(rhs.as_inner().e2epem() * self.as_inner().epem())
+ -(rhs.as_inner().w() * self.as_inner().e1ep())
+ rhs.as_inner().e12em() * self.as_inner().e1em(),
-(rhs.as_inner().w() * self.as_inner().e2ep())
+ rhs.as_inner().e12em() * self.as_inner().e2em()
+ rhs.as_inner().e1epem() * self.as_inner().epem(),
)
}
}
#[doc = "Weight expansion of [`PointPair`] with [`FlatPoint`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<FlatPoint<T>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &FlatPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.e1em() * self.e1em() + rhs.e2em() * self.e2em() + rhs.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<FlatPoint<T>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &FlatPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<FlatPoint<T>>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<FlatPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<FlatPoint<T>>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<FlatPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Weight expansion of [`PointPair`] with [`Line`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Line<T>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Line<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.d() * self.e2ep()) + -(rhs.nx() * self.m()) + -(rhs.ny() * self.e1ep()),
-(rhs.d() * self.e2em()) + -(rhs.ny() * self.e1em()),
-(rhs.d() * self.epem()) + rhs.nx() * self.e1em(),
rhs.nx() * self.e2em() + rhs.ny() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Line<T>> for Unit<PointPair<T>> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Line<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.d() * self.as_inner().e2ep())
+ -(rhs.nx() * self.as_inner().m())
+ -(rhs.ny() * self.as_inner().e1ep()),
-(rhs.d() * self.as_inner().e2em()) + -(rhs.ny() * self.as_inner().e1em()),
-(rhs.d() * self.as_inner().epem()) + rhs.nx() * self.as_inner().e1em(),
rhs.nx() * self.as_inner().e2em() + rhs.ny() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Line<T>>> for PointPair<T> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Line<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().d() * self.e2ep())
+ -(rhs.as_inner().nx() * self.m())
+ -(rhs.as_inner().ny() * self.e1ep()),
-(rhs.as_inner().d() * self.e2em()) + -(rhs.as_inner().ny() * self.e1em()),
-(rhs.as_inner().d() * self.epem()) + rhs.as_inner().nx() * self.e1em(),
rhs.as_inner().nx() * self.e2em() + rhs.as_inner().ny() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Line<T>>> for Unit<PointPair<T>> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Line<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().d() * self.as_inner().e2ep())
+ -(rhs.as_inner().nx() * self.as_inner().m())
+ -(rhs.as_inner().ny() * self.as_inner().e1ep()),
-(rhs.as_inner().d() * self.as_inner().e2em())
+ -(rhs.as_inner().ny() * self.as_inner().e1em()),
-(rhs.as_inner().d() * self.as_inner().epem())
+ rhs.as_inner().nx() * self.as_inner().e1em(),
rhs.as_inner().nx() * self.as_inner().e2em()
+ rhs.as_inner().ny() * self.as_inner().epem(),
)
}
}
#[doc = "Weight expansion of [`PointPair`] with [`PointPair`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<PointPair<T>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &PointPair<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e1ep() * self.e1ep())
+ -(rhs.e2ep() * self.e2ep())
+ -(rhs.m() * self.m())
+ rhs.e1em() * self.e1em()
+ rhs.e2em() * self.e2em()
+ rhs.epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<PointPair<T>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &PointPair<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.e1ep() * self.as_inner().e1ep())
+ -(rhs.e2ep() * self.as_inner().e2ep())
+ -(rhs.m() * self.as_inner().m())
+ rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<PointPair<T>>> for PointPair<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<PointPair<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e1ep() * self.e1ep())
+ -(rhs.as_inner().e2ep() * self.e2ep())
+ -(rhs.as_inner().m() * self.m())
+ rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<PointPair<T>>> for Unit<PointPair<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<PointPair<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().e1ep() * self.as_inner().e1ep())
+ -(rhs.as_inner().e2ep() * self.as_inner().e2ep())
+ -(rhs.as_inner().m() * self.as_inner().m())
+ rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem(),
)
}
}
#[doc = "Weight expansion of [`PointPair`] with [`Pseudoscalar`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Pseudoscalar<T>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn weight_expand(&self, rhs: &Pseudoscalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.ps() * self.m(),
rhs.ps() * self.e1ep(),
rhs.ps() * self.e2ep(),
rhs.ps() * self.e1em(),
rhs.ps() * self.e2em(),
rhs.ps() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Pseudoscalar<T>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn weight_expand(&self, rhs: &Pseudoscalar<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.ps() * self.as_inner().m(),
rhs.ps() * self.as_inner().e1ep(),
rhs.ps() * self.as_inner().e2ep(),
rhs.ps() * self.as_inner().e1em(),
rhs.ps() * self.as_inner().e2em(),
rhs.ps() * self.as_inner().epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Pseudoscalar<T>>> for PointPair<T> {
type Output = PointPair<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().ps() * self.m(),
rhs.as_inner().ps() * self.e1ep(),
rhs.as_inner().ps() * self.e2ep(),
rhs.as_inner().ps() * self.e1em(),
rhs.as_inner().ps() * self.e2em(),
rhs.as_inner().ps() * self.epem(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Pseudoscalar<T>>> for Unit<PointPair<T>> {
type Output = PointPair<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().ps() * self.as_inner().m(),
rhs.as_inner().ps() * self.as_inner().e1ep(),
rhs.as_inner().ps() * self.as_inner().e2ep(),
rhs.as_inner().ps() * self.as_inner().e1em(),
rhs.as_inner().ps() * self.as_inner().e2em(),
rhs.as_inner().ps() * self.as_inner().epem(),
)
}
}
#[doc = "Weight expansion of [`Pseudoscalar`] with [`Pseudoscalar`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Pseudoscalar<T>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.ps() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Pseudoscalar<T>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Pseudoscalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.ps() * self.as_inner().ps())
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Pseudoscalar<T>>> for Pseudoscalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.as_inner().ps() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Pseudoscalar<T>>> for Unit<Pseudoscalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(rhs.as_inner().ps() * self.as_inner().ps())
}
}
#[doc = "Weight expansion of [`RoundPoint`] with [`Circle`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Circle<T>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn weight_expand(&self, rhs: &Circle<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.e1epem() * self.x() + rhs.e2epem() * self.y(),
-(rhs.e12em() * self.x()) + rhs.e2epem() * self.ep(),
-(rhs.e12em() * self.y()) + -(rhs.e1epem() * self.ep()),
-(rhs.w() * self.x()) + rhs.e2epem() * self.em(),
-(rhs.e1epem() * self.em()) + -(rhs.w() * self.y()),
-(rhs.w() * self.ep()) + rhs.e12em() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Circle<T>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn weight_expand(&self, rhs: &Circle<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.e1epem() * self.as_inner().x() + rhs.e2epem() * self.as_inner().y(),
-(rhs.e12em() * self.as_inner().x()) + rhs.e2epem() * self.as_inner().ep(),
-(rhs.e12em() * self.as_inner().y()) + -(rhs.e1epem() * self.as_inner().ep()),
-(rhs.w() * self.as_inner().x()) + rhs.e2epem() * self.as_inner().em(),
-(rhs.e1epem() * self.as_inner().em()) + -(rhs.w() * self.as_inner().y()),
-(rhs.w() * self.as_inner().ep()) + rhs.e12em() * self.as_inner().em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Circle<T>>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Circle<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().e1epem() * self.x() + rhs.as_inner().e2epem() * self.y(),
-(rhs.as_inner().e12em() * self.x()) + rhs.as_inner().e2epem() * self.ep(),
-(rhs.as_inner().e12em() * self.y()) + -(rhs.as_inner().e1epem() * self.ep()),
-(rhs.as_inner().w() * self.x()) + rhs.as_inner().e2epem() * self.em(),
-(rhs.as_inner().e1epem() * self.em()) + -(rhs.as_inner().w() * self.y()),
-(rhs.as_inner().w() * self.ep()) + rhs.as_inner().e12em() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Circle<T>>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Circle<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().e1epem() * self.as_inner().x()
+ rhs.as_inner().e2epem() * self.as_inner().y(),
-(rhs.as_inner().e12em() * self.as_inner().x())
+ rhs.as_inner().e2epem() * self.as_inner().ep(),
-(rhs.as_inner().e12em() * self.as_inner().y())
+ -(rhs.as_inner().e1epem() * self.as_inner().ep()),
-(rhs.as_inner().w() * self.as_inner().x())
+ rhs.as_inner().e2epem() * self.as_inner().em(),
-(rhs.as_inner().e1epem() * self.as_inner().em())
+ -(rhs.as_inner().w() * self.as_inner().y()),
-(rhs.as_inner().w() * self.as_inner().ep())
+ rhs.as_inner().e12em() * self.as_inner().em(),
)
}
}
#[doc = "Weight expansion of [`RoundPoint`] with [`FlatPoint`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<FlatPoint<T>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &FlatPoint<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.e1em() * self.x() + rhs.e2em() * self.y() + rhs.epem() * self.ep(),
rhs.epem() * self.em(),
-(rhs.e2em() * self.em()),
rhs.e1em() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<FlatPoint<T>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &FlatPoint<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.e1em() * self.as_inner().x()
+ rhs.e2em() * self.as_inner().y()
+ rhs.epem() * self.as_inner().ep(),
rhs.epem() * self.as_inner().em(),
-(rhs.e2em() * self.as_inner().em()),
rhs.e1em() * self.as_inner().em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<FlatPoint<T>>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<FlatPoint<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().e1em() * self.x()
+ rhs.as_inner().e2em() * self.y()
+ rhs.as_inner().epem() * self.ep(),
rhs.as_inner().epem() * self.em(),
-(rhs.as_inner().e2em() * self.em()),
rhs.as_inner().e1em() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<FlatPoint<T>>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<FlatPoint<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().x()
+ rhs.as_inner().e2em() * self.as_inner().y()
+ rhs.as_inner().epem() * self.as_inner().ep(),
rhs.as_inner().epem() * self.as_inner().em(),
-(rhs.as_inner().e2em() * self.as_inner().em()),
rhs.as_inner().e1em() * self.as_inner().em(),
)
}
}
#[doc = "Weight expansion of [`RoundPoint`] with [`Line`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Line<T>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn weight_expand(&self, rhs: &Line<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.d() * self.y() + rhs.ny() * self.x(),
-(rhs.nx() * self.x()) + rhs.d() * self.ep(),
-(rhs.nx() * self.y()) + -(rhs.ny() * self.ep()),
rhs.d() * self.em(),
-(rhs.ny() * self.em()),
rhs.nx() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Line<T>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn weight_expand(&self, rhs: &Line<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.d() * self.as_inner().y() + rhs.ny() * self.as_inner().x(),
-(rhs.nx() * self.as_inner().x()) + rhs.d() * self.as_inner().ep(),
-(rhs.nx() * self.as_inner().y()) + -(rhs.ny() * self.as_inner().ep()),
rhs.d() * self.as_inner().em(),
-(rhs.ny() * self.as_inner().em()),
rhs.nx() * self.as_inner().em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Line<T>>> for RoundPoint<T> {
type Output = PointPair<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Line<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().d() * self.y() + rhs.as_inner().ny() * self.x(),
-(rhs.as_inner().nx() * self.x()) + rhs.as_inner().d() * self.ep(),
-(rhs.as_inner().nx() * self.y()) + -(rhs.as_inner().ny() * self.ep()),
rhs.as_inner().d() * self.em(),
-(rhs.as_inner().ny() * self.em()),
rhs.as_inner().nx() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Line<T>>> for Unit<RoundPoint<T>> {
type Output = PointPair<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Line<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().d() * self.as_inner().y() + rhs.as_inner().ny() * self.as_inner().x(),
-(rhs.as_inner().nx() * self.as_inner().x())
+ rhs.as_inner().d() * self.as_inner().ep(),
-(rhs.as_inner().nx() * self.as_inner().y())
+ -(rhs.as_inner().ny() * self.as_inner().ep()),
rhs.as_inner().d() * self.as_inner().em(),
-(rhs.as_inner().ny() * self.as_inner().em()),
rhs.as_inner().nx() * self.as_inner().em(),
)
}
}
#[doc = "Weight expansion of [`RoundPoint`] with [`PointPair`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<PointPair<T>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &PointPair<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.e1em() * self.x() + rhs.e2em() * self.y() + rhs.epem() * self.ep(),
rhs.e1ep() * self.x() + rhs.e2ep() * self.y() + rhs.epem() * self.em(),
-(rhs.e2em() * self.em()) + -(rhs.m() * self.x()) + rhs.e2ep() * self.ep(),
-(rhs.e1ep() * self.ep()) + -(rhs.m() * self.y()) + rhs.e1em() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<PointPair<T>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &PointPair<T>) -> Circle<T> {
Circle::new_unchecked(
rhs.e1em() * self.as_inner().x()
+ rhs.e2em() * self.as_inner().y()
+ rhs.epem() * self.as_inner().ep(),
rhs.e1ep() * self.as_inner().x()
+ rhs.e2ep() * self.as_inner().y()
+ rhs.epem() * self.as_inner().em(),
-(rhs.e2em() * self.as_inner().em())
+ -(rhs.m() * self.as_inner().x())
+ rhs.e2ep() * self.as_inner().ep(),
-(rhs.e1ep() * self.as_inner().ep())
+ -(rhs.m() * self.as_inner().y())
+ rhs.e1em() * self.as_inner().em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<PointPair<T>>> for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<PointPair<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().e1em() * self.x()
+ rhs.as_inner().e2em() * self.y()
+ rhs.as_inner().epem() * self.ep(),
rhs.as_inner().e1ep() * self.x()
+ rhs.as_inner().e2ep() * self.y()
+ rhs.as_inner().epem() * self.em(),
-(rhs.as_inner().e2em() * self.em())
+ -(rhs.as_inner().m() * self.x())
+ rhs.as_inner().e2ep() * self.ep(),
-(rhs.as_inner().e1ep() * self.ep())
+ -(rhs.as_inner().m() * self.y())
+ rhs.as_inner().e1em() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<PointPair<T>>> for Unit<RoundPoint<T>> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<PointPair<T>>) -> Circle<T> {
Circle::new_unchecked(
rhs.as_inner().e1em() * self.as_inner().x()
+ rhs.as_inner().e2em() * self.as_inner().y()
+ rhs.as_inner().epem() * self.as_inner().ep(),
rhs.as_inner().e1ep() * self.as_inner().x()
+ rhs.as_inner().e2ep() * self.as_inner().y()
+ rhs.as_inner().epem() * self.as_inner().em(),
-(rhs.as_inner().e2em() * self.as_inner().em())
+ -(rhs.as_inner().m() * self.as_inner().x())
+ rhs.as_inner().e2ep() * self.as_inner().ep(),
-(rhs.as_inner().e1ep() * self.as_inner().ep())
+ -(rhs.as_inner().m() * self.as_inner().y())
+ rhs.as_inner().e1em() * self.as_inner().em(),
)
}
}
#[doc = "Weight expansion of [`RoundPoint`] with [`Pseudoscalar`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Pseudoscalar<T>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_expand(&self, rhs: &Pseudoscalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.ps() * self.x(),
rhs.ps() * self.y(),
rhs.ps() * self.ep(),
rhs.ps() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Pseudoscalar<T>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn weight_expand(&self, rhs: &Pseudoscalar<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.ps() * self.as_inner().x(),
rhs.ps() * self.as_inner().y(),
rhs.ps() * self.as_inner().ep(),
rhs.ps() * self.as_inner().em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Pseudoscalar<T>>> for RoundPoint<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().ps() * self.x(),
rhs.as_inner().ps() * self.y(),
rhs.as_inner().ps() * self.ep(),
rhs.as_inner().ps() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Pseudoscalar<T>>> for Unit<RoundPoint<T>> {
type Output = RoundPoint<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
rhs.as_inner().ps() * self.as_inner().x(),
rhs.as_inner().ps() * self.as_inner().y(),
rhs.as_inner().ps() * self.as_inner().ep(),
rhs.as_inner().ps() * self.as_inner().em(),
)
}
}
#[doc = "Weight expansion of [`RoundPoint`] with [`RoundPoint`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<RoundPoint<T>> for RoundPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &RoundPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.ep() * self.ep())
+ -(rhs.x() * self.x())
+ -(rhs.y() * self.y())
+ rhs.em() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<RoundPoint<T>> for Unit<RoundPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &RoundPoint<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.ep() * self.as_inner().ep())
+ -(rhs.x() * self.as_inner().x())
+ -(rhs.y() * self.as_inner().y())
+ rhs.em() * self.as_inner().em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<RoundPoint<T>>> for RoundPoint<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<RoundPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().ep() * self.ep())
+ -(rhs.as_inner().x() * self.x())
+ -(rhs.as_inner().y() * self.y())
+ rhs.as_inner().em() * self.em(),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<RoundPoint<T>>> for Unit<RoundPoint<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<RoundPoint<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(
-(rhs.as_inner().ep() * self.as_inner().ep())
+ -(rhs.as_inner().x() * self.as_inner().x())
+ -(rhs.as_inner().y() * self.as_inner().y())
+ rhs.as_inner().em() * self.as_inner().em(),
)
}
}
#[doc = "Weight expansion of [`Scalar`] with [`Circle`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Circle<T>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_expand(&self, rhs: &Circle<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e2epem() * self.s()),
rhs.e1epem() * self.s(),
-(rhs.e12em() * self.s()),
-(rhs.w() * self.s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Circle<T>> for Unit<Scalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn weight_expand(&self, rhs: &Circle<T>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.e2epem() * self.as_inner().s()),
rhs.e1epem() * self.as_inner().s(),
-(rhs.e12em() * self.as_inner().s()),
-(rhs.w() * self.as_inner().s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Circle<T>>> for Scalar<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Circle<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e2epem() * self.s()),
rhs.as_inner().e1epem() * self.s(),
-(rhs.as_inner().e12em() * self.s()),
-(rhs.as_inner().w() * self.s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Circle<T>>> for Unit<Scalar<T>> {
type Output = RoundPoint<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Circle<T>>) -> RoundPoint<T> {
RoundPoint::new_unchecked(
-(rhs.as_inner().e2epem() * self.as_inner().s()),
rhs.as_inner().e1epem() * self.as_inner().s(),
-(rhs.as_inner().e12em() * self.as_inner().s()),
-(rhs.as_inner().w() * self.as_inner().s()),
)
}
}
#[doc = "Weight expansion of [`Scalar`] with [`PointPair`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<PointPair<T>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn weight_expand(&self, rhs: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.epem() * self.s(),
-(rhs.e2em() * self.s()),
rhs.e1em() * self.s(),
-(rhs.e2ep() * self.s()),
rhs.e1ep() * self.s(),
-(rhs.m() * self.s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<PointPair<T>> for Unit<Scalar<T>> {
type Output = PointPair<T>;
#[inline]
fn weight_expand(&self, rhs: &PointPair<T>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.epem() * self.as_inner().s(),
-(rhs.e2em() * self.as_inner().s()),
rhs.e1em() * self.as_inner().s(),
-(rhs.e2ep() * self.as_inner().s()),
rhs.e1ep() * self.as_inner().s(),
-(rhs.m() * self.as_inner().s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<PointPair<T>>> for Scalar<T> {
type Output = PointPair<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().epem() * self.s(),
-(rhs.as_inner().e2em() * self.s()),
rhs.as_inner().e1em() * self.s(),
-(rhs.as_inner().e2ep() * self.s()),
rhs.as_inner().e1ep() * self.s(),
-(rhs.as_inner().m() * self.s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<PointPair<T>>> for Unit<Scalar<T>> {
type Output = PointPair<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<PointPair<T>>) -> PointPair<T> {
PointPair::new_unchecked(
rhs.as_inner().epem() * self.as_inner().s(),
-(rhs.as_inner().e2em() * self.as_inner().s()),
rhs.as_inner().e1em() * self.as_inner().s(),
-(rhs.as_inner().e2ep() * self.as_inner().s()),
rhs.as_inner().e1ep() * self.as_inner().s(),
-(rhs.as_inner().m() * self.as_inner().s()),
)
}
}
#[doc = "Weight expansion of [`Scalar`] with [`Pseudoscalar`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Pseudoscalar<T>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Pseudoscalar<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.ps() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Pseudoscalar<T>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Pseudoscalar<T>) -> Scalar<T> {
Scalar::new_unchecked(rhs.ps() * self.as_inner().s())
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Pseudoscalar<T>>> for Scalar<T> {
type Output = Scalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(rhs.as_inner().ps() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Pseudoscalar<T>>> for Unit<Scalar<T>> {
type Output = Scalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Pseudoscalar<T>>) -> Scalar<T> {
Scalar::new_unchecked(rhs.as_inner().ps() * self.as_inner().s())
}
}
#[doc = "Weight expansion of [`Scalar`] with [`RoundPoint`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<RoundPoint<T>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &RoundPoint<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.em() * self.s()),
-(rhs.ep() * self.s()),
rhs.y() * self.s(),
-(rhs.x() * self.s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<RoundPoint<T>> for Unit<Scalar<T>> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &RoundPoint<T>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.em() * self.as_inner().s()),
-(rhs.ep() * self.as_inner().s()),
rhs.y() * self.as_inner().s(),
-(rhs.x() * self.as_inner().s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<RoundPoint<T>>> for Scalar<T> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<RoundPoint<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().em() * self.s()),
-(rhs.as_inner().ep() * self.s()),
rhs.as_inner().y() * self.s(),
-(rhs.as_inner().x() * self.s()),
)
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<RoundPoint<T>>> for Unit<Scalar<T>> {
type Output = Circle<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<RoundPoint<T>>) -> Circle<T> {
Circle::new_unchecked(
-(rhs.as_inner().em() * self.as_inner().s()),
-(rhs.as_inner().ep() * self.as_inner().s()),
rhs.as_inner().y() * self.as_inner().s(),
-(rhs.as_inner().x() * self.as_inner().s()),
)
}
}
#[doc = "Weight expansion of [`Scalar`] with [`Scalar`].\n\nThe weight expansion is the dual of weight contraction, extracting the\ndegenerate/ideal component of the exterior product complement."]
impl<T: Float> WeightExpand<Scalar<T>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Scalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(rhs.s() * self.s()))
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Scalar<T>> for Unit<Scalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Scalar<T>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(rhs.s() * self.as_inner().s()))
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Scalar<T>>> for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Scalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(rhs.as_inner().s() * self.s()))
}
}
#[allow(unused_variables)]
impl<T: Float> WeightExpand<Unit<Scalar<T>>> for Unit<Scalar<T>> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_expand(&self, rhs: &Unit<Scalar<T>>) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-(rhs.as_inner().s() * self.as_inner().s()))
}
}
impl<T: Float> Dot<Circle<T>> for Circle<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Circle<T>) -> T {
-(self.w() * rhs.w())
+ self.e12em() * rhs.e12em()
+ self.e1epem() * rhs.e1epem()
+ self.e2epem() * rhs.e2epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Circle<T>> for Unit<Circle<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Circle<T>) -> T {
-(rhs.w() * self.as_inner().w())
+ rhs.e12em() * self.as_inner().e12em()
+ rhs.e1epem() * self.as_inner().e1epem()
+ rhs.e2epem() * self.as_inner().e2epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Circle<T>>> for Circle<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Circle<T>>) -> T {
-(rhs.as_inner().w() * self.w())
+ rhs.as_inner().e12em() * self.e12em()
+ rhs.as_inner().e1epem() * self.e1epem()
+ rhs.as_inner().e2epem() * self.e2epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Circle<T>>> for Unit<Circle<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Circle<T>>) -> T {
-(rhs.as_inner().w() * self.as_inner().w())
+ rhs.as_inner().e12em() * self.as_inner().e12em()
+ rhs.as_inner().e1epem() * self.as_inner().e1epem()
+ rhs.as_inner().e2epem() * self.as_inner().e2epem()
}
}
impl<T: Float> Dot<Line<T>> for Circle<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Line<T>) -> T {
self.e12em() * rhs.nx() + self.e1epem() * rhs.ny() + self.e2epem() * rhs.d()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Line<T>> for Unit<Circle<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Line<T>) -> T {
rhs.d() * self.as_inner().e2epem()
+ rhs.nx() * self.as_inner().e12em()
+ rhs.ny() * self.as_inner().e1epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Line<T>>> for Circle<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Line<T>>) -> T {
rhs.as_inner().d() * self.e2epem()
+ rhs.as_inner().nx() * self.e12em()
+ rhs.as_inner().ny() * self.e1epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Line<T>>> for Unit<Circle<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Line<T>>) -> T {
rhs.as_inner().d() * self.as_inner().e2epem()
+ rhs.as_inner().nx() * self.as_inner().e12em()
+ rhs.as_inner().ny() * self.as_inner().e1epem()
}
}
impl<T: Float> Dot<FlatPoint<T>> for FlatPoint<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &FlatPoint<T>) -> T {
self.e1em() * rhs.e1em() + self.e2em() * rhs.e2em() + self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<FlatPoint<T>> for Unit<FlatPoint<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &FlatPoint<T>) -> T {
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<FlatPoint<T>>> for FlatPoint<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<FlatPoint<T>>) -> T {
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<FlatPoint<T>>> for Unit<FlatPoint<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<FlatPoint<T>>) -> T {
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem()
}
}
impl<T: Float> Dot<Motor<T>> for FlatPoint<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Motor<T>) -> T {
self.e1em() * rhs.e1em() + self.e2em() * rhs.e2em() + self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Motor<T>> for Unit<FlatPoint<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Motor<T>) -> T {
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Motor<T>>> for FlatPoint<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Motor<T>>) -> T {
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Motor<T>>> for Unit<FlatPoint<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Motor<T>>) -> T {
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem()
}
}
impl<T: Float> Dot<PointPair<T>> for FlatPoint<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &PointPair<T>) -> T {
self.e1em() * rhs.e1em() + self.e2em() * rhs.e2em() + self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<PointPair<T>> for Unit<FlatPoint<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &PointPair<T>) -> T {
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<PointPair<T>>> for FlatPoint<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<PointPair<T>>) -> T {
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<PointPair<T>>> for Unit<FlatPoint<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<PointPair<T>>) -> T {
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem()
}
}
impl<T: Float> Dot<Circle<T>> for Line<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Circle<T>) -> T {
self.nx() * rhs.e12em() + self.ny() * rhs.e1epem() + self.d() * rhs.e2epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Circle<T>> for Unit<Line<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Circle<T>) -> T {
rhs.e12em() * self.as_inner().nx()
+ rhs.e1epem() * self.as_inner().ny()
+ rhs.e2epem() * self.as_inner().d()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Circle<T>>> for Line<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Circle<T>>) -> T {
rhs.as_inner().e12em() * self.nx()
+ rhs.as_inner().e1epem() * self.ny()
+ rhs.as_inner().e2epem() * self.d()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Circle<T>>> for Unit<Line<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Circle<T>>) -> T {
rhs.as_inner().e12em() * self.as_inner().nx()
+ rhs.as_inner().e1epem() * self.as_inner().ny()
+ rhs.as_inner().e2epem() * self.as_inner().d()
}
}
impl<T: Float> Dot<Line<T>> for Line<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Line<T>) -> T {
self.nx() * rhs.nx() + self.ny() * rhs.ny() + self.d() * rhs.d()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Line<T>> for Unit<Line<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Line<T>) -> T {
rhs.d() * self.as_inner().d()
+ rhs.nx() * self.as_inner().nx()
+ rhs.ny() * self.as_inner().ny()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Line<T>>> for Line<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Line<T>>) -> T {
rhs.as_inner().d() * self.d()
+ rhs.as_inner().nx() * self.nx()
+ rhs.as_inner().ny() * self.ny()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Line<T>>> for Unit<Line<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Line<T>>) -> T {
rhs.as_inner().d() * self.as_inner().d()
+ rhs.as_inner().nx() * self.as_inner().nx()
+ rhs.as_inner().ny() * self.as_inner().ny()
}
}
impl<T: Float> Dot<FlatPoint<T>> for Motor<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &FlatPoint<T>) -> T {
self.e1em() * rhs.e1em() + self.e2em() * rhs.e2em() + self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<FlatPoint<T>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &FlatPoint<T>) -> T {
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<FlatPoint<T>>> for Motor<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<FlatPoint<T>>) -> T {
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<FlatPoint<T>>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<FlatPoint<T>>) -> T {
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem()
}
}
impl<T: Float> Dot<Motor<T>> for Motor<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Motor<T>) -> T {
self.s() * rhs.s()
- self.m() * rhs.m()
- self.e1ep() * rhs.e1ep()
- self.e2ep() * rhs.e2ep()
+ self.e1em() * rhs.e1em()
+ self.e2em() * rhs.e2em()
+ self.epem() * rhs.epem()
- self.ps() * rhs.ps()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Motor<T>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Motor<T>) -> T {
-(rhs.e1ep() * self.as_inner().e1ep())
+ -(rhs.e2ep() * self.as_inner().e2ep())
+ -(rhs.m() * self.as_inner().m())
+ -(rhs.ps() * self.as_inner().ps())
+ rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem()
+ rhs.s() * self.as_inner().s()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Motor<T>>> for Motor<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Motor<T>>) -> T {
-(rhs.as_inner().e1ep() * self.e1ep())
+ -(rhs.as_inner().e2ep() * self.e2ep())
+ -(rhs.as_inner().m() * self.m())
+ -(rhs.as_inner().ps() * self.ps())
+ rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem()
+ rhs.as_inner().s() * self.s()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Motor<T>>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Motor<T>>) -> T {
-(rhs.as_inner().e1ep() * self.as_inner().e1ep())
+ -(rhs.as_inner().e2ep() * self.as_inner().e2ep())
+ -(rhs.as_inner().m() * self.as_inner().m())
+ -(rhs.as_inner().ps() * self.as_inner().ps())
+ rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem()
+ rhs.as_inner().s() * self.as_inner().s()
}
}
impl<T: Float> Dot<PointPair<T>> for Motor<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &PointPair<T>) -> T {
-(self.m() * rhs.m()) - self.e1ep() * rhs.e1ep() - self.e2ep() * rhs.e2ep()
+ self.e1em() * rhs.e1em()
+ self.e2em() * rhs.e2em()
+ self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<PointPair<T>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &PointPair<T>) -> T {
-(rhs.e1ep() * self.as_inner().e1ep())
+ -(rhs.e2ep() * self.as_inner().e2ep())
+ -(rhs.m() * self.as_inner().m())
+ rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<PointPair<T>>> for Motor<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<PointPair<T>>) -> T {
-(rhs.as_inner().e1ep() * self.e1ep())
+ -(rhs.as_inner().e2ep() * self.e2ep())
+ -(rhs.as_inner().m() * self.m())
+ rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<PointPair<T>>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<PointPair<T>>) -> T {
-(rhs.as_inner().e1ep() * self.as_inner().e1ep())
+ -(rhs.as_inner().e2ep() * self.as_inner().e2ep())
+ -(rhs.as_inner().m() * self.as_inner().m())
+ rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem()
}
}
impl<T: Float> Dot<Pseudoscalar<T>> for Motor<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Pseudoscalar<T>) -> T {
-(self.ps() * rhs.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Pseudoscalar<T>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Pseudoscalar<T>) -> T {
-(rhs.ps() * self.as_inner().ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Pseudoscalar<T>>> for Motor<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Pseudoscalar<T>>) -> T {
-(rhs.as_inner().ps() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Pseudoscalar<T>>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Pseudoscalar<T>>) -> T {
-(rhs.as_inner().ps() * self.as_inner().ps())
}
}
impl<T: Float> Dot<Scalar<T>> for Motor<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Scalar<T>) -> T {
self.s() * rhs.s()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Scalar<T>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Scalar<T>) -> T {
rhs.s() * self.as_inner().s()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Scalar<T>>> for Motor<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Scalar<T>>) -> T {
rhs.as_inner().s() * self.s()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Scalar<T>>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Scalar<T>>) -> T {
rhs.as_inner().s() * self.as_inner().s()
}
}
impl<T: Float> Dot<FlatPoint<T>> for PointPair<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &FlatPoint<T>) -> T {
self.e1em() * rhs.e1em() + self.e2em() * rhs.e2em() + self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<FlatPoint<T>> for Unit<PointPair<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &FlatPoint<T>) -> T {
rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<FlatPoint<T>>> for PointPair<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<FlatPoint<T>>) -> T {
rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<FlatPoint<T>>> for Unit<PointPair<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<FlatPoint<T>>) -> T {
rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem()
}
}
impl<T: Float> Dot<Motor<T>> for PointPair<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Motor<T>) -> T {
-(self.m() * rhs.m()) - self.e1ep() * rhs.e1ep() - self.e2ep() * rhs.e2ep()
+ self.e1em() * rhs.e1em()
+ self.e2em() * rhs.e2em()
+ self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Motor<T>> for Unit<PointPair<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Motor<T>) -> T {
-(rhs.e1ep() * self.as_inner().e1ep())
+ -(rhs.e2ep() * self.as_inner().e2ep())
+ -(rhs.m() * self.as_inner().m())
+ rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Motor<T>>> for PointPair<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Motor<T>>) -> T {
-(rhs.as_inner().e1ep() * self.e1ep())
+ -(rhs.as_inner().e2ep() * self.e2ep())
+ -(rhs.as_inner().m() * self.m())
+ rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Motor<T>>> for Unit<PointPair<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Motor<T>>) -> T {
-(rhs.as_inner().e1ep() * self.as_inner().e1ep())
+ -(rhs.as_inner().e2ep() * self.as_inner().e2ep())
+ -(rhs.as_inner().m() * self.as_inner().m())
+ rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem()
}
}
impl<T: Float> Dot<PointPair<T>> for PointPair<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &PointPair<T>) -> T {
-(self.m() * rhs.m()) - self.e1ep() * rhs.e1ep() - self.e2ep() * rhs.e2ep()
+ self.e1em() * rhs.e1em()
+ self.e2em() * rhs.e2em()
+ self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<PointPair<T>> for Unit<PointPair<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &PointPair<T>) -> T {
-(rhs.e1ep() * self.as_inner().e1ep())
+ -(rhs.e2ep() * self.as_inner().e2ep())
+ -(rhs.m() * self.as_inner().m())
+ rhs.e1em() * self.as_inner().e1em()
+ rhs.e2em() * self.as_inner().e2em()
+ rhs.epem() * self.as_inner().epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<PointPair<T>>> for PointPair<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<PointPair<T>>) -> T {
-(rhs.as_inner().e1ep() * self.e1ep())
+ -(rhs.as_inner().e2ep() * self.e2ep())
+ -(rhs.as_inner().m() * self.m())
+ rhs.as_inner().e1em() * self.e1em()
+ rhs.as_inner().e2em() * self.e2em()
+ rhs.as_inner().epem() * self.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<PointPair<T>>> for Unit<PointPair<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<PointPair<T>>) -> T {
-(rhs.as_inner().e1ep() * self.as_inner().e1ep())
+ -(rhs.as_inner().e2ep() * self.as_inner().e2ep())
+ -(rhs.as_inner().m() * self.as_inner().m())
+ rhs.as_inner().e1em() * self.as_inner().e1em()
+ rhs.as_inner().e2em() * self.as_inner().e2em()
+ rhs.as_inner().epem() * self.as_inner().epem()
}
}
impl<T: Float> Dot<Motor<T>> for Pseudoscalar<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Motor<T>) -> T {
-(self.ps() * rhs.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Motor<T>> for Unit<Pseudoscalar<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Motor<T>) -> T {
-(rhs.ps() * self.as_inner().ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Motor<T>>> for Pseudoscalar<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Motor<T>>) -> T {
-(rhs.as_inner().ps() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Motor<T>>> for Unit<Pseudoscalar<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Motor<T>>) -> T {
-(rhs.as_inner().ps() * self.as_inner().ps())
}
}
impl<T: Float> Dot<Pseudoscalar<T>> for Pseudoscalar<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Pseudoscalar<T>) -> T {
-(self.ps() * rhs.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Pseudoscalar<T>> for Unit<Pseudoscalar<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Pseudoscalar<T>) -> T {
-(rhs.ps() * self.as_inner().ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Pseudoscalar<T>>> for Pseudoscalar<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Pseudoscalar<T>>) -> T {
-(rhs.as_inner().ps() * self.ps())
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Pseudoscalar<T>>> for Unit<Pseudoscalar<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Pseudoscalar<T>>) -> T {
-(rhs.as_inner().ps() * self.as_inner().ps())
}
}
impl<T: Float> Dot<RoundPoint<T>> for RoundPoint<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &RoundPoint<T>) -> T {
self.x() * rhs.x() + self.y() * rhs.y() + self.ep() * rhs.ep() - self.em() * rhs.em()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<RoundPoint<T>> for Unit<RoundPoint<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &RoundPoint<T>) -> T {
-(rhs.em() * self.as_inner().em())
+ rhs.ep() * self.as_inner().ep()
+ rhs.x() * self.as_inner().x()
+ rhs.y() * self.as_inner().y()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<RoundPoint<T>>> for RoundPoint<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<RoundPoint<T>>) -> T {
-(rhs.as_inner().em() * self.em())
+ rhs.as_inner().ep() * self.ep()
+ rhs.as_inner().x() * self.x()
+ rhs.as_inner().y() * self.y()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<RoundPoint<T>>> for Unit<RoundPoint<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<RoundPoint<T>>) -> T {
-(rhs.as_inner().em() * self.as_inner().em())
+ rhs.as_inner().ep() * self.as_inner().ep()
+ rhs.as_inner().x() * self.as_inner().x()
+ rhs.as_inner().y() * self.as_inner().y()
}
}
impl<T: Float> Dot<Motor<T>> for Scalar<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Motor<T>) -> T {
self.s() * rhs.s()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Motor<T>> for Unit<Scalar<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Motor<T>) -> T {
rhs.s() * self.as_inner().s()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Motor<T>>> for Scalar<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Motor<T>>) -> T {
rhs.as_inner().s() * self.s()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Motor<T>>> for Unit<Scalar<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Motor<T>>) -> T {
rhs.as_inner().s() * self.as_inner().s()
}
}
impl<T: Float> Dot<Scalar<T>> for Scalar<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Scalar<T>) -> T {
self.s() * rhs.s()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Scalar<T>> for Unit<Scalar<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Scalar<T>) -> T {
rhs.s() * self.as_inner().s()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Scalar<T>>> for Scalar<T> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Scalar<T>>) -> T {
rhs.as_inner().s() * self.s()
}
}
#[allow(unused_variables)]
impl<T: Float> Dot<Unit<Scalar<T>>> for Unit<Scalar<T>> {
type Scalar = T;
#[inline]
fn dot(&self, rhs: &Unit<Scalar<T>>) -> T {
rhs.as_inner().s() * self.as_inner().s()
}
}
impl<T: Float> Antidot<Circle<T>> for Circle<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Circle<T>) -> T {
-(self.w() * rhs.w())
+ self.e12em() * rhs.e12em()
+ self.e1epem() * rhs.e1epem()
+ self.e2epem() * rhs.e2epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Circle<T>> for Unit<Circle<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Circle<T>) -> T {
-(rhs.w() * self.as_inner().w())
+ rhs.e12em() * self.as_inner().e12em()
+ rhs.e1epem() * self.as_inner().e1epem()
+ rhs.e2epem() * self.as_inner().e2epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Circle<T>>> for Circle<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Circle<T>>) -> T {
-(rhs.as_inner().w() * self.w())
+ rhs.as_inner().e12em() * self.e12em()
+ rhs.as_inner().e1epem() * self.e1epem()
+ rhs.as_inner().e2epem() * self.e2epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Circle<T>>> for Unit<Circle<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Circle<T>>) -> T {
-(rhs.as_inner().w() * self.as_inner().w())
+ rhs.as_inner().e12em() * self.as_inner().e12em()
+ rhs.as_inner().e1epem() * self.as_inner().e1epem()
+ rhs.as_inner().e2epem() * self.as_inner().e2epem()
}
}
impl<T: Float> Antidot<Line<T>> for Circle<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Line<T>) -> T {
self.e12em() * rhs.nx() + self.e1epem() * rhs.ny() + self.e2epem() * rhs.d()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Line<T>> for Unit<Circle<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Line<T>) -> T {
rhs.d() * self.as_inner().e2epem()
+ rhs.nx() * self.as_inner().e12em()
+ rhs.ny() * self.as_inner().e1epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Line<T>>> for Circle<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Line<T>>) -> T {
rhs.as_inner().d() * self.e2epem()
+ rhs.as_inner().nx() * self.e12em()
+ rhs.as_inner().ny() * self.e1epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Line<T>>> for Unit<Circle<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Line<T>>) -> T {
rhs.as_inner().d() * self.as_inner().e2epem()
+ rhs.as_inner().nx() * self.as_inner().e12em()
+ rhs.as_inner().ny() * self.as_inner().e1epem()
}
}
impl<T: Float> Antidot<FlatPoint<T>> for FlatPoint<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &FlatPoint<T>) -> T {
-(self.e1em() * rhs.e1em()) - self.e2em() * rhs.e2em() - self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<FlatPoint<T>> for Unit<FlatPoint<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &FlatPoint<T>) -> T {
-(rhs.e1em() * self.as_inner().e1em())
+ -(rhs.e2em() * self.as_inner().e2em())
+ -(rhs.epem() * self.as_inner().epem())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<FlatPoint<T>>> for FlatPoint<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<FlatPoint<T>>) -> T {
-(rhs.as_inner().e1em() * self.e1em())
+ -(rhs.as_inner().e2em() * self.e2em())
+ -(rhs.as_inner().epem() * self.epem())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<FlatPoint<T>>> for Unit<FlatPoint<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<FlatPoint<T>>) -> T {
-(rhs.as_inner().e1em() * self.as_inner().e1em())
+ -(rhs.as_inner().e2em() * self.as_inner().e2em())
+ -(rhs.as_inner().epem() * self.as_inner().epem())
}
}
impl<T: Float> Antidot<Motor<T>> for FlatPoint<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Motor<T>) -> T {
-(self.e1em() * rhs.e1em()) - self.e2em() * rhs.e2em() - self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Motor<T>> for Unit<FlatPoint<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Motor<T>) -> T {
-(rhs.e1em() * self.as_inner().e1em())
+ -(rhs.e2em() * self.as_inner().e2em())
+ -(rhs.epem() * self.as_inner().epem())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Motor<T>>> for FlatPoint<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Motor<T>>) -> T {
-(rhs.as_inner().e1em() * self.e1em())
+ -(rhs.as_inner().e2em() * self.e2em())
+ -(rhs.as_inner().epem() * self.epem())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Motor<T>>> for Unit<FlatPoint<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Motor<T>>) -> T {
-(rhs.as_inner().e1em() * self.as_inner().e1em())
+ -(rhs.as_inner().e2em() * self.as_inner().e2em())
+ -(rhs.as_inner().epem() * self.as_inner().epem())
}
}
impl<T: Float> Antidot<PointPair<T>> for FlatPoint<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &PointPair<T>) -> T {
-(self.e1em() * rhs.e1em()) - self.e2em() * rhs.e2em() - self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<PointPair<T>> for Unit<FlatPoint<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &PointPair<T>) -> T {
-(rhs.e1em() * self.as_inner().e1em())
+ -(rhs.e2em() * self.as_inner().e2em())
+ -(rhs.epem() * self.as_inner().epem())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<PointPair<T>>> for FlatPoint<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<PointPair<T>>) -> T {
-(rhs.as_inner().e1em() * self.e1em())
+ -(rhs.as_inner().e2em() * self.e2em())
+ -(rhs.as_inner().epem() * self.epem())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<PointPair<T>>> for Unit<FlatPoint<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<PointPair<T>>) -> T {
-(rhs.as_inner().e1em() * self.as_inner().e1em())
+ -(rhs.as_inner().e2em() * self.as_inner().e2em())
+ -(rhs.as_inner().epem() * self.as_inner().epem())
}
}
impl<T: Float> Antidot<Circle<T>> for Line<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Circle<T>) -> T {
self.nx() * rhs.e12em() + self.ny() * rhs.e1epem() + self.d() * rhs.e2epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Circle<T>> for Unit<Line<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Circle<T>) -> T {
rhs.e12em() * self.as_inner().nx()
+ rhs.e1epem() * self.as_inner().ny()
+ rhs.e2epem() * self.as_inner().d()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Circle<T>>> for Line<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Circle<T>>) -> T {
rhs.as_inner().e12em() * self.nx()
+ rhs.as_inner().e1epem() * self.ny()
+ rhs.as_inner().e2epem() * self.d()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Circle<T>>> for Unit<Line<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Circle<T>>) -> T {
rhs.as_inner().e12em() * self.as_inner().nx()
+ rhs.as_inner().e1epem() * self.as_inner().ny()
+ rhs.as_inner().e2epem() * self.as_inner().d()
}
}
impl<T: Float> Antidot<Line<T>> for Line<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Line<T>) -> T {
self.nx() * rhs.nx() + self.ny() * rhs.ny() + self.d() * rhs.d()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Line<T>> for Unit<Line<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Line<T>) -> T {
rhs.d() * self.as_inner().d()
+ rhs.nx() * self.as_inner().nx()
+ rhs.ny() * self.as_inner().ny()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Line<T>>> for Line<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Line<T>>) -> T {
rhs.as_inner().d() * self.d()
+ rhs.as_inner().nx() * self.nx()
+ rhs.as_inner().ny() * self.ny()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Line<T>>> for Unit<Line<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Line<T>>) -> T {
rhs.as_inner().d() * self.as_inner().d()
+ rhs.as_inner().nx() * self.as_inner().nx()
+ rhs.as_inner().ny() * self.as_inner().ny()
}
}
impl<T: Float> Antidot<FlatPoint<T>> for Motor<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &FlatPoint<T>) -> T {
-(self.e1em() * rhs.e1em()) - self.e2em() * rhs.e2em() - self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<FlatPoint<T>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &FlatPoint<T>) -> T {
-(rhs.e1em() * self.as_inner().e1em())
+ -(rhs.e2em() * self.as_inner().e2em())
+ -(rhs.epem() * self.as_inner().epem())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<FlatPoint<T>>> for Motor<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<FlatPoint<T>>) -> T {
-(rhs.as_inner().e1em() * self.e1em())
+ -(rhs.as_inner().e2em() * self.e2em())
+ -(rhs.as_inner().epem() * self.epem())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<FlatPoint<T>>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<FlatPoint<T>>) -> T {
-(rhs.as_inner().e1em() * self.as_inner().e1em())
+ -(rhs.as_inner().e2em() * self.as_inner().e2em())
+ -(rhs.as_inner().epem() * self.as_inner().epem())
}
}
impl<T: Float> Antidot<Motor<T>> for Motor<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Motor<T>) -> T {
-(self.s() * rhs.s())
+ self.m() * rhs.m()
+ self.e1ep() * rhs.e1ep()
+ self.e2ep() * rhs.e2ep()
- self.e1em() * rhs.e1em()
- self.e2em() * rhs.e2em()
- self.epem() * rhs.epem()
+ self.ps() * rhs.ps()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Motor<T>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Motor<T>) -> T {
-(rhs.e1em() * self.as_inner().e1em())
+ -(rhs.e2em() * self.as_inner().e2em())
+ -(rhs.epem() * self.as_inner().epem())
+ -(rhs.s() * self.as_inner().s())
+ rhs.e1ep() * self.as_inner().e1ep()
+ rhs.e2ep() * self.as_inner().e2ep()
+ rhs.m() * self.as_inner().m()
+ rhs.ps() * self.as_inner().ps()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Motor<T>>> for Motor<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Motor<T>>) -> T {
-(rhs.as_inner().e1em() * self.e1em())
+ -(rhs.as_inner().e2em() * self.e2em())
+ -(rhs.as_inner().epem() * self.epem())
+ -(rhs.as_inner().s() * self.s())
+ rhs.as_inner().e1ep() * self.e1ep()
+ rhs.as_inner().e2ep() * self.e2ep()
+ rhs.as_inner().m() * self.m()
+ rhs.as_inner().ps() * self.ps()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Motor<T>>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Motor<T>>) -> T {
-(rhs.as_inner().e1em() * self.as_inner().e1em())
+ -(rhs.as_inner().e2em() * self.as_inner().e2em())
+ -(rhs.as_inner().epem() * self.as_inner().epem())
+ -(rhs.as_inner().s() * self.as_inner().s())
+ rhs.as_inner().e1ep() * self.as_inner().e1ep()
+ rhs.as_inner().e2ep() * self.as_inner().e2ep()
+ rhs.as_inner().m() * self.as_inner().m()
+ rhs.as_inner().ps() * self.as_inner().ps()
}
}
impl<T: Float> Antidot<PointPair<T>> for Motor<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &PointPair<T>) -> T {
self.m() * rhs.m() + self.e1ep() * rhs.e1ep() + self.e2ep() * rhs.e2ep()
- self.e1em() * rhs.e1em()
- self.e2em() * rhs.e2em()
- self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<PointPair<T>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &PointPair<T>) -> T {
-(rhs.e1em() * self.as_inner().e1em())
+ -(rhs.e2em() * self.as_inner().e2em())
+ -(rhs.epem() * self.as_inner().epem())
+ rhs.e1ep() * self.as_inner().e1ep()
+ rhs.e2ep() * self.as_inner().e2ep()
+ rhs.m() * self.as_inner().m()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<PointPair<T>>> for Motor<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<PointPair<T>>) -> T {
-(rhs.as_inner().e1em() * self.e1em())
+ -(rhs.as_inner().e2em() * self.e2em())
+ -(rhs.as_inner().epem() * self.epem())
+ rhs.as_inner().e1ep() * self.e1ep()
+ rhs.as_inner().e2ep() * self.e2ep()
+ rhs.as_inner().m() * self.m()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<PointPair<T>>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<PointPair<T>>) -> T {
-(rhs.as_inner().e1em() * self.as_inner().e1em())
+ -(rhs.as_inner().e2em() * self.as_inner().e2em())
+ -(rhs.as_inner().epem() * self.as_inner().epem())
+ rhs.as_inner().e1ep() * self.as_inner().e1ep()
+ rhs.as_inner().e2ep() * self.as_inner().e2ep()
+ rhs.as_inner().m() * self.as_inner().m()
}
}
impl<T: Float> Antidot<Pseudoscalar<T>> for Motor<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Pseudoscalar<T>) -> T {
self.ps() * rhs.ps()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Pseudoscalar<T>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Pseudoscalar<T>) -> T {
rhs.ps() * self.as_inner().ps()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Pseudoscalar<T>>> for Motor<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Pseudoscalar<T>>) -> T {
rhs.as_inner().ps() * self.ps()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Pseudoscalar<T>>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Pseudoscalar<T>>) -> T {
rhs.as_inner().ps() * self.as_inner().ps()
}
}
impl<T: Float> Antidot<Scalar<T>> for Motor<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Scalar<T>) -> T {
-(self.s() * rhs.s())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Scalar<T>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Scalar<T>) -> T {
-(rhs.s() * self.as_inner().s())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Scalar<T>>> for Motor<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Scalar<T>>) -> T {
-(rhs.as_inner().s() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Scalar<T>>> for Unit<Motor<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Scalar<T>>) -> T {
-(rhs.as_inner().s() * self.as_inner().s())
}
}
impl<T: Float> Antidot<FlatPoint<T>> for PointPair<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &FlatPoint<T>) -> T {
-(self.e1em() * rhs.e1em()) - self.e2em() * rhs.e2em() - self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<FlatPoint<T>> for Unit<PointPair<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &FlatPoint<T>) -> T {
-(rhs.e1em() * self.as_inner().e1em())
+ -(rhs.e2em() * self.as_inner().e2em())
+ -(rhs.epem() * self.as_inner().epem())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<FlatPoint<T>>> for PointPair<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<FlatPoint<T>>) -> T {
-(rhs.as_inner().e1em() * self.e1em())
+ -(rhs.as_inner().e2em() * self.e2em())
+ -(rhs.as_inner().epem() * self.epem())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<FlatPoint<T>>> for Unit<PointPair<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<FlatPoint<T>>) -> T {
-(rhs.as_inner().e1em() * self.as_inner().e1em())
+ -(rhs.as_inner().e2em() * self.as_inner().e2em())
+ -(rhs.as_inner().epem() * self.as_inner().epem())
}
}
impl<T: Float> Antidot<Motor<T>> for PointPair<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Motor<T>) -> T {
self.m() * rhs.m() + self.e1ep() * rhs.e1ep() + self.e2ep() * rhs.e2ep()
- self.e1em() * rhs.e1em()
- self.e2em() * rhs.e2em()
- self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Motor<T>> for Unit<PointPair<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Motor<T>) -> T {
-(rhs.e1em() * self.as_inner().e1em())
+ -(rhs.e2em() * self.as_inner().e2em())
+ -(rhs.epem() * self.as_inner().epem())
+ rhs.e1ep() * self.as_inner().e1ep()
+ rhs.e2ep() * self.as_inner().e2ep()
+ rhs.m() * self.as_inner().m()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Motor<T>>> for PointPair<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Motor<T>>) -> T {
-(rhs.as_inner().e1em() * self.e1em())
+ -(rhs.as_inner().e2em() * self.e2em())
+ -(rhs.as_inner().epem() * self.epem())
+ rhs.as_inner().e1ep() * self.e1ep()
+ rhs.as_inner().e2ep() * self.e2ep()
+ rhs.as_inner().m() * self.m()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Motor<T>>> for Unit<PointPair<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Motor<T>>) -> T {
-(rhs.as_inner().e1em() * self.as_inner().e1em())
+ -(rhs.as_inner().e2em() * self.as_inner().e2em())
+ -(rhs.as_inner().epem() * self.as_inner().epem())
+ rhs.as_inner().e1ep() * self.as_inner().e1ep()
+ rhs.as_inner().e2ep() * self.as_inner().e2ep()
+ rhs.as_inner().m() * self.as_inner().m()
}
}
impl<T: Float> Antidot<PointPair<T>> for PointPair<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &PointPair<T>) -> T {
self.m() * rhs.m() + self.e1ep() * rhs.e1ep() + self.e2ep() * rhs.e2ep()
- self.e1em() * rhs.e1em()
- self.e2em() * rhs.e2em()
- self.epem() * rhs.epem()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<PointPair<T>> for Unit<PointPair<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &PointPair<T>) -> T {
-(rhs.e1em() * self.as_inner().e1em())
+ -(rhs.e2em() * self.as_inner().e2em())
+ -(rhs.epem() * self.as_inner().epem())
+ rhs.e1ep() * self.as_inner().e1ep()
+ rhs.e2ep() * self.as_inner().e2ep()
+ rhs.m() * self.as_inner().m()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<PointPair<T>>> for PointPair<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<PointPair<T>>) -> T {
-(rhs.as_inner().e1em() * self.e1em())
+ -(rhs.as_inner().e2em() * self.e2em())
+ -(rhs.as_inner().epem() * self.epem())
+ rhs.as_inner().e1ep() * self.e1ep()
+ rhs.as_inner().e2ep() * self.e2ep()
+ rhs.as_inner().m() * self.m()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<PointPair<T>>> for Unit<PointPair<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<PointPair<T>>) -> T {
-(rhs.as_inner().e1em() * self.as_inner().e1em())
+ -(rhs.as_inner().e2em() * self.as_inner().e2em())
+ -(rhs.as_inner().epem() * self.as_inner().epem())
+ rhs.as_inner().e1ep() * self.as_inner().e1ep()
+ rhs.as_inner().e2ep() * self.as_inner().e2ep()
+ rhs.as_inner().m() * self.as_inner().m()
}
}
impl<T: Float> Antidot<Motor<T>> for Pseudoscalar<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Motor<T>) -> T {
self.ps() * rhs.ps()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Motor<T>> for Unit<Pseudoscalar<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Motor<T>) -> T {
rhs.ps() * self.as_inner().ps()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Motor<T>>> for Pseudoscalar<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Motor<T>>) -> T {
rhs.as_inner().ps() * self.ps()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Motor<T>>> for Unit<Pseudoscalar<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Motor<T>>) -> T {
rhs.as_inner().ps() * self.as_inner().ps()
}
}
impl<T: Float> Antidot<Pseudoscalar<T>> for Pseudoscalar<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Pseudoscalar<T>) -> T {
self.ps() * rhs.ps()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Pseudoscalar<T>> for Unit<Pseudoscalar<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Pseudoscalar<T>) -> T {
rhs.ps() * self.as_inner().ps()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Pseudoscalar<T>>> for Pseudoscalar<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Pseudoscalar<T>>) -> T {
rhs.as_inner().ps() * self.ps()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Pseudoscalar<T>>> for Unit<Pseudoscalar<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Pseudoscalar<T>>) -> T {
rhs.as_inner().ps() * self.as_inner().ps()
}
}
impl<T: Float> Antidot<RoundPoint<T>> for RoundPoint<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &RoundPoint<T>) -> T {
self.x() * rhs.x() + self.y() * rhs.y() + self.ep() * rhs.ep() - self.em() * rhs.em()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<RoundPoint<T>> for Unit<RoundPoint<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &RoundPoint<T>) -> T {
-(rhs.em() * self.as_inner().em())
+ rhs.ep() * self.as_inner().ep()
+ rhs.x() * self.as_inner().x()
+ rhs.y() * self.as_inner().y()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<RoundPoint<T>>> for RoundPoint<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<RoundPoint<T>>) -> T {
-(rhs.as_inner().em() * self.em())
+ rhs.as_inner().ep() * self.ep()
+ rhs.as_inner().x() * self.x()
+ rhs.as_inner().y() * self.y()
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<RoundPoint<T>>> for Unit<RoundPoint<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<RoundPoint<T>>) -> T {
-(rhs.as_inner().em() * self.as_inner().em())
+ rhs.as_inner().ep() * self.as_inner().ep()
+ rhs.as_inner().x() * self.as_inner().x()
+ rhs.as_inner().y() * self.as_inner().y()
}
}
impl<T: Float> Antidot<Motor<T>> for Scalar<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Motor<T>) -> T {
-(self.s() * rhs.s())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Motor<T>> for Unit<Scalar<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Motor<T>) -> T {
-(rhs.s() * self.as_inner().s())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Motor<T>>> for Scalar<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Motor<T>>) -> T {
-(rhs.as_inner().s() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Motor<T>>> for Unit<Scalar<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Motor<T>>) -> T {
-(rhs.as_inner().s() * self.as_inner().s())
}
}
impl<T: Float> Antidot<Scalar<T>> for Scalar<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Scalar<T>) -> T {
-(self.s() * rhs.s())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Scalar<T>> for Unit<Scalar<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Scalar<T>) -> T {
-(rhs.s() * self.as_inner().s())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Scalar<T>>> for Scalar<T> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Scalar<T>>) -> T {
-(rhs.as_inner().s() * self.s())
}
}
#[allow(unused_variables)]
impl<T: Float> Antidot<Unit<Scalar<T>>> for Unit<Scalar<T>> {
type Scalar = T;
#[inline]
fn antidot(&self, rhs: &Unit<Scalar<T>>) -> T {
-(rhs.as_inner().s() * self.as_inner().s())
}
}
impl<T: Float> Reverse for Circle<T> {
#[inline]
fn reverse(&self) -> Self {
Self::new_unchecked(-self.w(), -self.e12em(), -self.e1epem(), -self.e2epem())
}
}
impl<T: Float> Reverse for FlatPoint<T> {
#[inline]
fn reverse(&self) -> Self {
Self::new_unchecked(-self.e1em(), -self.e2em(), -self.epem())
}
}
impl<T: Float> Reverse for Line<T> {
#[inline]
fn reverse(&self) -> Self {
Self::new_unchecked(-self.nx(), -self.ny(), -self.d())
}
}
impl<T: Float> Reverse for Motor<T> {
#[inline]
fn reverse(&self) -> Self {
Self::new_unchecked(
self.s(),
-self.m(),
-self.e1ep(),
-self.e2ep(),
-self.e1em(),
-self.e2em(),
-self.epem(),
self.ps(),
)
}
}
impl<T: Float> Reverse for PointPair<T> {
#[inline]
fn reverse(&self) -> Self {
Self::new_unchecked(
-self.m(),
-self.e1ep(),
-self.e2ep(),
-self.e1em(),
-self.e2em(),
-self.epem(),
)
}
}
impl<T: Float> Reverse for Pseudoscalar<T> {
#[inline]
fn reverse(&self) -> Self {
Self::new_unchecked(self.ps())
}
}
impl<T: Float> Reverse for RoundPoint<T> {
#[inline]
fn reverse(&self) -> Self {
Self::new_unchecked(self.x(), self.y(), self.ep(), self.em())
}
}
impl<T: Float> Reverse for Scalar<T> {
#[inline]
fn reverse(&self) -> Self {
Self::new_unchecked(self.s())
}
}
impl<T: Float> Antireverse for Circle<T> {
#[inline]
fn antireverse(&self) -> Self {
Self::new_unchecked(self.w(), self.e12em(), self.e1epem(), self.e2epem())
}
}
impl<T: Float> Antireverse for FlatPoint<T> {
#[inline]
fn antireverse(&self) -> Self {
Self::new_unchecked(-self.e1em(), -self.e2em(), -self.epem())
}
}
impl<T: Float> Antireverse for Line<T> {
#[inline]
fn antireverse(&self) -> Self {
Self::new_unchecked(self.nx(), self.ny(), self.d())
}
}
impl<T: Float> Antireverse for Motor<T> {
#[inline]
fn antireverse(&self) -> Self {
Self::new_unchecked(
self.s(),
-self.m(),
-self.e1ep(),
-self.e2ep(),
-self.e1em(),
-self.e2em(),
-self.epem(),
self.ps(),
)
}
}
impl<T: Float> Antireverse for PointPair<T> {
#[inline]
fn antireverse(&self) -> Self {
Self::new_unchecked(
-self.m(),
-self.e1ep(),
-self.e2ep(),
-self.e1em(),
-self.e2em(),
-self.epem(),
)
}
}
impl<T: Float> Antireverse for Pseudoscalar<T> {
#[inline]
fn antireverse(&self) -> Self {
Self::new_unchecked(self.ps())
}
}
impl<T: Float> Antireverse for RoundPoint<T> {
#[inline]
fn antireverse(&self) -> Self {
Self::new_unchecked(-self.x(), -self.y(), -self.ep(), -self.em())
}
}
impl<T: Float> Antireverse for Scalar<T> {
#[inline]
fn antireverse(&self) -> Self {
Self::new_unchecked(self.s())
}
}
impl<T: Float> Involute for Circle<T> {
#[inline]
fn involute(&self) -> Self {
Self::new_unchecked(-self.w(), -self.e12em(), -self.e1epem(), -self.e2epem())
}
}
impl<T: Float> Involute for FlatPoint<T> {
#[inline]
fn involute(&self) -> Self {
Self::new_unchecked(-self.e1em(), -self.e2em(), -self.epem())
}
}
impl<T: Float> Involute for Line<T> {
#[inline]
fn involute(&self) -> Self {
Self::new_unchecked(-self.nx(), -self.ny(), -self.d())
}
}
impl<T: Float> Involute for Motor<T> {
#[inline]
fn involute(&self) -> Self {
Self::new_unchecked(
self.s(),
-self.m(),
-self.e1ep(),
-self.e2ep(),
-self.e1em(),
-self.e2em(),
-self.epem(),
self.ps(),
)
}
}
impl<T: Float> Involute for PointPair<T> {
#[inline]
fn involute(&self) -> Self {
Self::new_unchecked(
-self.m(),
-self.e1ep(),
-self.e2ep(),
-self.e1em(),
-self.e2em(),
-self.epem(),
)
}
}
impl<T: Float> Involute for Pseudoscalar<T> {
#[inline]
fn involute(&self) -> Self {
Self::new_unchecked(self.ps())
}
}
impl<T: Float> Involute for RoundPoint<T> {
#[inline]
fn involute(&self) -> Self {
Self::new_unchecked(self.x(), self.y(), self.ep(), self.em())
}
}
impl<T: Float> Involute for Scalar<T> {
#[inline]
fn involute(&self) -> Self {
Self::new_unchecked(self.s())
}
}
impl<T: Float> RightComplement for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn right_complement(&self) -> RoundPoint<T> {
RoundPoint::new_unchecked(-self.e2epem(), self.e1epem(), -self.e12em(), self.w())
}
}
impl<T: Float> RightComplement for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn right_complement(&self) -> FlatPoint<T> {
FlatPoint::new_unchecked(T::zero(), T::zero(), T::zero())
}
}
impl<T: Float> RightComplement for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn right_complement(&self) -> RoundPoint<T> {
RoundPoint::new_unchecked(-self.d(), self.ny(), -self.nx(), T::zero())
}
}
impl<T: Float> RightComplement for Motor<T> {
type Output = Motor<T>;
#[inline]
fn right_complement(&self) -> Motor<T> {
Motor::new_unchecked(
self.ps(),
self.epem(),
-self.e2em(),
self.e1em(),
self.e2ep(),
-self.e1ep(),
self.m(),
self.s(),
)
}
}
impl<T: Float> RightComplement for PointPair<T> {
type Output = FlatPoint<T>;
#[inline]
fn right_complement(&self) -> FlatPoint<T> {
FlatPoint::new_unchecked(self.e2ep(), -self.e1ep(), self.m())
}
}
impl<T: Float> RightComplement for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn right_complement(&self) -> Scalar<T> {
Scalar::new_unchecked(self.ps())
}
}
impl<T: Float> RightComplement for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn right_complement(&self) -> Circle<T> {
Circle::new_unchecked(-self.em(), self.ep(), -self.y(), self.x())
}
}
impl<T: Float> RightComplement for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn right_complement(&self) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(self.s())
}
}
impl<T: Float> WeightDual for Circle<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_dual(&self) -> RoundPoint<T> {
RoundPoint::new_unchecked(-self.e2epem(), self.e1epem(), -self.e12em(), -self.w())
}
}
impl<T: Float> WeightDual for FlatPoint<T> {
type Output = FlatPoint<T>;
#[inline]
fn weight_dual(&self) -> FlatPoint<T> {
FlatPoint::new_unchecked(T::zero(), T::zero(), T::zero())
}
}
impl<T: Float> WeightDual for Line<T> {
type Output = RoundPoint<T>;
#[inline]
fn weight_dual(&self) -> RoundPoint<T> {
RoundPoint::new_unchecked(-self.d(), self.ny(), -self.nx(), T::zero())
}
}
impl<T: Float> WeightDual for Motor<T> {
type Output = Motor<T>;
#[inline]
fn weight_dual(&self) -> Motor<T> {
Motor::new_unchecked(
self.ps(),
self.epem(),
-self.e2em(),
self.e1em(),
-self.e2ep(),
self.e1ep(),
-self.m(),
-self.s(),
)
}
}
impl<T: Float> WeightDual for PointPair<T> {
type Output = FlatPoint<T>;
#[inline]
fn weight_dual(&self) -> FlatPoint<T> {
FlatPoint::new_unchecked(-self.e2ep(), self.e1ep(), -self.m())
}
}
impl<T: Float> WeightDual for Pseudoscalar<T> {
type Output = Scalar<T>;
#[inline]
fn weight_dual(&self) -> Scalar<T> {
Scalar::new_unchecked(self.ps())
}
}
impl<T: Float> WeightDual for RoundPoint<T> {
type Output = Circle<T>;
#[inline]
fn weight_dual(&self) -> Circle<T> {
Circle::new_unchecked(-self.em(), -self.ep(), self.y(), -self.x())
}
}
impl<T: Float> WeightDual for Scalar<T> {
type Output = Pseudoscalar<T>;
#[inline]
fn weight_dual(&self) -> Pseudoscalar<T> {
Pseudoscalar::new_unchecked(-self.s())
}
}
impl<T: Float> VersorInverse for Circle<T> {
fn try_inverse(&self) -> Option<Self> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Self::new_unchecked(
-self.w() * inv_norm_sq,
-self.e12em() * inv_norm_sq,
-self.e1epem() * inv_norm_sq,
-self.e2epem() * inv_norm_sq,
))
}
}
impl<T: Float> VersorInverse for FlatPoint<T> {
fn try_inverse(&self) -> Option<Self> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Self::new_unchecked(
-self.e1em() * inv_norm_sq,
-self.e2em() * inv_norm_sq,
-self.epem() * inv_norm_sq,
))
}
}
impl<T: Float> VersorInverse for Line<T> {
fn try_inverse(&self) -> Option<Self> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Self::new_unchecked(
-self.nx() * inv_norm_sq,
-self.ny() * inv_norm_sq,
-self.d() * inv_norm_sq,
))
}
}
impl<T: Float> VersorInverse for Motor<T> {
fn try_inverse(&self) -> Option<Self> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Self::new_unchecked(
self.s() * inv_norm_sq,
-self.m() * inv_norm_sq,
-self.e1ep() * inv_norm_sq,
-self.e2ep() * inv_norm_sq,
-self.e1em() * inv_norm_sq,
-self.e2em() * inv_norm_sq,
-self.epem() * inv_norm_sq,
self.ps() * inv_norm_sq,
))
}
}
impl<T: Float> VersorInverse for PointPair<T> {
fn try_inverse(&self) -> Option<Self> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Self::new_unchecked(
-self.m() * inv_norm_sq,
-self.e1ep() * inv_norm_sq,
-self.e2ep() * inv_norm_sq,
-self.e1em() * inv_norm_sq,
-self.e2em() * inv_norm_sq,
-self.epem() * inv_norm_sq,
))
}
}
impl<T: Float> VersorInverse for Pseudoscalar<T> {
fn try_inverse(&self) -> Option<Self> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Self::new_unchecked(self.ps() * inv_norm_sq))
}
}
impl<T: Float> VersorInverse for RoundPoint<T> {
fn try_inverse(&self) -> Option<Self> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Self::new_unchecked(
self.x() * inv_norm_sq,
self.y() * inv_norm_sq,
self.ep() * inv_norm_sq,
self.em() * inv_norm_sq,
))
}
}
impl<T: Float> VersorInverse for Scalar<T> {
fn try_inverse(&self) -> Option<Self> {
let norm_sq = <Self as crate::norm::Normed>::norm_squared(self);
if norm_sq.abs() < T::epsilon() {
return None;
}
let inv_norm_sq = T::one() / norm_sq;
Some(Self::new_unchecked(self.s() * inv_norm_sq))
}
}
impl<T: Float> crate::norm::Normed for Circle<T> {
type Scalar = T;
#[inline]
fn norm_squared(&self) -> T {
self.w() * self.w()
+ -self.e12em() * self.e12em()
+ -self.e1epem() * self.e1epem()
+ -self.e2epem() * self.e2epem()
}
fn try_normalize(&self) -> Option<Self> {
let n = self.norm();
if n < T::epsilon() {
None
} else {
Some(self.scale(T::one() / n))
}
}
#[inline]
fn scale(&self, factor: T) -> Self {
Self::new_unchecked(
self.w() * factor,
self.e12em() * factor,
self.e1epem() * factor,
self.e2epem() * factor,
)
}
}
impl<T: Float> crate::norm::Normed for FlatPoint<T> {
type Scalar = T;
#[inline]
fn norm_squared(&self) -> T {
-self.e1em() * self.e1em() + -self.e2em() * self.e2em() + -self.epem() * self.epem()
}
fn try_normalize(&self) -> Option<Self> {
let n = self.norm();
if n < T::epsilon() {
None
} else {
Some(self.scale(T::one() / n))
}
}
#[inline]
fn scale(&self, factor: T) -> Self {
Self::new_unchecked(
self.e1em() * factor,
self.e2em() * factor,
self.epem() * factor,
)
}
}
impl<T: Float> crate::norm::Normed for Line<T> {
type Scalar = T;
#[inline]
fn norm_squared(&self) -> T {
-self.nx() * self.nx() + -self.ny() * self.ny() + -self.d() * self.d()
}
fn try_normalize(&self) -> Option<Self> {
let n = self.norm();
if n < T::epsilon() {
None
} else {
Some(self.scale(T::one() / n))
}
}
#[inline]
fn scale(&self, factor: T) -> Self {
Self::new_unchecked(self.nx() * factor, self.ny() * factor, self.d() * factor)
}
}
impl<T: Float> crate::norm::Normed for Motor<T> {
type Scalar = T;
#[inline]
fn norm_squared(&self) -> T {
self.s() * self.s()
+ self.m() * self.m()
+ self.e1ep() * self.e1ep()
+ self.e2ep() * self.e2ep()
+ -self.e1em() * self.e1em()
+ -self.e2em() * self.e2em()
+ -self.epem() * self.epem()
+ -self.ps() * self.ps()
}
fn try_normalize(&self) -> Option<Self> {
let n = self.norm();
if n < T::epsilon() {
None
} else {
Some(self.scale(T::one() / n))
}
}
#[inline]
fn scale(&self, factor: T) -> Self {
Self::new_unchecked(
self.s() * factor,
self.m() * factor,
self.e1ep() * factor,
self.e2ep() * factor,
self.e1em() * factor,
self.e2em() * factor,
self.epem() * factor,
self.ps() * factor,
)
}
}
impl<T: Float> crate::norm::Normed for PointPair<T> {
type Scalar = T;
#[inline]
fn norm_squared(&self) -> T {
self.m() * self.m()
+ self.e1ep() * self.e1ep()
+ self.e2ep() * self.e2ep()
+ -self.e1em() * self.e1em()
+ -self.e2em() * self.e2em()
+ -self.epem() * self.epem()
}
fn try_normalize(&self) -> Option<Self> {
let n = self.norm();
if n < T::epsilon() {
None
} else {
Some(self.scale(T::one() / n))
}
}
#[inline]
fn scale(&self, factor: T) -> Self {
Self::new_unchecked(
self.m() * factor,
self.e1ep() * factor,
self.e2ep() * factor,
self.e1em() * factor,
self.e2em() * factor,
self.epem() * factor,
)
}
}
impl<T: Float> crate::norm::Normed for Pseudoscalar<T> {
type Scalar = T;
#[inline]
fn norm_squared(&self) -> T {
-self.ps() * self.ps()
}
fn try_normalize(&self) -> Option<Self> {
let n = self.norm();
if n < T::epsilon() {
None
} else {
Some(self.scale(T::one() / n))
}
}
#[inline]
fn scale(&self, factor: T) -> Self {
Self::new_unchecked(self.ps() * factor)
}
}
impl<T: Float> crate::norm::Normed for RoundPoint<T> {
type Scalar = T;
#[inline]
fn norm_squared(&self) -> T {
self.x() * self.x() + self.y() * self.y() + self.ep() * self.ep() + -self.em() * self.em()
}
fn try_normalize(&self) -> Option<Self> {
let n = self.norm();
if n < T::epsilon() {
None
} else {
Some(self.scale(T::one() / n))
}
}
#[inline]
fn scale(&self, factor: T) -> Self {
Self::new_unchecked(
self.x() * factor,
self.y() * factor,
self.ep() * factor,
self.em() * factor,
)
}
}
impl<T: Float> crate::norm::Normed for Scalar<T> {
type Scalar = T;
#[inline]
fn norm_squared(&self) -> T {
self.s() * self.s()
}
fn try_normalize(&self) -> Option<Self> {
let n = self.norm();
if n < T::epsilon() {
None
} else {
Some(self.scale(T::one() / n))
}
}
#[inline]
fn scale(&self, factor: T) -> Self {
Self::new_unchecked(self.s() * factor)
}
}
impl<T: Float + AbsDiffEq<Epsilon = T>> AbsDiffEq for Circle<T> {
type Epsilon = T;
fn default_epsilon() -> Self::Epsilon {
T::default_epsilon()
}
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
self.w().abs_diff_eq(&other.w(), epsilon)
&& self.e12em().abs_diff_eq(&other.e12em(), epsilon)
&& self.e1epem().abs_diff_eq(&other.e1epem(), epsilon)
&& self.e2epem().abs_diff_eq(&other.e2epem(), epsilon)
}
}
impl<T: Float + RelativeEq<Epsilon = T>> RelativeEq for Circle<T> {
fn default_max_relative() -> Self::Epsilon {
T::default_max_relative()
}
fn relative_eq(
&self,
other: &Self,
epsilon: Self::Epsilon,
max_relative: Self::Epsilon,
) -> bool {
self.w().relative_eq(&other.w(), epsilon, max_relative)
&& self
.e12em()
.relative_eq(&other.e12em(), epsilon, max_relative)
&& self
.e1epem()
.relative_eq(&other.e1epem(), epsilon, max_relative)
&& self
.e2epem()
.relative_eq(&other.e2epem(), epsilon, max_relative)
}
}
impl<T: Float + UlpsEq<Epsilon = T>> UlpsEq for Circle<T> {
fn default_max_ulps() -> u32 {
T::default_max_ulps()
}
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
self.w().ulps_eq(&other.w(), epsilon, max_ulps)
&& self.e12em().ulps_eq(&other.e12em(), epsilon, max_ulps)
&& self.e1epem().ulps_eq(&other.e1epem(), epsilon, max_ulps)
&& self.e2epem().ulps_eq(&other.e2epem(), epsilon, max_ulps)
}
}
impl<T: Float + AbsDiffEq<Epsilon = T>> AbsDiffEq for FlatPoint<T> {
type Epsilon = T;
fn default_epsilon() -> Self::Epsilon {
T::default_epsilon()
}
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
self.e1em().abs_diff_eq(&other.e1em(), epsilon)
&& self.e2em().abs_diff_eq(&other.e2em(), epsilon)
&& self.epem().abs_diff_eq(&other.epem(), epsilon)
}
}
impl<T: Float + RelativeEq<Epsilon = T>> RelativeEq for FlatPoint<T> {
fn default_max_relative() -> Self::Epsilon {
T::default_max_relative()
}
fn relative_eq(
&self,
other: &Self,
epsilon: Self::Epsilon,
max_relative: Self::Epsilon,
) -> bool {
self.e1em()
.relative_eq(&other.e1em(), epsilon, max_relative)
&& self
.e2em()
.relative_eq(&other.e2em(), epsilon, max_relative)
&& self
.epem()
.relative_eq(&other.epem(), epsilon, max_relative)
}
}
impl<T: Float + UlpsEq<Epsilon = T>> UlpsEq for FlatPoint<T> {
fn default_max_ulps() -> u32 {
T::default_max_ulps()
}
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
self.e1em().ulps_eq(&other.e1em(), epsilon, max_ulps)
&& self.e2em().ulps_eq(&other.e2em(), epsilon, max_ulps)
&& self.epem().ulps_eq(&other.epem(), epsilon, max_ulps)
}
}
impl<T: Float + AbsDiffEq<Epsilon = T>> AbsDiffEq for Line<T> {
type Epsilon = T;
fn default_epsilon() -> Self::Epsilon {
T::default_epsilon()
}
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
self.nx().abs_diff_eq(&other.nx(), epsilon)
&& self.ny().abs_diff_eq(&other.ny(), epsilon)
&& self.d().abs_diff_eq(&other.d(), epsilon)
}
}
impl<T: Float + RelativeEq<Epsilon = T>> RelativeEq for Line<T> {
fn default_max_relative() -> Self::Epsilon {
T::default_max_relative()
}
fn relative_eq(
&self,
other: &Self,
epsilon: Self::Epsilon,
max_relative: Self::Epsilon,
) -> bool {
self.nx().relative_eq(&other.nx(), epsilon, max_relative)
&& self.ny().relative_eq(&other.ny(), epsilon, max_relative)
&& self.d().relative_eq(&other.d(), epsilon, max_relative)
}
}
impl<T: Float + UlpsEq<Epsilon = T>> UlpsEq for Line<T> {
fn default_max_ulps() -> u32 {
T::default_max_ulps()
}
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
self.nx().ulps_eq(&other.nx(), epsilon, max_ulps)
&& self.ny().ulps_eq(&other.ny(), epsilon, max_ulps)
&& self.d().ulps_eq(&other.d(), epsilon, max_ulps)
}
}
impl<T: Float + AbsDiffEq<Epsilon = T>> AbsDiffEq for Motor<T> {
type Epsilon = T;
fn default_epsilon() -> Self::Epsilon {
T::default_epsilon()
}
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
self.s().abs_diff_eq(&other.s(), epsilon)
&& self.m().abs_diff_eq(&other.m(), epsilon)
&& self.e1ep().abs_diff_eq(&other.e1ep(), epsilon)
&& self.e2ep().abs_diff_eq(&other.e2ep(), epsilon)
&& self.e1em().abs_diff_eq(&other.e1em(), epsilon)
&& self.e2em().abs_diff_eq(&other.e2em(), epsilon)
&& self.epem().abs_diff_eq(&other.epem(), epsilon)
&& self.ps().abs_diff_eq(&other.ps(), epsilon)
}
}
impl<T: Float + RelativeEq<Epsilon = T>> RelativeEq for Motor<T> {
fn default_max_relative() -> Self::Epsilon {
T::default_max_relative()
}
fn relative_eq(
&self,
other: &Self,
epsilon: Self::Epsilon,
max_relative: Self::Epsilon,
) -> bool {
self.s().relative_eq(&other.s(), epsilon, max_relative)
&& self.m().relative_eq(&other.m(), epsilon, max_relative)
&& self
.e1ep()
.relative_eq(&other.e1ep(), epsilon, max_relative)
&& self
.e2ep()
.relative_eq(&other.e2ep(), epsilon, max_relative)
&& self
.e1em()
.relative_eq(&other.e1em(), epsilon, max_relative)
&& self
.e2em()
.relative_eq(&other.e2em(), epsilon, max_relative)
&& self
.epem()
.relative_eq(&other.epem(), epsilon, max_relative)
&& self.ps().relative_eq(&other.ps(), epsilon, max_relative)
}
}
impl<T: Float + UlpsEq<Epsilon = T>> UlpsEq for Motor<T> {
fn default_max_ulps() -> u32 {
T::default_max_ulps()
}
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
self.s().ulps_eq(&other.s(), epsilon, max_ulps)
&& self.m().ulps_eq(&other.m(), epsilon, max_ulps)
&& self.e1ep().ulps_eq(&other.e1ep(), epsilon, max_ulps)
&& self.e2ep().ulps_eq(&other.e2ep(), epsilon, max_ulps)
&& self.e1em().ulps_eq(&other.e1em(), epsilon, max_ulps)
&& self.e2em().ulps_eq(&other.e2em(), epsilon, max_ulps)
&& self.epem().ulps_eq(&other.epem(), epsilon, max_ulps)
&& self.ps().ulps_eq(&other.ps(), epsilon, max_ulps)
}
}
impl<T: Float + AbsDiffEq<Epsilon = T>> AbsDiffEq for PointPair<T> {
type Epsilon = T;
fn default_epsilon() -> Self::Epsilon {
T::default_epsilon()
}
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
self.m().abs_diff_eq(&other.m(), epsilon)
&& self.e1ep().abs_diff_eq(&other.e1ep(), epsilon)
&& self.e2ep().abs_diff_eq(&other.e2ep(), epsilon)
&& self.e1em().abs_diff_eq(&other.e1em(), epsilon)
&& self.e2em().abs_diff_eq(&other.e2em(), epsilon)
&& self.epem().abs_diff_eq(&other.epem(), epsilon)
}
}
impl<T: Float + RelativeEq<Epsilon = T>> RelativeEq for PointPair<T> {
fn default_max_relative() -> Self::Epsilon {
T::default_max_relative()
}
fn relative_eq(
&self,
other: &Self,
epsilon: Self::Epsilon,
max_relative: Self::Epsilon,
) -> bool {
self.m().relative_eq(&other.m(), epsilon, max_relative)
&& self
.e1ep()
.relative_eq(&other.e1ep(), epsilon, max_relative)
&& self
.e2ep()
.relative_eq(&other.e2ep(), epsilon, max_relative)
&& self
.e1em()
.relative_eq(&other.e1em(), epsilon, max_relative)
&& self
.e2em()
.relative_eq(&other.e2em(), epsilon, max_relative)
&& self
.epem()
.relative_eq(&other.epem(), epsilon, max_relative)
}
}
impl<T: Float + UlpsEq<Epsilon = T>> UlpsEq for PointPair<T> {
fn default_max_ulps() -> u32 {
T::default_max_ulps()
}
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
self.m().ulps_eq(&other.m(), epsilon, max_ulps)
&& self.e1ep().ulps_eq(&other.e1ep(), epsilon, max_ulps)
&& self.e2ep().ulps_eq(&other.e2ep(), epsilon, max_ulps)
&& self.e1em().ulps_eq(&other.e1em(), epsilon, max_ulps)
&& self.e2em().ulps_eq(&other.e2em(), epsilon, max_ulps)
&& self.epem().ulps_eq(&other.epem(), epsilon, max_ulps)
}
}
impl<T: Float + AbsDiffEq<Epsilon = T>> AbsDiffEq for Pseudoscalar<T> {
type Epsilon = T;
fn default_epsilon() -> Self::Epsilon {
T::default_epsilon()
}
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
self.ps().abs_diff_eq(&other.ps(), epsilon)
}
}
impl<T: Float + RelativeEq<Epsilon = T>> RelativeEq for Pseudoscalar<T> {
fn default_max_relative() -> Self::Epsilon {
T::default_max_relative()
}
fn relative_eq(
&self,
other: &Self,
epsilon: Self::Epsilon,
max_relative: Self::Epsilon,
) -> bool {
self.ps().relative_eq(&other.ps(), epsilon, max_relative)
}
}
impl<T: Float + UlpsEq<Epsilon = T>> UlpsEq for Pseudoscalar<T> {
fn default_max_ulps() -> u32 {
T::default_max_ulps()
}
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
self.ps().ulps_eq(&other.ps(), epsilon, max_ulps)
}
}
impl<T: Float + AbsDiffEq<Epsilon = T>> AbsDiffEq for RoundPoint<T> {
type Epsilon = T;
fn default_epsilon() -> Self::Epsilon {
T::default_epsilon()
}
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
self.x().abs_diff_eq(&other.x(), epsilon)
&& self.y().abs_diff_eq(&other.y(), epsilon)
&& self.ep().abs_diff_eq(&other.ep(), epsilon)
&& self.em().abs_diff_eq(&other.em(), epsilon)
}
}
impl<T: Float + RelativeEq<Epsilon = T>> RelativeEq for RoundPoint<T> {
fn default_max_relative() -> Self::Epsilon {
T::default_max_relative()
}
fn relative_eq(
&self,
other: &Self,
epsilon: Self::Epsilon,
max_relative: Self::Epsilon,
) -> bool {
self.x().relative_eq(&other.x(), epsilon, max_relative)
&& self.y().relative_eq(&other.y(), epsilon, max_relative)
&& self.ep().relative_eq(&other.ep(), epsilon, max_relative)
&& self.em().relative_eq(&other.em(), epsilon, max_relative)
}
}
impl<T: Float + UlpsEq<Epsilon = T>> UlpsEq for RoundPoint<T> {
fn default_max_ulps() -> u32 {
T::default_max_ulps()
}
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
self.x().ulps_eq(&other.x(), epsilon, max_ulps)
&& self.y().ulps_eq(&other.y(), epsilon, max_ulps)
&& self.ep().ulps_eq(&other.ep(), epsilon, max_ulps)
&& self.em().ulps_eq(&other.em(), epsilon, max_ulps)
}
}
impl<T: Float + AbsDiffEq<Epsilon = T>> AbsDiffEq for Scalar<T> {
type Epsilon = T;
fn default_epsilon() -> Self::Epsilon {
T::default_epsilon()
}
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
self.s().abs_diff_eq(&other.s(), epsilon)
}
}
impl<T: Float + RelativeEq<Epsilon = T>> RelativeEq for Scalar<T> {
fn default_max_relative() -> Self::Epsilon {
T::default_max_relative()
}
fn relative_eq(
&self,
other: &Self,
epsilon: Self::Epsilon,
max_relative: Self::Epsilon,
) -> bool {
self.s().relative_eq(&other.s(), epsilon, max_relative)
}
}
impl<T: Float + UlpsEq<Epsilon = T>> UlpsEq for Scalar<T> {
fn default_max_ulps() -> u32 {
T::default_max_ulps()
}
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
self.s().ulps_eq(&other.s(), epsilon, max_ulps)
}
}
#[cfg(any(test, feature = "proptest-support"))]
#[allow(clippy::missing_docs_in_private_items)]
mod arbitrary_impls {
use super::*;
use proptest::prelude::*;
use proptest::strategy::BoxedStrategy;
use std::fmt::Debug;
impl<T: Float + Debug + 'static> Arbitrary for Circle<T> {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
(
-100.0f64..100.0,
-100.0f64..100.0,
-100.0f64..100.0,
-100.0f64..100.0,
)
.prop_map(|(x0, x1, x2, x3)| {
Circle::new_unchecked(
T::from_f64(x0),
T::from_f64(x1),
T::from_f64(x2),
T::from_f64(x3),
)
})
.boxed()
}
}
impl<T: Float + Debug + 'static> Arbitrary for FlatPoint<T> {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
(-100.0f64..100.0, -100.0f64..100.0, -100.0f64..100.0)
.prop_map(|(x0, x1, x2)| {
FlatPoint::new_unchecked(T::from_f64(x0), T::from_f64(x1), T::from_f64(x2))
})
.boxed()
}
}
impl<T: Float + Debug + 'static> Arbitrary for Line<T> {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
(-100.0f64..100.0, -100.0f64..100.0, -100.0f64..100.0)
.prop_map(|(x0, x1, x2)| {
Line::new_unchecked(T::from_f64(x0), T::from_f64(x1), T::from_f64(x2))
})
.boxed()
}
}
impl<T: Float + Debug + 'static> Arbitrary for Motor<T> {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
(
-100.0f64..100.0,
-100.0f64..100.0,
-100.0f64..100.0,
-100.0f64..100.0,
-100.0f64..100.0,
-100.0f64..100.0,
-100.0f64..100.0,
)
.prop_filter("non-zero divisor", |(x0, _x1, _x2, _x3, _x4, _x5, _x6)| {
(x0).abs() > 0.1
})
.prop_map(|(x0, x1, x2, x3, x4, x5, x6)| {
Motor::new_unchecked(
T::from_f64(x0),
T::from_f64(x1),
T::from_f64(x2),
T::from_f64(x3),
T::from_f64(x4),
T::from_f64(x5),
T::from_f64(x6),
T::from_f64((x4 * x3 - x5 * x2 + x6 * x1) / (x0)),
)
})
.boxed()
}
}
impl<T: Float + Debug + 'static> Arbitrary for PointPair<T> {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
(
-100.0f64..100.0,
-100.0f64..100.0,
-100.0f64..100.0,
-100.0f64..100.0,
-100.0f64..100.0,
)
.prop_filter("non-zero divisor", |(x0, _x1, _x2, _x3, _x4)| {
(x0).abs() > 0.1
})
.prop_map(|(x0, x1, x2, x3, x4)| {
PointPair::new_unchecked(
T::from_f64(x0),
T::from_f64(x1),
T::from_f64(x2),
T::from_f64(x3),
T::from_f64(x4),
T::from_f64((-x3 * x2 + x4 * x1) / (x0)),
)
})
.boxed()
}
}
impl<T: Float + Debug + 'static> Arbitrary for Pseudoscalar<T> {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
(-100.0f64..100.0)
.prop_map(|x0| Pseudoscalar::new_unchecked(T::from_f64(x0)))
.boxed()
}
}
impl<T: Float + Debug + 'static> Arbitrary for RoundPoint<T> {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
(
-100.0f64..100.0,
-100.0f64..100.0,
-100.0f64..100.0,
-100.0f64..100.0,
)
.prop_map(|(x0, x1, x2, x3)| {
RoundPoint::new_unchecked(
T::from_f64(x0),
T::from_f64(x1),
T::from_f64(x2),
T::from_f64(x3),
)
})
.boxed()
}
}
impl<T: Float + Debug + 'static> Arbitrary for Scalar<T> {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
(-100.0f64..100.0)
.prop_map(|x0| Scalar::new_unchecked(T::from_f64(x0)))
.boxed()
}
}
}
// ============================================================
// Verification Tests (compare against Multivector)
// ============================================================
#[cfg(test)]
#[allow(clippy::missing_docs_in_private_items)]
mod verification_tests {
use super::*;
use crate::algebra::Multivector;
#[allow(unused_imports)]
use crate::norm::{DegenerateNormed, Normed};
use crate::signature::Cl3_1_0;
#[allow(unused_imports)]
use crate::wrappers::Unit;
use approx::relative_eq;
use proptest::prelude::*;
/// Relative epsilon for floating-point comparisons in verification tests.
/// Using relative comparison handles varying magnitudes better than absolute.
const REL_EPSILON: f64 = 1e-10;
proptest! {
#[test]
fn circle_add_matches_multivector(a in any::<Circle<f64>>(), b in any::<Circle<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result = a + b;
let generic_result = mv_a + mv_b;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Add mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
#[test]
fn circle_sub_matches_multivector(a in any::<Circle<f64>>(), b in any::<Circle<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result = a - b;
let generic_result = mv_a - mv_b;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Sub mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
#[test]
fn circle_neg_matches_multivector(a in any::<Circle<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let specialized_result = -a;
let generic_result = -mv_a;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Neg mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn flatpoint_add_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<FlatPoint<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result = a + b;
let generic_result = mv_a + mv_b;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Add mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
#[test]
fn flatpoint_sub_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<FlatPoint<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result = a - b;
let generic_result = mv_a - mv_b;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Sub mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
#[test]
fn flatpoint_neg_matches_multivector(a in any::<FlatPoint<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let specialized_result = -a;
let generic_result = -mv_a;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Neg mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn line_add_matches_multivector(a in any::<Line<f64>>(), b in any::<Line<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result = a + b;
let generic_result = mv_a + mv_b;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Add mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
#[test]
fn line_sub_matches_multivector(a in any::<Line<f64>>(), b in any::<Line<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result = a - b;
let generic_result = mv_a - mv_b;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Sub mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
#[test]
fn line_neg_matches_multivector(a in any::<Line<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let specialized_result = -a;
let generic_result = -mv_a;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Neg mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn motor_add_matches_multivector(a in any::<Motor<f64>>(), b in any::<Motor<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result = a + b;
let generic_result = mv_a + mv_b;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Add mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
#[test]
fn motor_sub_matches_multivector(a in any::<Motor<f64>>(), b in any::<Motor<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result = a - b;
let generic_result = mv_a - mv_b;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Sub mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
#[test]
fn motor_neg_matches_multivector(a in any::<Motor<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let specialized_result = -a;
let generic_result = -mv_a;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Neg mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn pointpair_add_matches_multivector(a in any::<PointPair<f64>>(), b in any::<PointPair<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result = a + b;
let generic_result = mv_a + mv_b;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Add mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
#[test]
fn pointpair_sub_matches_multivector(a in any::<PointPair<f64>>(), b in any::<PointPair<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result = a - b;
let generic_result = mv_a - mv_b;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Sub mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
#[test]
fn pointpair_neg_matches_multivector(a in any::<PointPair<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let specialized_result = -a;
let generic_result = -mv_a;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Neg mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn pseudoscalar_add_matches_multivector(a in any::<Pseudoscalar<f64>>(), b in any::<Pseudoscalar<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result = a + b;
let generic_result = mv_a + mv_b;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Add mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
#[test]
fn pseudoscalar_sub_matches_multivector(a in any::<Pseudoscalar<f64>>(), b in any::<Pseudoscalar<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result = a - b;
let generic_result = mv_a - mv_b;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Sub mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
#[test]
fn pseudoscalar_neg_matches_multivector(a in any::<Pseudoscalar<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let specialized_result = -a;
let generic_result = -mv_a;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Neg mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn roundpoint_add_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<RoundPoint<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result = a + b;
let generic_result = mv_a + mv_b;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Add mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
#[test]
fn roundpoint_sub_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<RoundPoint<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result = a - b;
let generic_result = mv_a - mv_b;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Sub mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
#[test]
fn roundpoint_neg_matches_multivector(a in any::<RoundPoint<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let specialized_result = -a;
let generic_result = -mv_a;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Neg mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn scalar_add_matches_multivector(a in any::<Scalar<f64>>(), b in any::<Scalar<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result = a + b;
let generic_result = mv_a + mv_b;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Add mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
#[test]
fn scalar_sub_matches_multivector(a in any::<Scalar<f64>>(), b in any::<Scalar<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result = a - b;
let generic_result = mv_a - mv_b;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Sub mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
#[test]
fn scalar_neg_matches_multivector(a in any::<Scalar<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let specialized_result = -a;
let generic_result = -mv_a;
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Neg mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_circle_roundpoint_pseudoscalar_matches_multivector(a in any::<Circle<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_circle_scalar_circle_matches_multivector(a in any::<Circle<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_flatpoint_pointpair_pseudoscalar_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_flatpoint_roundpoint_line_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Line<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_flatpoint_scalar_flatpoint_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: FlatPoint<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_line_roundpoint_pseudoscalar_matches_multivector(a in any::<Line<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_line_scalar_line_matches_multivector(a in any::<Line<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Line<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_pointpair_flatpoint_pseudoscalar_matches_multivector(a in any::<PointPair<f64>>(), b in any::<FlatPoint<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_pointpair_pointpair_pseudoscalar_matches_multivector(a in any::<PointPair<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_pointpair_roundpoint_circle_matches_multivector(a in any::<PointPair<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_pointpair_scalar_pointpair_matches_multivector(a in any::<PointPair<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_pseudoscalar_scalar_pseudoscalar_matches_multivector(a in any::<Pseudoscalar<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_roundpoint_circle_pseudoscalar_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_roundpoint_flatpoint_line_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<FlatPoint<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Line<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_roundpoint_line_pseudoscalar_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<Line<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_roundpoint_pointpair_circle_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_roundpoint_roundpoint_pointpair_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_roundpoint_scalar_roundpoint_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_scalar_circle_circle_matches_multivector(a in any::<Scalar<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_scalar_flatpoint_flatpoint_matches_multivector(a in any::<Scalar<f64>>(), b in any::<FlatPoint<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: FlatPoint<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_scalar_line_line_matches_multivector(a in any::<Scalar<f64>>(), b in any::<Line<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Line<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_scalar_pointpair_pointpair_matches_multivector(a in any::<Scalar<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_scalar_pseudoscalar_pseudoscalar_matches_multivector(a in any::<Scalar<f64>>(), b in any::<Pseudoscalar<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_scalar_roundpoint_roundpoint_matches_multivector(a in any::<Scalar<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn wedge_scalar_scalar_scalar_matches_multivector(a in any::<Scalar<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::Wedge;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.wedge(&b);
let generic_result = mv_a.exterior(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Wedge product mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_circle_circle_scalar_matches_multivector(a in any::<Circle<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_circle_line_scalar_matches_multivector(a in any::<Circle<f64>>(), b in any::<Line<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_circle_pointpair_roundpoint_matches_multivector(a in any::<Circle<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_circle_roundpoint_pointpair_matches_multivector(a in any::<Circle<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_circle_scalar_circle_matches_multivector(a in any::<Circle<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_flatpoint_flatpoint_scalar_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<FlatPoint<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_flatpoint_pointpair_scalar_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_flatpoint_roundpoint_roundpoint_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_flatpoint_scalar_flatpoint_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: FlatPoint<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_line_circle_scalar_matches_multivector(a in any::<Line<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_line_line_scalar_matches_multivector(a in any::<Line<f64>>(), b in any::<Line<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_line_pointpair_roundpoint_matches_multivector(a in any::<Line<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_line_roundpoint_pointpair_matches_multivector(a in any::<Line<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_line_scalar_line_matches_multivector(a in any::<Line<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Line<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_pointpair_flatpoint_scalar_matches_multivector(a in any::<PointPair<f64>>(), b in any::<FlatPoint<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_pointpair_pointpair_scalar_matches_multivector(a in any::<PointPair<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_pointpair_roundpoint_roundpoint_matches_multivector(a in any::<PointPair<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_pointpair_scalar_pointpair_matches_multivector(a in any::<PointPair<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_pseudoscalar_circle_roundpoint_matches_multivector(a in any::<Pseudoscalar<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_pseudoscalar_pointpair_pointpair_matches_multivector(a in any::<Pseudoscalar<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_pseudoscalar_pseudoscalar_scalar_matches_multivector(a in any::<Pseudoscalar<f64>>(), b in any::<Pseudoscalar<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_pseudoscalar_roundpoint_circle_matches_multivector(a in any::<Pseudoscalar<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_pseudoscalar_scalar_pseudoscalar_matches_multivector(a in any::<Pseudoscalar<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_roundpoint_roundpoint_scalar_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_roundpoint_scalar_roundpoint_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_contraction_scalar_scalar_scalar_matches_multivector(a in any::<Scalar<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::BulkContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.bulk_contract(&b);
let generic_result = mv_a.bulk_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_circle_circle_scalar_matches_multivector(a in any::<Circle<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_circle_line_scalar_matches_multivector(a in any::<Circle<f64>>(), b in any::<Line<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_circle_pointpair_roundpoint_matches_multivector(a in any::<Circle<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_circle_roundpoint_pointpair_matches_multivector(a in any::<Circle<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_circle_scalar_circle_matches_multivector(a in any::<Circle<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_flatpoint_flatpoint_scalar_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<FlatPoint<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_flatpoint_pointpair_scalar_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_flatpoint_roundpoint_roundpoint_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_flatpoint_scalar_flatpoint_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: FlatPoint<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_line_circle_scalar_matches_multivector(a in any::<Line<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_line_line_scalar_matches_multivector(a in any::<Line<f64>>(), b in any::<Line<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_line_pointpair_roundpoint_matches_multivector(a in any::<Line<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_line_roundpoint_pointpair_matches_multivector(a in any::<Line<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_line_scalar_line_matches_multivector(a in any::<Line<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Line<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_pointpair_flatpoint_scalar_matches_multivector(a in any::<PointPair<f64>>(), b in any::<FlatPoint<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_pointpair_pointpair_scalar_matches_multivector(a in any::<PointPair<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_pointpair_roundpoint_roundpoint_matches_multivector(a in any::<PointPair<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_pointpair_scalar_pointpair_matches_multivector(a in any::<PointPair<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_pseudoscalar_circle_roundpoint_matches_multivector(a in any::<Pseudoscalar<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_pseudoscalar_pointpair_pointpair_matches_multivector(a in any::<Pseudoscalar<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_pseudoscalar_pseudoscalar_scalar_matches_multivector(a in any::<Pseudoscalar<f64>>(), b in any::<Pseudoscalar<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_pseudoscalar_roundpoint_circle_matches_multivector(a in any::<Pseudoscalar<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_pseudoscalar_scalar_pseudoscalar_matches_multivector(a in any::<Pseudoscalar<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_roundpoint_roundpoint_scalar_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_roundpoint_scalar_roundpoint_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_contraction_scalar_scalar_scalar_matches_multivector(a in any::<Scalar<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::WeightContract;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.weight_contract(&b);
let generic_result = mv_a.weight_contraction(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight contraction mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_circle_circle_pseudoscalar_matches_multivector(a in any::<Circle<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_circle_line_pseudoscalar_matches_multivector(a in any::<Circle<f64>>(), b in any::<Line<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_circle_pseudoscalar_circle_matches_multivector(a in any::<Circle<f64>>(), b in any::<Pseudoscalar<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_flatpoint_circle_line_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Line<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_flatpoint_flatpoint_pseudoscalar_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<FlatPoint<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_flatpoint_line_line_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<Line<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Line<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_flatpoint_pointpair_pseudoscalar_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_flatpoint_pseudoscalar_flatpoint_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<Pseudoscalar<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: FlatPoint<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_line_circle_pseudoscalar_matches_multivector(a in any::<Line<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_line_line_pseudoscalar_matches_multivector(a in any::<Line<f64>>(), b in any::<Line<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_line_pseudoscalar_line_matches_multivector(a in any::<Line<f64>>(), b in any::<Pseudoscalar<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Line<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_pointpair_circle_circle_matches_multivector(a in any::<PointPair<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_pointpair_flatpoint_pseudoscalar_matches_multivector(a in any::<PointPair<f64>>(), b in any::<FlatPoint<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_pointpair_line_circle_matches_multivector(a in any::<PointPair<f64>>(), b in any::<Line<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_pointpair_pointpair_pseudoscalar_matches_multivector(a in any::<PointPair<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_pointpair_pseudoscalar_pointpair_matches_multivector(a in any::<PointPair<f64>>(), b in any::<Pseudoscalar<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_pseudoscalar_pseudoscalar_pseudoscalar_matches_multivector(a in any::<Pseudoscalar<f64>>(), b in any::<Pseudoscalar<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_roundpoint_circle_pointpair_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_roundpoint_flatpoint_circle_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<FlatPoint<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_roundpoint_line_pointpair_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<Line<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_roundpoint_pointpair_circle_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_roundpoint_pseudoscalar_roundpoint_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<Pseudoscalar<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_roundpoint_roundpoint_pseudoscalar_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_scalar_circle_roundpoint_matches_multivector(a in any::<Scalar<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_scalar_pointpair_pointpair_matches_multivector(a in any::<Scalar<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_scalar_pseudoscalar_scalar_matches_multivector(a in any::<Scalar<f64>>(), b in any::<Pseudoscalar<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_scalar_roundpoint_circle_matches_multivector(a in any::<Scalar<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn bulk_expansion_scalar_scalar_pseudoscalar_matches_multivector(a in any::<Scalar<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::BulkExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.bulk_expand(&b);
let generic_result = mv_a.bulk_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Bulk expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_circle_circle_pseudoscalar_matches_multivector(a in any::<Circle<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_circle_line_pseudoscalar_matches_multivector(a in any::<Circle<f64>>(), b in any::<Line<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_circle_pseudoscalar_circle_matches_multivector(a in any::<Circle<f64>>(), b in any::<Pseudoscalar<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_flatpoint_circle_line_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Line<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_flatpoint_flatpoint_pseudoscalar_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<FlatPoint<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_flatpoint_line_line_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<Line<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Line<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_flatpoint_pointpair_pseudoscalar_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_flatpoint_pseudoscalar_flatpoint_matches_multivector(a in any::<FlatPoint<f64>>(), b in any::<Pseudoscalar<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: FlatPoint<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_line_circle_pseudoscalar_matches_multivector(a in any::<Line<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_line_line_pseudoscalar_matches_multivector(a in any::<Line<f64>>(), b in any::<Line<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_line_pseudoscalar_line_matches_multivector(a in any::<Line<f64>>(), b in any::<Pseudoscalar<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Line<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_pointpair_circle_circle_matches_multivector(a in any::<PointPair<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_pointpair_flatpoint_pseudoscalar_matches_multivector(a in any::<PointPair<f64>>(), b in any::<FlatPoint<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_pointpair_line_circle_matches_multivector(a in any::<PointPair<f64>>(), b in any::<Line<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_pointpair_pointpair_pseudoscalar_matches_multivector(a in any::<PointPair<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_pointpair_pseudoscalar_pointpair_matches_multivector(a in any::<PointPair<f64>>(), b in any::<Pseudoscalar<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_pseudoscalar_pseudoscalar_pseudoscalar_matches_multivector(a in any::<Pseudoscalar<f64>>(), b in any::<Pseudoscalar<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_roundpoint_circle_pointpair_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_roundpoint_flatpoint_circle_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<FlatPoint<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_roundpoint_line_pointpair_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<Line<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_roundpoint_pointpair_circle_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_roundpoint_pseudoscalar_roundpoint_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<Pseudoscalar<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_roundpoint_roundpoint_pseudoscalar_matches_multivector(a in any::<RoundPoint<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_scalar_circle_roundpoint_matches_multivector(a in any::<Scalar<f64>>(), b in any::<Circle<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: RoundPoint<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_scalar_pointpair_pointpair_matches_multivector(a in any::<Scalar<f64>>(), b in any::<PointPair<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: PointPair<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_scalar_pseudoscalar_scalar_matches_multivector(a in any::<Scalar<f64>>(), b in any::<Pseudoscalar<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Scalar<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_scalar_roundpoint_circle_matches_multivector(a in any::<Scalar<f64>>(), b in any::<RoundPoint<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Circle<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
#[test]
fn weight_expansion_scalar_scalar_pseudoscalar_matches_multivector(a in any::<Scalar<f64>>(), b in any::<Scalar<f64>>()) {
use crate::ops::WeightExpand;
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
let specialized_result: Pseudoscalar<f64> = a.weight_expand(&b);
let generic_result = mv_a.weight_expansion(&mv_b);
let specialized_mv: Multivector<f64, Cl3_1_0> = specialized_result.into();
prop_assert!(
relative_eq!(specialized_mv, generic_result, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Weight expansion mismatch: specialized={:?}, generic={:?}",
specialized_mv, generic_result
);
}
}
proptest! {
/// De Morgan: complement(a * b) = complement(a) ⋇ complement(b)
#[test]
fn de_morgan_geometric_circle(a in any::<Circle<f64>>(), b in any::<Circle<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
// LHS: complement(a * b)
let lhs = (mv_a * mv_b).complement();
// RHS: complement(a) ⋇ complement(b)
let rhs = mv_a.complement().antiproduct(&mv_b.complement());
prop_assert!(
relative_eq!(lhs, rhs, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"De Morgan (geometric) failed: complement(a*b)={:?}, complement(a)⋇complement(b)={:?}",
lhs, rhs
);
}
/// De Morgan: complement(a ⋇ b) = complement(a) * complement(b)
#[test]
fn de_morgan_antiproduct_circle(a in any::<Circle<f64>>(), b in any::<Circle<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
// LHS: complement(a ⋇ b)
let lhs = mv_a.antiproduct(&mv_b).complement();
// RHS: complement(a) * complement(b)
let rhs = mv_a.complement() * mv_b.complement();
prop_assert!(
relative_eq!(lhs, rhs, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"De Morgan (antiproduct) failed: complement(a⋇b)={:?}, complement(a)*complement(b)={:?}",
lhs, rhs
);
}
}
proptest! {
/// De Morgan: complement(a * b) = complement(a) ⋇ complement(b)
#[test]
fn de_morgan_geometric_flatpoint(a in any::<FlatPoint<f64>>(), b in any::<FlatPoint<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
// LHS: complement(a * b)
let lhs = (mv_a * mv_b).complement();
// RHS: complement(a) ⋇ complement(b)
let rhs = mv_a.complement().antiproduct(&mv_b.complement());
prop_assert!(
relative_eq!(lhs, rhs, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"De Morgan (geometric) failed: complement(a*b)={:?}, complement(a)⋇complement(b)={:?}",
lhs, rhs
);
}
/// De Morgan: complement(a ⋇ b) = complement(a) * complement(b)
#[test]
fn de_morgan_antiproduct_flatpoint(a in any::<FlatPoint<f64>>(), b in any::<FlatPoint<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
// LHS: complement(a ⋇ b)
let lhs = mv_a.antiproduct(&mv_b).complement();
// RHS: complement(a) * complement(b)
let rhs = mv_a.complement() * mv_b.complement();
prop_assert!(
relative_eq!(lhs, rhs, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"De Morgan (antiproduct) failed: complement(a⋇b)={:?}, complement(a)*complement(b)={:?}",
lhs, rhs
);
}
}
proptest! {
/// De Morgan: complement(a * b) = complement(a) ⋇ complement(b)
#[test]
fn de_morgan_geometric_line(a in any::<Line<f64>>(), b in any::<Line<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
// LHS: complement(a * b)
let lhs = (mv_a * mv_b).complement();
// RHS: complement(a) ⋇ complement(b)
let rhs = mv_a.complement().antiproduct(&mv_b.complement());
prop_assert!(
relative_eq!(lhs, rhs, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"De Morgan (geometric) failed: complement(a*b)={:?}, complement(a)⋇complement(b)={:?}",
lhs, rhs
);
}
/// De Morgan: complement(a ⋇ b) = complement(a) * complement(b)
#[test]
fn de_morgan_antiproduct_line(a in any::<Line<f64>>(), b in any::<Line<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
// LHS: complement(a ⋇ b)
let lhs = mv_a.antiproduct(&mv_b).complement();
// RHS: complement(a) * complement(b)
let rhs = mv_a.complement() * mv_b.complement();
prop_assert!(
relative_eq!(lhs, rhs, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"De Morgan (antiproduct) failed: complement(a⋇b)={:?}, complement(a)*complement(b)={:?}",
lhs, rhs
);
}
}
proptest! {
/// De Morgan: complement(a * b) = complement(a) ⋇ complement(b)
#[test]
fn de_morgan_geometric_pointpair(a in any::<PointPair<f64>>(), b in any::<PointPair<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
// LHS: complement(a * b)
let lhs = (mv_a * mv_b).complement();
// RHS: complement(a) ⋇ complement(b)
let rhs = mv_a.complement().antiproduct(&mv_b.complement());
prop_assert!(
relative_eq!(lhs, rhs, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"De Morgan (geometric) failed: complement(a*b)={:?}, complement(a)⋇complement(b)={:?}",
lhs, rhs
);
}
/// De Morgan: complement(a ⋇ b) = complement(a) * complement(b)
#[test]
fn de_morgan_antiproduct_pointpair(a in any::<PointPair<f64>>(), b in any::<PointPair<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
// LHS: complement(a ⋇ b)
let lhs = mv_a.antiproduct(&mv_b).complement();
// RHS: complement(a) * complement(b)
let rhs = mv_a.complement() * mv_b.complement();
prop_assert!(
relative_eq!(lhs, rhs, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"De Morgan (antiproduct) failed: complement(a⋇b)={:?}, complement(a)*complement(b)={:?}",
lhs, rhs
);
}
}
proptest! {
/// De Morgan: complement(a * b) = complement(a) ⋇ complement(b)
#[test]
fn de_morgan_geometric_pseudoscalar(a in any::<Pseudoscalar<f64>>(), b in any::<Pseudoscalar<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
// LHS: complement(a * b)
let lhs = (mv_a * mv_b).complement();
// RHS: complement(a) ⋇ complement(b)
let rhs = mv_a.complement().antiproduct(&mv_b.complement());
prop_assert!(
relative_eq!(lhs, rhs, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"De Morgan (geometric) failed: complement(a*b)={:?}, complement(a)⋇complement(b)={:?}",
lhs, rhs
);
}
/// De Morgan: complement(a ⋇ b) = complement(a) * complement(b)
#[test]
fn de_morgan_antiproduct_pseudoscalar(a in any::<Pseudoscalar<f64>>(), b in any::<Pseudoscalar<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
// LHS: complement(a ⋇ b)
let lhs = mv_a.antiproduct(&mv_b).complement();
// RHS: complement(a) * complement(b)
let rhs = mv_a.complement() * mv_b.complement();
prop_assert!(
relative_eq!(lhs, rhs, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"De Morgan (antiproduct) failed: complement(a⋇b)={:?}, complement(a)*complement(b)={:?}",
lhs, rhs
);
}
}
proptest! {
/// De Morgan: complement(a * b) = complement(a) ⋇ complement(b)
#[test]
fn de_morgan_geometric_roundpoint(a in any::<RoundPoint<f64>>(), b in any::<RoundPoint<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
// LHS: complement(a * b)
let lhs = (mv_a * mv_b).complement();
// RHS: complement(a) ⋇ complement(b)
let rhs = mv_a.complement().antiproduct(&mv_b.complement());
prop_assert!(
relative_eq!(lhs, rhs, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"De Morgan (geometric) failed: complement(a*b)={:?}, complement(a)⋇complement(b)={:?}",
lhs, rhs
);
}
/// De Morgan: complement(a ⋇ b) = complement(a) * complement(b)
#[test]
fn de_morgan_antiproduct_roundpoint(a in any::<RoundPoint<f64>>(), b in any::<RoundPoint<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
// LHS: complement(a ⋇ b)
let lhs = mv_a.antiproduct(&mv_b).complement();
// RHS: complement(a) * complement(b)
let rhs = mv_a.complement() * mv_b.complement();
prop_assert!(
relative_eq!(lhs, rhs, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"De Morgan (antiproduct) failed: complement(a⋇b)={:?}, complement(a)*complement(b)={:?}",
lhs, rhs
);
}
}
proptest! {
/// De Morgan: complement(a * b) = complement(a) ⋇ complement(b)
#[test]
fn de_morgan_geometric_scalar(a in any::<Scalar<f64>>(), b in any::<Scalar<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
// LHS: complement(a * b)
let lhs = (mv_a * mv_b).complement();
// RHS: complement(a) ⋇ complement(b)
let rhs = mv_a.complement().antiproduct(&mv_b.complement());
prop_assert!(
relative_eq!(lhs, rhs, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"De Morgan (geometric) failed: complement(a*b)={:?}, complement(a)⋇complement(b)={:?}",
lhs, rhs
);
}
/// De Morgan: complement(a ⋇ b) = complement(a) * complement(b)
#[test]
fn de_morgan_antiproduct_scalar(a in any::<Scalar<f64>>(), b in any::<Scalar<f64>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = b.into();
// LHS: complement(a ⋇ b)
let lhs = mv_a.antiproduct(&mv_b).complement();
// RHS: complement(a) * complement(b)
let rhs = mv_a.complement() * mv_b.complement();
prop_assert!(
relative_eq!(lhs, rhs, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"De Morgan (antiproduct) failed: complement(a⋇b)={:?}, complement(a)*complement(b)={:?}",
lhs, rhs
);
}
}
proptest! {
/// Project idempotency with normalized target: project(project(a, unit_b), unit_b) == project(a, unit_b)
#[test]
fn project_idempotent_circle_flatpoint(a in any::<Circle<f64>>(), unit_b in any::<Unit<FlatPoint<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.project(&mv_b);
let second = first.project(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Project idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Project idempotency with normalized target: project(project(a, unit_b), unit_b) == project(a, unit_b)
#[test]
fn project_idempotent_circle_pointpair(a in any::<Circle<f64>>(), unit_b in any::<Unit<PointPair<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.project(&mv_b);
let second = first.project(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Project idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Project idempotency with normalized target: project(project(a, unit_b), unit_b) == project(a, unit_b)
#[test]
fn project_idempotent_circle_roundpoint(a in any::<Circle<f64>>(), unit_b in any::<Unit<RoundPoint<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.project(&mv_b);
let second = first.project(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Project idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Project idempotency with normalized target: project(project(a, unit_b), unit_b) == project(a, unit_b)
#[test]
fn project_idempotent_flatpoint_roundpoint(a in any::<FlatPoint<f64>>(), unit_b in any::<Unit<RoundPoint<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.project(&mv_b);
let second = first.project(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Project idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Project idempotency with normalized target: project(project(a, unit_b), unit_b) == project(a, unit_b)
#[test]
fn project_idempotent_line_flatpoint(a in any::<Line<f64>>(), unit_b in any::<Unit<FlatPoint<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.project(&mv_b);
let second = first.project(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Project idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Project idempotency with normalized target: project(project(a, unit_b), unit_b) == project(a, unit_b)
#[test]
fn project_idempotent_line_pointpair(a in any::<Line<f64>>(), unit_b in any::<Unit<PointPair<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.project(&mv_b);
let second = first.project(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Project idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Project idempotency with normalized target: project(project(a, unit_b), unit_b) == project(a, unit_b)
#[test]
fn project_idempotent_line_roundpoint(a in any::<Line<f64>>(), unit_b in any::<Unit<RoundPoint<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.project(&mv_b);
let second = first.project(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Project idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Project idempotency with normalized target: project(project(a, unit_b), unit_b) == project(a, unit_b)
#[test]
fn project_idempotent_pointpair_roundpoint(a in any::<PointPair<f64>>(), unit_b in any::<Unit<RoundPoint<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.project(&mv_b);
let second = first.project(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Project idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Project idempotency with normalized target: project(project(a, unit_b), unit_b) == project(a, unit_b)
#[test]
fn project_idempotent_pseudoscalar_circle(a in any::<Pseudoscalar<f64>>(), unit_b in any::<Unit<Circle<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.project(&mv_b);
let second = first.project(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Project idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Project idempotency with normalized target: project(project(a, unit_b), unit_b) == project(a, unit_b)
#[test]
fn project_idempotent_pseudoscalar_flatpoint(a in any::<Pseudoscalar<f64>>(), unit_b in any::<Unit<FlatPoint<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.project(&mv_b);
let second = first.project(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Project idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Project idempotency with normalized target: project(project(a, unit_b), unit_b) == project(a, unit_b)
#[test]
fn project_idempotent_pseudoscalar_line(a in any::<Pseudoscalar<f64>>(), unit_b in any::<Unit<Line<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.project(&mv_b);
let second = first.project(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Project idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Project idempotency with normalized target: project(project(a, unit_b), unit_b) == project(a, unit_b)
#[test]
fn project_idempotent_pseudoscalar_pointpair(a in any::<Pseudoscalar<f64>>(), unit_b in any::<Unit<PointPair<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.project(&mv_b);
let second = first.project(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Project idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Project idempotency with normalized target: project(project(a, unit_b), unit_b) == project(a, unit_b)
#[test]
fn project_idempotent_pseudoscalar_roundpoint(a in any::<Pseudoscalar<f64>>(), unit_b in any::<Unit<RoundPoint<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.project(&mv_b);
let second = first.project(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Project idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Antiproject idempotency with normalized target: antiproject(antiproject(a, unit_b), unit_b) == antiproject(a, unit_b)
#[test]
fn antiproject_idempotent_circle_pseudoscalar(a in any::<Circle<f64>>(), unit_b in any::<Unit<Pseudoscalar<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.antiproject(&mv_b);
let second = first.antiproject(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Antiproject idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Antiproject idempotency with normalized target: antiproject(antiproject(a, unit_b), unit_b) == antiproject(a, unit_b)
#[test]
fn antiproject_idempotent_flatpoint_circle(a in any::<FlatPoint<f64>>(), unit_b in any::<Unit<Circle<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.antiproject(&mv_b);
let second = first.antiproject(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Antiproject idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Antiproject idempotency with normalized target: antiproject(antiproject(a, unit_b), unit_b) == antiproject(a, unit_b)
#[test]
fn antiproject_idempotent_flatpoint_line(a in any::<FlatPoint<f64>>(), unit_b in any::<Unit<Line<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.antiproject(&mv_b);
let second = first.antiproject(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Antiproject idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Antiproject idempotency with normalized target: antiproject(antiproject(a, unit_b), unit_b) == antiproject(a, unit_b)
#[test]
fn antiproject_idempotent_flatpoint_pseudoscalar(a in any::<FlatPoint<f64>>(), unit_b in any::<Unit<Pseudoscalar<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.antiproject(&mv_b);
let second = first.antiproject(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Antiproject idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Antiproject idempotency with normalized target: antiproject(antiproject(a, unit_b), unit_b) == antiproject(a, unit_b)
#[test]
fn antiproject_idempotent_line_pseudoscalar(a in any::<Line<f64>>(), unit_b in any::<Unit<Pseudoscalar<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.antiproject(&mv_b);
let second = first.antiproject(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Antiproject idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Antiproject idempotency with normalized target: antiproject(antiproject(a, unit_b), unit_b) == antiproject(a, unit_b)
#[test]
fn antiproject_idempotent_pointpair_circle(a in any::<PointPair<f64>>(), unit_b in any::<Unit<Circle<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.antiproject(&mv_b);
let second = first.antiproject(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Antiproject idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Antiproject idempotency with normalized target: antiproject(antiproject(a, unit_b), unit_b) == antiproject(a, unit_b)
#[test]
fn antiproject_idempotent_pointpair_line(a in any::<PointPair<f64>>(), unit_b in any::<Unit<Line<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.antiproject(&mv_b);
let second = first.antiproject(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Antiproject idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Antiproject idempotency with normalized target: antiproject(antiproject(a, unit_b), unit_b) == antiproject(a, unit_b)
#[test]
fn antiproject_idempotent_pointpair_pseudoscalar(a in any::<PointPair<f64>>(), unit_b in any::<Unit<Pseudoscalar<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.antiproject(&mv_b);
let second = first.antiproject(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Antiproject idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Antiproject idempotency with normalized target: antiproject(antiproject(a, unit_b), unit_b) == antiproject(a, unit_b)
#[test]
fn antiproject_idempotent_roundpoint_circle(a in any::<RoundPoint<f64>>(), unit_b in any::<Unit<Circle<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.antiproject(&mv_b);
let second = first.antiproject(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Antiproject idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Antiproject idempotency with normalized target: antiproject(antiproject(a, unit_b), unit_b) == antiproject(a, unit_b)
#[test]
fn antiproject_idempotent_roundpoint_flatpoint(a in any::<RoundPoint<f64>>(), unit_b in any::<Unit<FlatPoint<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.antiproject(&mv_b);
let second = first.antiproject(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Antiproject idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Antiproject idempotency with normalized target: antiproject(antiproject(a, unit_b), unit_b) == antiproject(a, unit_b)
#[test]
fn antiproject_idempotent_roundpoint_line(a in any::<RoundPoint<f64>>(), unit_b in any::<Unit<Line<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.antiproject(&mv_b);
let second = first.antiproject(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Antiproject idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Antiproject idempotency with normalized target: antiproject(antiproject(a, unit_b), unit_b) == antiproject(a, unit_b)
#[test]
fn antiproject_idempotent_roundpoint_pointpair(a in any::<RoundPoint<f64>>(), unit_b in any::<Unit<PointPair<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.antiproject(&mv_b);
let second = first.antiproject(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Antiproject idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
proptest! {
/// Antiproject idempotency with normalized target: antiproject(antiproject(a, unit_b), unit_b) == antiproject(a, unit_b)
#[test]
fn antiproject_idempotent_roundpoint_pseudoscalar(a in any::<RoundPoint<f64>>(), unit_b in any::<Unit<Pseudoscalar<f64>>>()) {
let mv_a: Multivector<f64, Cl3_1_0> = a.into();
let mv_b: Multivector<f64, Cl3_1_0> = unit_b.into_inner().into();
let first = mv_a.antiproject(&mv_b);
let second = first.antiproject(&mv_b);
prop_assert!(
relative_eq!(first, second, epsilon = REL_EPSILON, max_relative = REL_EPSILON),
"Antiproject idempotency failed: first={:?}, second={:?}",
first, second
);
}
}
}