Last active
February 21, 2022 16:21
-
-
Save nyurik/d0e3fe5d5d3b6446d524130081eb7edb to your computer and use it in GitHub Desktop.
Multidimensional Geo-types
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use num_traits::{Float, Num, NumCast}; | |
use std::fmt::Debug; | |
trait CoordinateType: Default + Num + Copy + NumCast + PartialOrd + Debug {} | |
impl<T: Default + Num + Copy + NumCast + PartialOrd + Debug> CoordinateType for T {} | |
trait CoordNum: CoordinateType {} | |
impl<T: CoordinateType + Debug> CoordNum for T {} | |
trait CoordFloat: CoordNum + Float {} | |
impl<T: CoordNum + Float> CoordFloat for T {} | |
#[derive(Clone, Copy, Debug)] | |
struct Coordinate<T: CoordNum, const D: usize> { | |
coord: [T; D], | |
} | |
impl<T: CoordNum, const D: usize> Coordinate<T, D> { | |
pub fn new(coord: [T; D]) -> Self { | |
Self { coord } | |
} | |
} | |
impl<T: CoordNum, const D: usize> Default for Coordinate<T, D> { | |
fn default() -> Self { | |
Self { | |
coord: [T::default(); D], | |
} | |
} | |
} | |
#[derive(Clone, Copy, Debug)] | |
struct SizedMultipoint<T: CoordNum, const D: usize, const P: usize> { | |
coords: [Coordinate<T, D>; P], | |
} | |
impl<T: CoordNum, const D: usize, const P: usize> Default for SizedMultipoint<T, D, P> { | |
fn default() -> Self { | |
Self { | |
coords: [Coordinate::<T, D>::default(); P], | |
} | |
} | |
} | |
#[derive(Default, Clone, Debug)] | |
struct Multipoint<T: CoordNum, const D: usize> { | |
coords: Vec<Coordinate<T, D>>, | |
} | |
type Point<T, const D: usize> = SizedMultipoint<T, D, 1>; | |
impl<T: CoordNum, const D: usize> Point<T, D> { | |
pub fn get_vertex(self) -> Coordinate<T, D> { | |
self.coords[0] | |
} | |
} | |
type Point2D<T> = Point<T, 2>; | |
impl<T: CoordNum> Point2D<T> { | |
pub fn get_x(self) -> T { | |
self.get_vertex().coord[0] | |
} | |
pub fn get_y(self) -> T { | |
self.get_vertex().coord[1] | |
} | |
} | |
type Point3D<T> = Point<T, 3>; | |
impl<T: CoordNum> Point3D<T> { | |
pub fn get_z(self) -> T { | |
self.get_vertex().coord[2] | |
} | |
} | |
type Line<T, const D: usize> = SizedMultipoint<T, D, 2>; | |
type Line2D<T> = Line<T, 2>; | |
type Line3D<T> = Line<T, 3>; | |
type Line3DM<T> = Line<T, 4>; | |
type Triangle<T, const D: usize> = SizedMultipoint<T, D, 3>; | |
type Triangle2D<T> = Triangle<T, 2>; | |
type Triangle3D<T> = Triangle<T, 3>; | |
type Triangle3DM<T> = Triangle<T, 4>; | |
impl<T: CoordNum> Line2D<T> { | |
pub fn get_x(self) -> T { | |
self.coords[0].coord[2] | |
} | |
} | |
impl<T: CoordNum> Point2D<T> { | |
pub fn new(x: T, y: T) -> Self { | |
Self { | |
coords: [Coordinate::new([x, y])], | |
} | |
} | |
} | |
impl<T: CoordNum> Point3D<T> { | |
pub fn new(x: T, y: T, z: T) -> Self { | |
Self { | |
coords: [Coordinate::new([x, y, z])], | |
} | |
} | |
} | |
fn test() { | |
let p = Line3DM::<i64>::default(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment