use prelude::*;
use super::{Vec3, Vector, Angle, Rect, Point2};
#[derive(Copy, Clone)]
#[cfg_attr(feature = "serialize-serde", derive(Deserialize, Serialize))]
pub struct Vec2<T = f32>(pub T, pub T);
impl<T> Vec2<T> where T: Float {
pub fn new() -> Self {
Vec2::<T>(T::zero(), T::zero())
}
pub fn len(self: &Self) -> T {
(self.0*self.0 + self.1*self.1).sqrt()
}
pub fn dot(self: &Self, other: &Self) -> T {
self.0 * other.0 + self.1 * other.1
}
#[deprecated(since = "0.2.2", note = "use Angle::from().to_radians() instead")]
pub fn to_radians(self: &Self) -> T {
self.1.atan2(self.0)
}
#[deprecated(since = "0.2.2", note = "use Angle::from().to_degrees() instead")]
pub fn to_degrees(self: &Self) -> T {
Angle::from(*self).to_degrees()
}
#[deprecated(since = "0.2.2", note = "use Angle::from() instead")]
pub fn to_angle(self: &Self) -> Angle<T> {
Angle::from(*self)
}
#[deprecated(since = "0.2.2", note = "use Vec2::from(Angle::from_radians()) instead")]
pub fn from_radians(radians: T) -> Self {
Vec2::<T>(radians.cos(), radians.sin())
}
#[deprecated(since = "0.2.2", note = "use Vec2::from(Angle::from_degrees()) instead")]
pub fn from_degrees(degrees: T) -> Self {
Self::from(Angle::from_degrees(degrees))
}
#[deprecated(since = "0.2.2", note = "use Vec2::from() instead")]
pub fn from_angle(angle: Angle<T>) -> Self {
Self::from(angle)
}
pub fn normalize(mut self: Self) -> Self {
let len = self.len();
if len > T::zero() {
self.0 = self.0 / len;
self.1 = self.1 / len;
}
self
}
pub fn left(mut self: Self) -> Self {
let x = self.0;
self.0 = -self.1;
self.1 = x;
self
}
pub fn right(mut self: Self) -> Self {
let x = self.0;
self.0 = self.1;
self.1 = -x;
self
}
pub fn extend(mut self: Self, extension_len: T) -> Self {
let base_len = self.len();
if base_len > T::zero() {
let new_len = base_len + extension_len;
let factor = new_len / base_len;
self.0 = self.0 * factor;
self.1 = self.1 * factor;
}
self
}
pub fn rotate(self: Self, angle: Angle<T>) -> Self {
let cos = angle.0.cos();
let sin = angle.0.sin();
Vec2(
cos * self.0 - sin * self.1,
sin * self.0 + cos * self.1
)
}
pub fn outbound(self: &Self, bounding: Rect<T>) -> Option<Self> {
let min = bounding.0;
let max = bounding.1;
let outside = Vec2(
if self.0 < min.0 { self.0 - min.0 } else if self.0 > max.0 { self.0 - max.0 } else { T::zero() },
if self.1 < min.1 { self.1 - min.1 } else if self.1 > max.1 { self.1 - max.1 } else { T::zero() }
);
if (outside.0 != T::zero()) || (outside.1 != T::zero()) { Some(outside) } else { None }
}
pub fn is_zero(self: &Self) -> bool {
self.0 == T::zero() && self.1 == T::zero()
}
pub fn distance(self: &Self, other: &Self) -> T{
let dv = *self - *other;
(dv.0 * dv.0 + dv.1 * dv.1).sqrt()
}
}
impl<T> Vector<T> for Vec2<T> where T: Copy {
fn as_vec3(&self, neutral: T) -> Vec3<T> {
Vec3::<T>(self.0, self.1, neutral)
}
}
impl<T> From<Angle<T>> for Vec2<T> where T: Float {
fn from(angle: Angle<T>) -> Vec2<T> {
Vec2::<T>(angle.0.cos(), angle.0.sin())
}
}
impl<T> From<[ T; 2 ]> for Vec2<T> where T: Copy {
fn from(source: [ T; 2 ]) -> Self {
Vec2(source[0], source[1])
}
}
impl From<Vec2<f32>> for [ f32; 2 ] {
fn from(source: Vec2<f32>) -> Self {
[ source.0, source.1 ]
}
}
impl From<Vec2<f64>> for [ f64; 2 ] {
fn from(source: Vec2<f64>) -> Self {
[ source.0, source.1 ]
}
}
impl<T> From<Point2<T>> for Vec2<T> {
fn from(source: Point2<T>) -> Self {
Vec2(source.0, source.1)
}
}
impl From<Vec2<f32>> for Point2<f32> {
fn from(source: Vec2<f32>) -> Self {
(source.0, source.1)
}
}
impl From<Vec2<f64>> for Point2<f64> {
fn from(source: Vec2<f64>) -> Self {
(source.0, source.1)
}
}
impl<T> Default for Vec2<T> where T: Float {
fn default() -> Self {
Vec2(T::zero(), T::zero())
}
}
impl<T> Neg for Vec2<T> where T: Float {
type Output = Vec2<T>;
fn neg(self) -> Vec2<T> {
Vec2::<T>(-self.0, -self.1)
}
}
impl<T> Add for Vec2<T> where T: Float {
type Output = Vec2<T>;
fn add(self, other: Vec2<T>) -> Vec2<T> {
Vec2::<T>(self.0 + other.0, self.1 + other.1)
}
}
impl<T> AddAssign for Vec2<T> where T: Float {
fn add_assign(self: &mut Self, other: Vec2<T>) {
*self = Vec2::<T> (
self.0 + other.0,
self.1 + other.1
)
}
}
impl<T> Sub for Vec2<T> where T: Float {
type Output = Vec2<T>;
fn sub(self, other: Vec2<T>) -> Vec2<T> {
Vec2::<T>(self.0 - other.0, self.1 - other.1)
}
}
impl<T> SubAssign for Vec2<T> where T: Float {
fn sub_assign(self: &mut Self, other: Vec2<T>) {
*self = Vec2::<T> (
self.0 - other.0,
self.1 - other.1
)
}
}
impl<T> Mul<Vec2<T>> for Vec2<T> where T: Float {
type Output = Vec2<T>;
fn mul(self, other: Vec2<T>) -> Vec2<T> {
Vec2::<T>(self.0 * other.0, self.1 * other.1)
}
}
impl<T> MulAssign<Vec2<T>> for Vec2<T> where T: Float {
fn mul_assign(&mut self, other: Vec2<T>) {
*self = Vec2::<T>(self.0 * other.0, self.1 * other.1)
}
}
impl<T> Mul<T> for Vec2<T> where T: Float {
type Output = Vec2<T>;
fn mul(self, other: T) -> Vec2<T> {
Vec2::<T>(self.0 * other, self.1 * other)
}
}
impl<T> MulAssign<T> for Vec2<T> where T: Float {
fn mul_assign(&mut self, other: T) {
*self = Vec2::<T>(self.0 * other, self.1 * other)
}
}
impl<T> Div<Vec2<T>> for Vec2<T> where T: Float {
type Output = Vec2<T>;
fn div(self, other: Vec2<T>) -> Vec2<T> {
Vec2::<T>(self.0 / other.0, self.1 / other.1)
}
}
impl<T> DivAssign<Vec2<T>> for Vec2<T> where T: Float {
fn div_assign(&mut self, other: Vec2<T>) {
*self = Vec2::<T>(self.0 / other.0, self.1 / other.1)
}
}
impl<T> Div<T> for Vec2<T> where T: Float {
type Output = Vec2<T>;
fn div(self, other: T) -> Vec2<T> {
Vec2::<T>(self.0 / other, self.1 / other)
}
}
impl<T> DivAssign<T> for Vec2<T> where T: Float {
fn div_assign(&mut self, other: T) {
*self = Vec2::<T>(self.0 / other, self.1 / other)
}
}
impl Mul<Vec2<f32>> for f32 {
type Output = Vec2<f32>;
fn mul(self, other: Vec2<f32>) -> Vec2<f32> {
Vec2::<f32>(self * other.0, self * other.1)
}
}
impl Mul<Vec2<f64>> for f64 {
type Output = Vec2<f64>;
fn mul(self, other: Vec2<f64>) -> Vec2<f64> {
Vec2::<f64>(self * other.0, self * other.1)
}
}
#[cfg(feature = "uniforms")]
use radiant_rs::{Uniform, AsUniform};
#[cfg(feature = "uniforms")]
impl AsUniform for Vec2<f32> {
fn as_uniform(&self) -> Uniform {
Uniform::Vec2([ self.0, self.1 ])
}
}
#[cfg(feature = "uniforms")]
impl AsUniform for Vec2<f64> {
fn as_uniform(&self) -> Uniform {
Uniform::DoubleVec2([ self.0, self.1 ])
}
}
impl<T> Debug for Vec2<T> where T: Debug {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Vec2({:?}, {:?})", self.0, self.1)
}
}