use std::{fmt::Display, ops::Add};
use num_traits::Float;
use crate::{defs::{bivector::Bivector, vector::Vector}, traits::RegressiveProduct};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Point2d<N: Float> {
pub x: N,
pub y: N
}
impl<N: Float> Point2d<N> {
pub fn new(x: N, y: N) -> Point2d<N> {
Point2d {x, y}
}
pub fn to_bivector(&self) -> Bivector<N> {
Bivector {
e12: N::from(1.0).unwrap(),
e20: self.x,
e01: self.y,
}
}
pub fn from_bivector(bivector: &Bivector<N>) -> Point2d<N> {
Point2d {
x: bivector.e20/bivector.e12,
y: bivector.e01/bivector.e12,
}
}
}
impl<N: Float> Point2d<N> {
pub fn line_between_points(p1: Point2d<N>, p2: Point2d<N>) -> Vector<N> {
let bv1 = p1.to_bivector();
let bv2 = p2.to_bivector();
bv1.regressive(&bv2)
}
}
impl<N: Float+Display> Display for Point2d<N> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "[{}, {}]", self.x, self.y)
}
}
impl<N: Float> Add<Point2d<N>> for Point2d<N> {
type Output = Self;
fn add(self, rhs: Point2d<N>) -> Self::Output {
Point2d {
x: self.x + rhs.x,
y: self.y + rhs.y
}
}
}