use std::fmt;
use std::ops::Add;
use std::ops::Div;
use std::ops::Mul;
use std::ops::Sub;
use crate::core::geometry::vector::Vector2;
use crate::core::geometry::Number;
use crate::Float;
#[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct Point2<T>
where
T: Number,
{
pub x: T,
pub y: T,
}
impl<T> Point2<T>
where
T: Number,
{
pub fn min(p1: Point2<T>, p2: Point2<T>) -> Point2<T> {
let x = p1.x.min(p2.x);
let y = p1.y.min(p2.y);
Point2 { x, y }
}
pub fn max(p1: Point2<T>, p2: Point2<T>) -> Point2<T> {
let x = p1.x.max(p2.x);
let y = p1.y.max(p2.y);
Point2 { x, y }
}
}
impl<T> From<[T; 2]> for Point2<T>
where
T: Number,
{
fn from(xy: [T; 2]) -> Self {
Point2 { x: xy[0], y: xy[1] }
}
}
impl<T> From<(T, T)> for Point2<T>
where
T: Number,
{
fn from((x, y): (T, T)) -> Self {
Point2 { x, y }
}
}
impl<T> fmt::Display for Point2<T>
where
T: Number,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[ {}, {} ]", self.x, self.y)
}
}
impl<T> Div<T> for Point2<T>
where
T: Number,
{
type Output = Self;
fn div(self, rhs: T) -> Self::Output {
Point2 {
x: self.x / rhs,
y: self.y / rhs,
}
}
}
impl<T> Mul<T> for Point2<T>
where
T: Number,
{
type Output = Self;
fn mul(self, rhs: T) -> Self::Output {
Point2 {
x: self.x * rhs,
y: self.y * rhs,
}
}
}
impl<T> Sub for Point2<T>
where
T: Number,
{
type Output = Vector2<T>;
fn sub(self, rhs: Self) -> Self::Output {
Vector2 {
x: self.x - rhs.x,
y: self.y - rhs.y,
}
}
}
impl<T> Sub<Vector2<T>> for Point2<T>
where
T: Number,
{
type Output = Self;
fn sub(self, rhs: Vector2<T>) -> Self::Output {
Point2 {
x: self.x - rhs.x,
y: self.y - rhs.y,
}
}
}
impl<T> Add for Point2<T>
where
T: Number,
{
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Point2 {
x: self.x + rhs.x,
y: self.y + rhs.y,
}
}
}
impl<T> Add<Vector2<T>> for Point2<T>
where
T: Number,
{
type Output = Self;
fn add(self, rhs: Vector2<T>) -> Self::Output {
Point2 {
x: self.x + rhs.x,
y: self.y + rhs.y,
}
}
}
pub type Point2f = Point2<Float>;
impl Point2f {
pub fn floor(&self) -> Point2f {
[self.x.floor(), self.y.floor()].into()
}
pub fn ceil(&self) -> Point2f {
[self.x.ceil(), self.y.ceil()].into()
}
}
impl From<Point2i> for Point2f {
fn from(p: Point2i) -> Self {
Self {
x: p.x as Float,
y: p.y as Float,
}
}
}
pub type Point2i = Point2<isize>;
impl From<Point2f> for Point2i {
fn from(p: Point2f) -> Self {
Self {
x: p.x as isize,
y: p.y as isize,
}
}
}
#[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct Point3<T> {
pub x: T,
pub y: T,
pub z: T,
}
impl<T> Point3<T>
where
T: Number,
{
pub fn min(p1: Point3<T>, p2: Point3<T>) -> Point3<T> {
let x = p1.x.min(p2.x);
let y = p1.y.min(p2.y);
let z = p1.z.min(p2.z);
Point3 { x, y, z }
}
pub fn max(p1: Point3<T>, p2: Point3<T>) -> Point3<T> {
let x = p1.x.max(p2.x);
let y = p1.y.max(p2.y);
let z = p1.z.max(p2.z);
Point3 { x, y, z }
}
}
impl<T> From<[T; 3]> for Point3<T>
where
T: Number,
{
fn from(xyz: [T; 3]) -> Self {
Point3 {
x: xyz[0],
y: xyz[1],
z: xyz[2],
}
}
}
pub type Point3f = Point3<Float>;
impl Point3f {
pub fn floor(&self) -> Point3f {
[self.x.floor(), self.y.floor(), self.z.floor()].into()
}
pub fn ceil(&self) -> Point3f {
[self.x.ceil(), self.y.ceil(), self.z.ceil()].into()
}
}
pub type Point3i = Point3<isize>;