Consolidate Vec/Coord into the geom submodule
Also add the missing coord.rs to version control... It should have been checked in earlier
This commit is contained in:
313
src/geom/vec.rs
Normal file
313
src/geom/vec.rs
Normal file
@@ -0,0 +1,313 @@
|
||||
use crate::flt::{Flt, Real};
|
||||
use super::Coord;
|
||||
use std::convert::From;
|
||||
use std::iter::Sum;
|
||||
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub};
|
||||
|
||||
fn round(f: Real) -> Real {
|
||||
Real::from_inner(f.into_inner().round())
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
pub struct Vec2 {
|
||||
pub x: Real,
|
||||
pub y: Real,
|
||||
}
|
||||
|
||||
impl Add for Vec2 {
|
||||
type Output = Vec2;
|
||||
fn add(self, other: Vec2) -> Vec2 {
|
||||
let mut ret = self.clone();
|
||||
ret += other;
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign for Vec2 {
|
||||
fn add_assign(&mut self, other: Vec2) {
|
||||
self.x += other.x;
|
||||
self.y += other.y;
|
||||
}
|
||||
}
|
||||
|
||||
impl Neg for Vec2 {
|
||||
type Output = Vec2;
|
||||
fn neg(self) -> Vec2 {
|
||||
Vec2 {
|
||||
x: -self.x,
|
||||
y: -self.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for Vec2 {
|
||||
type Output = Vec2;
|
||||
fn sub(self, other: Vec2) -> Vec2 {
|
||||
self + (-other)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Flt> for Vec2 {
|
||||
type Output = Vec2;
|
||||
fn mul(self, s: Flt) -> Vec2 {
|
||||
Vec2 {
|
||||
x: self.x * s,
|
||||
y: self.y * s,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<(Flt, Flt)> for Vec2 {
|
||||
fn into(self) -> (Flt, Flt) {
|
||||
(self.x(), self.y())
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<(Real, Real)> for Vec2 {
|
||||
fn into(self) -> (Real, Real) {
|
||||
(self.x, self.y)
|
||||
}
|
||||
}
|
||||
|
||||
impl Vec2 {
|
||||
pub fn new(x: Flt, y: Flt) -> Self {
|
||||
Self {
|
||||
x: x.into(),
|
||||
y: y.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn x(&self) -> Flt {
|
||||
self.x.into()
|
||||
}
|
||||
|
||||
pub fn y(&self) -> Flt {
|
||||
self.y.into()
|
||||
}
|
||||
|
||||
pub fn round(&self) -> Vec2 {
|
||||
Vec2 {
|
||||
x: round(self.x),
|
||||
y: round(self.y),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn distance_sq(&self, other: Self) -> Flt {
|
||||
(*self - other).mag_sq()
|
||||
}
|
||||
|
||||
pub fn mag_sq(&self) -> Flt {
|
||||
(self.x*self.x + self.y*self.y).into()
|
||||
}
|
||||
|
||||
pub fn mag(&self) -> Flt {
|
||||
self.mag_sq().sqrt()
|
||||
}
|
||||
|
||||
pub fn with_mag(&self, new_mag: Flt) -> Vec2 {
|
||||
if new_mag == 0.0 {
|
||||
// avoid div-by-zero if self.mag() == 0 and new_mag == 0
|
||||
Vec2::new(0.0, 0.0)
|
||||
} else {
|
||||
let scale = Real::from_inner(new_mag) / self.mag();
|
||||
self.clone() * scale.into_inner()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq)]
|
||||
pub struct Vec3 {
|
||||
pub(crate) x: Real,
|
||||
pub(crate) y: Real,
|
||||
pub(crate) z: Real,
|
||||
}
|
||||
|
||||
impl Vec3 {
|
||||
pub fn new(x: Flt, y: Flt, z: Flt) -> Self {
|
||||
Self {
|
||||
x: x.into(),
|
||||
y: y.into(),
|
||||
z: z.into()
|
||||
}
|
||||
}
|
||||
pub fn unit() -> Self {
|
||||
Self::new(1.0, 1.0, 1.0)
|
||||
}
|
||||
pub fn zero() -> Self {
|
||||
Self::new(0.0, 0.0, 0.0)
|
||||
}
|
||||
pub fn x(&self) -> Flt {
|
||||
self.x.into()
|
||||
}
|
||||
pub fn y(&self) -> Flt {
|
||||
self.y.into()
|
||||
}
|
||||
pub fn z(&self) -> Flt {
|
||||
self.z.into()
|
||||
}
|
||||
pub fn xy(&self) -> Vec2 {
|
||||
Vec2::new(self.x(), self.y())
|
||||
}
|
||||
pub fn mag(&self) -> Flt {
|
||||
let Vec3 { x, y, z } = *self;
|
||||
(x*x + y*y + z*z).into_inner().sqrt()
|
||||
}
|
||||
pub fn component_sum(&self) -> Flt {
|
||||
(self.x + self.y + self.z).into()
|
||||
}
|
||||
|
||||
pub fn dot(&self, other: Self) -> Flt {
|
||||
self.elem_mul(other).component_sum()
|
||||
}
|
||||
|
||||
/// Perform element-wise multiplication with `other`.
|
||||
pub fn elem_mul(&self, other: Self) -> Self {
|
||||
Self {
|
||||
x: self.x * other.x,
|
||||
y: self.y * other.y,
|
||||
z: self.z * other.z,
|
||||
}
|
||||
}
|
||||
|
||||
/// Perform element-wise division with `other`.
|
||||
pub fn elem_div(&self, other: Self) -> Self {
|
||||
Self {
|
||||
x: self.x / other.x,
|
||||
y: self.y / other.y,
|
||||
z: self.z / other.z,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<(Flt, Flt, Flt)> for Vec3 {
|
||||
fn into(self) -> (Flt, Flt, Flt) {
|
||||
(self.x(), self.y(), self.z())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(Flt, Flt, Flt)> for Vec3 {
|
||||
fn from((x, y, z): (Flt, Flt, Flt)) -> Self {
|
||||
Self::new(x, y, z)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(Real, Real, Real)> for Vec3 {
|
||||
fn from((x, y, z): (Real, Real, Real)) -> Self {
|
||||
Self { x, y, z }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Coord> for Vec3 {
|
||||
fn from(c: Coord) -> Self {
|
||||
Self::new(c.x().into(), c.y().into(), c.z().into())
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign for Vec3 {
|
||||
fn add_assign(&mut self, other: Self) {
|
||||
self.x += other.x;
|
||||
self.y += other.y;
|
||||
self.z += other.z;
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Vec3 {
|
||||
type Output = Self;
|
||||
fn add(self, other: Self) -> Self {
|
||||
let mut work = self.clone();
|
||||
work += other;
|
||||
work
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for Vec3 {
|
||||
type Output = Self;
|
||||
fn sub(self, other: Self) -> Self {
|
||||
Self {
|
||||
x: self.x - other.x,
|
||||
y: self.y - other.y,
|
||||
z: self.z - other.z,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Neg for Vec3 {
|
||||
type Output = Self;
|
||||
fn neg(self) -> Self {
|
||||
Self {
|
||||
x: -self.x,
|
||||
y: -self.y,
|
||||
z: -self.z,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MulAssign<Real> for Vec3 {
|
||||
fn mul_assign(&mut self, other: Real) {
|
||||
self.x *= other;
|
||||
self.y *= other;
|
||||
self.z *= other;
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Real> for Vec3 {
|
||||
type Output = Self;
|
||||
fn mul(self, other: Real) -> Self {
|
||||
let mut work = self.clone();
|
||||
work *= other;
|
||||
work
|
||||
}
|
||||
}
|
||||
|
||||
impl MulAssign<Flt> for Vec3 {
|
||||
fn mul_assign(&mut self, other: Flt) {
|
||||
self.x *= other;
|
||||
self.y *= other;
|
||||
self.z *= other;
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Flt> for Vec3 {
|
||||
type Output = Self;
|
||||
fn mul(self, other: Flt) -> Self {
|
||||
let mut work = self.clone();
|
||||
work *= other;
|
||||
work
|
||||
}
|
||||
}
|
||||
|
||||
impl DivAssign<Real> for Vec3 {
|
||||
fn div_assign(&mut self, other: Real) {
|
||||
*self *= Real::from_inner(1.0) / other;
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<Real> for Vec3 {
|
||||
type Output = Self;
|
||||
fn div(self, other: Real) -> Self {
|
||||
let mut work = self.clone();
|
||||
work /= other;
|
||||
work
|
||||
}
|
||||
}
|
||||
|
||||
impl DivAssign<Flt> for Vec3 {
|
||||
fn div_assign(&mut self, other: Flt) {
|
||||
*self *= 1.0 / other;
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<Flt> for Vec3 {
|
||||
type Output = Self;
|
||||
fn div(self, other: Flt) -> Self {
|
||||
let mut work = self.clone();
|
||||
work /= other;
|
||||
work
|
||||
}
|
||||
}
|
||||
|
||||
impl Sum for Vec3 {
|
||||
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
|
||||
iter.fold(Self::default(), |a, b| a + b)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user