use crate::common;
use crate::vector3::Vector3;
use std::cmp;
use std::convert::From;
use std::f32::EPSILON;
use std::fmt;
use std::fmt::{Display, Formatter};
use std::ops::{
Index,
IndexMut,
Neg,
Add,
AddAssign,
Sub,
SubAssign,
Mul,
MulAssign,
Div,
DivAssign,
};
#[repr(C, packed)]
#[derive(Copy, Clone, Debug)]
pub struct Vector2 {
pub x: f32,
pub y: f32,
}
impl Vector2 {
#[inline]
pub fn new() -> Vector2 {
Vector2 { x: 0.0, y: 0.0 }
}
#[inline]
pub fn one() -> Vector2 {
Vector2 { x: 1.0, y: 1.0 }
}
#[inline]
pub fn make(x: f32, y: f32) -> Vector2 {
Vector2 { x, y }
}
#[inline]
pub fn dot(a: &Vector2, b: &Vector2) -> f32 {
a.x * b.x + a.y * b.y
}
#[inline]
pub fn cross(a: &Vector2, b: &Vector2) -> f32 {
a.x * b.y - a.y * b.x
}
#[inline]
pub fn cross_scalar_vec(s: f32, v: &Vector2) -> Vector2 {
Vector2::make(-s * v.y, s * v.x)
}
#[inline]
pub fn cross_vec_scalar(v: &Vector2, s: f32) -> Vector2 {
Vector2::make(s * v.y, -s * v.x)
}
#[inline]
pub fn min(a: &Vector2, b: &Vector2) -> Vector2 {
Vector2::make(a.x.min(b.x), a.y.min(b.y))
}
#[inline]
pub fn max(a: &Vector2, b: &Vector2) -> Vector2 {
Vector2::make(a.x.max(b.x), a.y.max(b.y))
}
#[inline]
pub fn clamp(&mut self, a: &Vector2, b: &Vector2) {
let low = Self::min(a, b);
let high = Self::max(a, b);
let result = Self::max(&low, &Self::min(self, &high));
self.set(result.x, result.y);
}
#[inline]
pub fn set(&mut self, x: f32, y: f32) {
self.x = x;
self.y = y;
}
#[inline]
pub fn mag(&self) -> f32 {
self.mag_sq().sqrt()
}
#[inline]
pub fn mag_sq(&self) -> f32 {
self.x * self.x + self.y * self.y
}
#[inline]
pub fn norm(&mut self) -> f32 {
let length = self.mag();
if length > EPSILON {
self.x /= length;
self.y /= length;
length
} else {
0.0
}
}
#[inline]
pub fn abs(&mut self) {
self.x = self.x.abs();
self.y = self.y.abs();
}
#[inline]
pub fn skew(&mut self) {
let x = self.x;
self.x = -self.y;
self.y = x;
}
#[inline]
pub fn is_valid(&self) -> bool {
for i in 0..2 {
if !common::is_valid(self[i]) {
return false;
}
}
true
}
}
impl From<Vector3> for Vector2 {
#[inline]
fn from(item: Vector3) -> Self {
Vector2 {
x: item.x,
y: item.y,
}
}
}
impl Index<u32> for Vector2 {
type Output = f32;
#[inline]
fn index(&self, index: u32) -> &f32 {
unsafe {
match index {
0 => &self.x,
1 => &self.y,
_ => panic!("Invalid index for Vector2: {}", index),
}
}
}
}
impl IndexMut<u32> for Vector2 {
#[inline]
fn index_mut<'a>(&'a mut self, index: u32) -> &'a mut f32 {
unsafe {
match index {
0 => &mut self.x,
1 => &mut self.y,
_ => panic!("Invalid index for Vector2: {}", index),
}
}
}
}
impl Neg for Vector2 {
type Output = Vector2;
#[inline]
fn neg(self) -> Vector2 {
Vector2::make(-self.x, -self.y)
}
}
impl Add<f32> for Vector2 {
type Output = Vector2;
#[inline]
fn add(self, _rhs: f32) -> Vector2 {
Vector2::make(self.x + _rhs, self.y + _rhs)
}
}
impl Add<Vector2> for Vector2 {
type Output = Vector2;
#[inline]
fn add(self, _rhs: Vector2) -> Vector2 {
Vector2::make(self.x + _rhs.x, self.y + _rhs.y)
}
}
impl AddAssign<f32> for Vector2 {
#[inline]
fn add_assign(&mut self, _rhs: f32) {
self.x += _rhs;
self.y += _rhs;
}
}
impl AddAssign<Vector2> for Vector2 {
#[inline]
fn add_assign(&mut self, _rhs: Vector2) {
self.x += _rhs.x;
self.y += _rhs.y;
}
}
impl Sub<f32> for Vector2 {
type Output = Vector2;
#[inline]
fn sub(self, _rhs: f32) -> Vector2 {
Vector2::make(self.x - _rhs, self.y - _rhs)
}
}
impl Sub<Vector2> for Vector2 {
type Output = Vector2;
#[inline]
fn sub(self, _rhs: Vector2) -> Vector2 {
Vector2::make(self.x - _rhs.x, self.y - _rhs.y)
}
}
impl SubAssign<f32> for Vector2 {
#[inline]
fn sub_assign(&mut self, _rhs: f32) {
self.x -= _rhs;
self.y -= _rhs;
}
}
impl SubAssign<Vector2> for Vector2 {
#[inline]
fn sub_assign(&mut self, _rhs: Vector2) {
self.x -= _rhs.x;
self.y -= _rhs.y;
}
}
impl Mul<f32> for Vector2 {
type Output = Vector2;
#[inline]
fn mul(self, _rhs: f32) -> Vector2 {
Vector2::make(self.x * _rhs, self.y * _rhs)
}
}
impl Mul<Vector2> for Vector2 {
type Output = Vector2;
#[inline]
fn mul(self, _rhs: Vector2) -> Vector2 {
Vector2::make(self.x * _rhs.x, self.y * _rhs.y)
}
}
impl MulAssign<f32> for Vector2 {
#[inline]
fn mul_assign(&mut self, _rhs: f32) {
self.x *= _rhs;
self.y *= _rhs;
}
}
impl MulAssign<Vector2> for Vector2 {
#[inline]
fn mul_assign(&mut self, _rhs: Vector2) {
self.x *= _rhs.x;
self.y *= _rhs.y;
}
}
impl Div<f32> for Vector2 {
type Output = Vector2;
#[inline]
fn div(self, _rhs: f32) -> Vector2 {
Vector2::make(self.x / _rhs, self.y / _rhs)
}
}
impl Div<Vector2> for Vector2 {
type Output = Vector2;
#[inline]
fn div(self, _rhs: Vector2) -> Vector2 {
Vector2::make(self.x / _rhs.x, self.y / _rhs.y)
}
}
impl DivAssign<f32> for Vector2 {
#[inline]
fn div_assign(&mut self, _rhs: f32) {
self.x /= _rhs;
self.y /= _rhs;
}
}
impl DivAssign<Vector2> for Vector2 {
#[inline]
fn div_assign(&mut self, _rhs: Vector2) {
self.x /= _rhs.x;
self.y /= _rhs.y;
}
}
impl cmp::PartialEq for Vector2 {
#[inline]
fn eq(&self, _rhs: &Vector2) -> bool {
for i in 0..2 {
if self[i] != _rhs[i] {
return false;
}
}
true
}
}
impl Display for Vector2 {
#[inline]
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
unsafe { write!(f, "<{} {}>", self.x, self.y) }
}
}