geotrans 1.2.0

Giant Magellan Telescope Geometric Transformations
Documentation
use std::cmp::PartialEq;
use std::fmt;
use std::ops::{Add, AddAssign, Deref, DerefMut, Div, Mul, Neg, Sub};
/// Vector
#[derive(Clone, Debug)]
pub struct Vector([f64; 3]);
impl Vector {
    pub fn dot(&self, other: &Vector) -> f64 {
        self.0
            .iter()
            .zip(other.0.iter())
            .fold(0., |a, (x, y)| a + x * y)
    }
    pub fn cross(&self, other: &Vector) -> Vector {
        let [a1, a2, a3] = self.0;
        let [b1, b2, b3] = other.0;
        Vector([a2 * b3 - a3 * b2, a3 * b1 - a1 * b3, a1 * b2 - a2 * b1])
    }
    pub fn norm_squared(&self) -> f64 {
        self.dot(self)
    }
    pub fn norm(&self) -> f64 {
        self.norm_squared().sqrt()
    }
    pub fn null() -> Self {
        Vector::from(0f64)
    }
    pub fn i() -> Self {
        Vector::from([1, 0, 0])
    }
    pub fn j() -> Self {
        Vector::from([0, 1, 0])
    }
    pub fn k() -> Self {
        Vector::from([0, 0, 1])
    }
}
impl AsRef<[f64]> for Vector {
    fn as_ref(&self) -> &[f64] {
        &self.0
    }
}
impl Deref for Vector {
    type Target = [f64];
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}
impl DerefMut for Vector {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}
impl From<Vec<f64>> for Vector {
    fn from(v: Vec<f64>) -> Self {
        Vector([v[0], v[1], v[2]])
    }
}
impl From<f64> for Vector {
    fn from(v: f64) -> Self {
        Vector([v; 3])
    }
}
impl From<std::slice::Iter<'_, f64>> for Vector {
    fn from(v: std::slice::Iter<'_, f64>) -> Self {
        Vector::from(v.cloned().collect::<Vec<f64>>())
    }
}
impl From<[f64; 3]> for Vector {
    fn from(v: [f64; 3]) -> Self {
        Vector(v)
    }
}
impl From<[i32; 3]> for Vector {
    fn from(v: [i32; 3]) -> Self {
        Vector::from(v.iter().map(|&x| x as f64).collect::<Vec<f64>>())
    }
}
impl From<&[f64]> for Vector {
    fn from(v: &[f64]) -> Self {
        if v.len() == 2 {
            Vector([v[0], v[1], 0.])
        } else {
            Vector([v[0], v[1], v[2]])
        }
    }
}
impl From<&mut [f64; 3]> for Vector {
    fn from(v: &mut [f64; 3]) -> Self {
        Vector([v[0], v[1], v[2]])
    }
}
impl From<Vector> for Vec<f64> {
    fn from(v: Vector) -> Self {
        (*v).into()
    }
}
impl From<Vector> for [f64; 3] {
    fn from(v: Vector) -> Self {
        v.0
    }
}
impl Add for Vector {
    type Output = Self;
    fn add(self, other: Self) -> Self {
        Vector([
            self.0[0] + other.0[0],
            self.0[1] + other.0[1],
            self.0[2] + other.0[2],
        ])
    }
}
impl AddAssign for Vector {
    fn add_assign(&mut self, other: Self) {
        *self = Self([
            self.0[0] + other.0[0],
            self.0[1] + other.0[1],
            self.0[2] + other.0[2],
        ])
    }
}
impl Add<&Vector> for Vector {
    type Output = Self;
    fn add(self, other: &Self) -> Self {
        Vector([
            self.0[0] + other.0[0],
            self.0[1] + other.0[1],
            self.0[2] + other.0[2],
        ])
    }
}
impl Sub for Vector {
    type Output = Self;
    fn sub(self, other: Self) -> Self {
        Vector([
            self.0[0] - other.0[0],
            self.0[1] - other.0[1],
            self.0[2] - other.0[2],
        ])
    }
}
impl Sub<&Vector> for Vector {
    type Output = Self;
    fn sub(self, other: &Self) -> Self {
        Vector([
            self.0[0] - other.0[0],
            self.0[1] - other.0[1],
            self.0[2] - other.0[2],
        ])
    }
}
impl Neg for Vector {
    type Output = Self;
    fn neg(self) -> Self {
        Vector([-self.0[0], -self.0[1], -self.0[2]])
    }
}
impl Mul<f64> for &Vector {
    type Output = Vector;
    fn mul(self, rhs: f64) -> Vector {
        Vector([
            rhs * self.as_ref()[0],
            rhs * self.as_ref()[1],
            rhs * self.as_ref()[2],
        ])
    }
}
impl Div<f64> for &Vector {
    type Output = Vector;
    fn div(self, rhs: f64) -> Vector {
        Vector([
            self.as_ref()[0] / rhs,
            self.as_ref()[1] / rhs,
            self.as_ref()[2] / rhs,
        ])
    }
}
impl Div<f64> for Vector {
    type Output = Vector;
    fn div(self, rhs: f64) -> Vector {
        Vector([
            self.as_ref()[0] / rhs,
            self.as_ref()[1] / rhs,
            self.as_ref()[2] / rhs,
        ])
    }
}
impl Mul<&Vector> for f64 {
    type Output = Vector;
    fn mul(self, rhs: &Vector) -> Vector {
        Vector([
            rhs.as_ref()[0] * self,
            rhs.as_ref()[1] * self,
            rhs.as_ref()[2] * self,
        ])
    }
}
impl Mul<Vector> for f64 {
    type Output = Vector;
    fn mul(self, rhs: Vector) -> Vector {
        Vector([
            rhs.as_ref()[0] * self,
            rhs.as_ref()[1] * self,
            rhs.as_ref()[2] * self,
        ])
    }
}
impl PartialEq for Vector {
    fn eq(&self, other: &Self) -> bool {
        self.0
            .iter()
            .zip(other.0.iter())
            .fold(true, |a, (x, y)| a && x == y)
    }
}
impl fmt::Display for Vector {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "{:.6}i + {:.6}j + {:.6}k",
            self.0[0], self.0[1], self.0[2]
        )
    }
}

impl IntoIterator for Vector {
    type Item = f64;

    type IntoIter = std::array::IntoIter<Self::Item, 3>;

    fn into_iter(self) -> Self::IntoIter {
        IntoIterator::into_iter(self.0)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn vector_dot() {
        let u = Vector::from([1., -2., 1.]);
        let v = Vector::from([-1., 2., 3.]);
        let d = u.dot(&v);
        assert_eq!(d, -2.)
    }

    #[test]
    fn vector_cross() {
        let u = Vector::from([1., -2., 1.]);
        let v = Vector::from([-1., 2., 3.]);
        let c = u.cross(&v);
        assert_eq!(c, Vector::from([-8., -4., 0.]));
    }

    #[test]
    fn vector_scale() {
        let u = Vector::from([1., -2., 1.]);
        let s = 3. * u;
        assert_eq!(s, Vector::from([3., -6., 3.]));
    }
}