267 lines
6.5 KiB
Rust
267 lines
6.5 KiB
Rust
use coremem_cross::real::ToFloat;
|
|
use coremem_cross::vec::{Vec3, Vec3u};
|
|
use serde::{Serialize, Deserialize};
|
|
use std::fmt::{self, Display};
|
|
use std::cmp::Ordering;
|
|
use std::ops::{Add, Deref, Div, Mul, Neg, Sub};
|
|
use std::hash::{Hash, Hasher};
|
|
|
|
pub trait Coord: Copy + Clone {
|
|
fn to_meters(&self, feature_size: f32) -> Meters;
|
|
/// rounds
|
|
fn to_index(&self, feature_size: f32) -> Index;
|
|
fn to_index_ceil(&self, feature_size: f32) -> Index;
|
|
fn to_index_floor(&self, feature_size: f32) -> Index;
|
|
fn from_meters(other: Meters, feature_size: f32) -> Self;
|
|
fn from_index(other: Index, feature_size: f32) -> Self;
|
|
fn from_either(i: Index, m: Meters) -> Self;
|
|
}
|
|
|
|
#[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd, Serialize, Deserialize)]
|
|
pub struct Meters(pub Vec3<f32>);
|
|
|
|
impl Meters {
|
|
pub fn new<R: ToFloat>(x: R, y: R, z: R) -> Self {
|
|
Self(Vec3::new(x.to_f32(), y.to_f32(), z.to_f32()))
|
|
}
|
|
pub fn new_x<R: ToFloat>(x: R) -> Self {
|
|
Self::new(x.to_f32(), 0.0, 0.0)
|
|
}
|
|
pub fn new_y<R: ToFloat>(y: R) -> Self {
|
|
Self::new(0.0, y.to_f32(), 0.0)
|
|
}
|
|
pub fn new_z<R: ToFloat>(z: R) -> Self {
|
|
Self::new(0.0, 0.0, z.to_f32())
|
|
}
|
|
pub fn with_x<R: ToFloat>(&self, x: R) -> Self {
|
|
Self::new(x.to_f32(), self.y(), self.z())
|
|
}
|
|
pub fn with_y<R: ToFloat>(&self, y: R) -> Self {
|
|
Self::new(self.x(), y.to_f32(), self.z())
|
|
}
|
|
pub fn with_z<R: ToFloat>(&self, z: R) -> Self {
|
|
Self::new(self.x(), self.y(), z.to_f32())
|
|
}
|
|
/// Rotate `rad` radians around the +z axis
|
|
pub fn rotate_z<R: ToFloat>(&self, rad: R) -> Self {
|
|
Self(self.0.with_xy(self.0.xy().rotate(rad.to_f32())))
|
|
}
|
|
}
|
|
|
|
impl Coord for Meters {
|
|
fn to_meters(&self, _feature_size: f32) -> Meters {
|
|
*self
|
|
}
|
|
fn to_index(&self, feature_size: f32) -> Index {
|
|
Index((self.0 / feature_size).round().into())
|
|
}
|
|
fn to_index_ceil(&self, feature_size: f32) -> Index {
|
|
Index((self.0 / feature_size).ceil().into())
|
|
}
|
|
fn to_index_floor(&self, feature_size: f32) -> Index {
|
|
Index((self.0 / feature_size).floor().into())
|
|
}
|
|
fn from_meters(other: Meters, _feature_size: f32) -> Self {
|
|
other
|
|
}
|
|
fn from_index(other: Index, feature_size: f32) -> Self {
|
|
other.to_meters(feature_size)
|
|
}
|
|
fn from_either(_i: Index, m: Meters) -> Self {
|
|
m
|
|
}
|
|
}
|
|
|
|
impl Deref for Meters {
|
|
type Target = Vec3<f32>;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
impl Add<Meters> for Meters {
|
|
type Output = Self;
|
|
fn add(self, other: Self) -> Self {
|
|
Self(self.0 + other.0)
|
|
}
|
|
}
|
|
|
|
impl Neg for Meters {
|
|
type Output = Self;
|
|
fn neg(self) -> Self {
|
|
Self(-self.0)
|
|
}
|
|
}
|
|
|
|
impl Sub<Meters> for Meters {
|
|
type Output = Self;
|
|
fn sub(self, other: Self) -> Self {
|
|
Self(self.0 - other.0)
|
|
}
|
|
}
|
|
|
|
impl Div<f32> for Meters {
|
|
type Output = Meters;
|
|
fn div(self, s: f32) -> Self {
|
|
Self(self.0/s)
|
|
}
|
|
}
|
|
|
|
impl Mul<f32> for Meters {
|
|
type Output = Meters;
|
|
fn mul(self, s: f32) -> Self {
|
|
Self(self.0*s)
|
|
}
|
|
}
|
|
|
|
impl Display for Meters {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "Meters{}", self.0)
|
|
}
|
|
}
|
|
|
|
#[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd, Serialize, Deserialize)]
|
|
pub struct OrdMeters(pub Meters);
|
|
|
|
impl Deref for OrdMeters {
|
|
type Target = Meters;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
impl Ord for OrdMeters {
|
|
fn cmp(&self, other: &Self) -> Ordering {
|
|
self.partial_cmp(other).unwrap()
|
|
}
|
|
}
|
|
impl Eq for OrdMeters { }
|
|
|
|
impl Hash for OrdMeters {
|
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
let bits: (u32, u32, u32) = unsafe { std::mem::transmute(*self) };
|
|
bits.hash(state)
|
|
}
|
|
}
|
|
|
|
#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
|
|
pub struct Index(pub Vec3u);
|
|
|
|
impl Index {
|
|
pub fn new(x: u32, y: u32, z: u32) -> Self {
|
|
Self((x, y, z).into())
|
|
}
|
|
pub fn unit() -> Self {
|
|
Self::new(1, 1, 1)
|
|
}
|
|
pub fn to_tuple(&self) -> (u32, u32, u32) {
|
|
(self.0.x(), self.0.y(), self.0.z())
|
|
}
|
|
pub fn from_tuple(xyz: (u32, u32, u32)) -> Self {
|
|
Self::new(xyz.0, xyz.1, xyz.2)
|
|
}
|
|
pub fn volume(&self) -> u64 {
|
|
(self.0.x() as u64) * (self.0.y() as u64) * (self.0.z() as u64)
|
|
}
|
|
|
|
pub fn left(&self) -> Self {
|
|
Self::new(self.x() - 1, self.y(), self.z())
|
|
}
|
|
pub fn right(&self) -> Self {
|
|
Self::new(self.x() + 1, self.y(), self.z())
|
|
}
|
|
pub fn up(&self) -> Self {
|
|
Self::new(self.x(), self.y() - 1, self.z())
|
|
}
|
|
pub fn down(&self) -> Self {
|
|
Self::new(self.x(), self.y() + 1, self.z())
|
|
}
|
|
pub fn out(&self) -> Self {
|
|
Self::new(self.x(), self.y(), self.z() - 1)
|
|
}
|
|
pub fn in_(&self) -> Self {
|
|
Self::new(self.x(), self.y(), self.z() + 1)
|
|
}
|
|
|
|
pub fn cardinal_neighbors(&self) -> [Self; 6] {
|
|
[self.left(), self.right(), self.up(), self.down(), self.out(), self.in_()]
|
|
}
|
|
}
|
|
|
|
impl Into<Vec3u> for Index {
|
|
fn into(self) -> Vec3u {
|
|
self.0
|
|
}
|
|
}
|
|
impl From<Vec3u> for Index {
|
|
fn from(v: Vec3u) -> Self {
|
|
Self(v)
|
|
}
|
|
}
|
|
|
|
impl Coord for Index {
|
|
fn to_meters(&self, feature_size: f32) -> Meters {
|
|
Meters(Vec3::from(self.0) * feature_size)
|
|
}
|
|
fn to_index(&self, _feature_size: f32) -> Index {
|
|
*self
|
|
}
|
|
fn to_index_ceil(&self, _feature_size: f32) -> Index {
|
|
*self
|
|
}
|
|
fn to_index_floor(&self, _feature_size: f32) -> Index {
|
|
*self
|
|
}
|
|
fn from_meters(other: Meters, feature_size: f32) -> Self {
|
|
other.to_index(feature_size)
|
|
}
|
|
fn from_index(other: Index, _feature_size: f32) -> Self {
|
|
other
|
|
}
|
|
fn from_either(i: Index, _m: Meters) -> Self {
|
|
i
|
|
}
|
|
}
|
|
|
|
impl Deref for Index {
|
|
type Target = Vec3u;
|
|
fn deref(&self) -> &Vec3u {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
|
|
impl Add<Index> for Index {
|
|
type Output = Self;
|
|
fn add(self, other: Self) -> Self {
|
|
Self(self.0 + other.0)
|
|
}
|
|
}
|
|
|
|
impl Sub<Index> for Index {
|
|
type Output = Self;
|
|
fn sub(self, other: Self) -> Self {
|
|
Self(self.0 - other.0)
|
|
}
|
|
}
|
|
|
|
impl Div<u32> for Index {
|
|
type Output = Index;
|
|
fn div(self, s: u32) -> Self {
|
|
Self(self.0/s)
|
|
}
|
|
}
|
|
|
|
impl Mul<u32> for Index {
|
|
type Output = Index;
|
|
fn mul(self, s: u32) -> Self {
|
|
Self(self.0*s)
|
|
}
|
|
}
|
|
|
|
impl Display for Index {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "Index{}", self.0)
|
|
}
|
|
}
|