use crate::*;
use std::ops::{Div, DivAssign, Mul, MulAssign, Sub};
use derive_more::{Add, AddAssign, Neg, Sub, SubAssign};
use inner_space::{DotProduct, VectorSpace};
use scalars::{Real, Zero};
use vector_basis::Basis;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Add, AddAssign, Sub, SubAssign, Neg)]
pub struct Vector<T> {
pub x: T,
pub y: T,
}
impl<T> Vector<T> {
pub fn new(x: T, y: T) -> Self {
Self { x, y }
}
}
impl<T: Zero> Vector<T> {
pub fn x(x: T) -> Self {
Self { x, y: T::zero() }
}
pub fn y(y: T) -> Self {
Self { x: T::zero(), y }
}
}
impl<T: Real> Basis<0> for Vector<T> {
fn unit_basis() -> Self {
Self {
x: T::one(),
y: T::zero(),
}
}
fn basis_of(x: T) -> Self {
Self { x, y: T::zero() }
}
fn basis(&self) -> Self::Scalar {
self.x
}
fn basis_mut(&mut self) -> &mut Self::Scalar {
&mut self.x
}
fn with_basis(self, x: T) -> Self {
Self { x, ..self }
}
}
impl<T: Real> Basis<1> for Vector<T> {
fn unit_basis() -> Self {
Self {
x: T::zero(),
y: T::one(),
}
}
fn basis_of(y: T) -> Self {
Self { x: T::zero(), y }
}
fn basis(&self) -> Self::Scalar {
self.y
}
fn basis_mut(&mut self) -> &mut Self::Scalar {
&mut self.y
}
fn with_basis(self, y: T) -> Self {
Self { y, ..self }
}
}
impl<T: Zero> Zero for Vector<T> {
fn zero() -> Self {
Self {
x: T::zero(),
y: T::zero(),
}
}
fn is_zero(&self) -> bool {
self.x.is_zero() && self.y.is_zero()
}
}
impl<T> Mul<T> for Vector<T>
where
T: Mul<Output = T> + Copy,
{
type Output = Self;
fn mul(self, other: T) -> Self {
Self {
x: self.x * other,
y: self.y * other,
}
}
}
impl<T> MulAssign<T> for Vector<T>
where
T: MulAssign + Copy,
{
fn mul_assign(&mut self, other: T) {
self.x *= other;
self.y *= other;
}
}
impl<T> Div<T> for Vector<T>
where
T: Div<Output = T> + Copy,
{
type Output = Self;
fn div(self, other: T) -> Self {
Self {
x: self.x / other,
y: self.y / other,
}
}
}
impl<T> DivAssign<T> for Vector<T>
where
T: DivAssign + Copy,
{
fn div_assign(&mut self, other: T) {
self.x /= other;
self.y /= other;
}
}
impl<T: Real> VectorSpace for Vector<T> {
type Scalar = T;
}
impl<T: Real> DotProduct for Vector<T> {
type Output = Self::Scalar;
fn dot(&self, other: &Self) -> T {
self.x * other.x + self.y * other.y
}
}
impl<T: Real> DotProduct<Bivector<T>> for Vector<T> {
type Output = Self;
fn dot(&self, other: &Bivector<T>) -> Self {
Self {
x: -self.y * other.xy,
y: self.x * other.xy,
}
}
}
impl<T: Real> DotProduct<Rotor<T>> for Vector<T> {
type Output = Self;
fn dot(&self, other: &Rotor<T>) -> Self {
*self * other.scalar
+ Self {
x: -self.y * other.xy,
y: self.x * other.xy,
}
}
}
impl<T: Real> Mul for Vector<T> {
type Output = Rotor<T>;
fn mul(self, other: Self) -> Rotor<T> {
Rotor {
scalar: self.dot(&other),
xy: self.x * other.y - self.y * other.x,
}
}
}
impl<T> From<[T; 2]> for Vector<T> {
fn from([x, y]: [T; 2]) -> Self {
Self { x, y }
}
}
impl<T> From<Vector<T>> for [T; 2] {
fn from(Vector { x, y }: Vector<T>) -> Self {
[x, y]
}
}
impl<T> From<(T, T)> for Vector<T> {
fn from((x, y): (T, T)) -> Self {
Self { x, y }
}
}
impl<T> From<Vector<T>> for (T, T) {
fn from(Vector { x, y }: Vector<T>) -> Self {
(x, y)
}
}
impl<T> Vector<T>
where
T: Mul<Output = T> + Sub<Output = T> + Copy,
{
pub fn wedge(self, other: Self) -> Bivector<T> {
Bivector {
xy: self.x * other.y - self.y * other.x,
}
}
}
impl<T: std::fmt::Display> std::fmt::Display for Vector<T> {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(formatter, "({}, {})", self.x, self.y)
}
}
impl<T: std::str::FromStr> std::str::FromStr for Vector<T> {
type Err = String;
fn from_str(source: &str) -> Result<Self, Self::Err> {
let trimmed = source
.strip_prefix('(')
.and_then(|s| s.strip_suffix(')'))
.ok_or_else(|| format!("expected format (x, y), got {source}"))?;
let mut parts = trimmed.split(',');
let x = parts
.next()
.ok_or_else(|| "missing x component".to_string())?
.trim()
.parse::<T>()
.map_err(|_| "failed to parse x component".to_string())?;
let y = parts
.next()
.ok_or_else(|| "missing y component".to_string())?
.trim()
.parse::<T>()
.map_err(|_| "failed to parse y component".to_string())?;
if parts.next().is_some() {
return Err("too many components".to_string());
}
Ok(Self { x, y })
}
}