<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use super::UnknownUnit;
use approxeq::ApproxEq;
use length::Length;
#[cfg(feature = "mint")]
use mint;
use point::{TypedPoint2D, TypedPoint3D, point2, point3};
use size::{TypedSize2D, size2};
use scale::TypedScale;
use trig::Trig;
use Angle;
use num::*;
use num_traits::{Float, NumCast, Signed};
use core::fmt;
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use core::marker::PhantomData;

/// A 2d Vector tagged with a unit.
#[derive(EuclidMatrix)]
#[repr(C)]
pub struct TypedVector2D<T, U> {
    pub x: T,
    pub y: T,
    #[doc(hidden)]
    pub _unit: PhantomData<U>,
}

mint_vec!(TypedVector2D[x, y] = Vector2);

/// Default 2d vector type with no unit.
///
/// `Vector2D` provides the same methods as `TypedVector2D`.
pub type Vector2D<T> = TypedVector2D<T, UnknownUnit>;

impl<T: Copy + Zero, U> TypedVector2D<T, U> {
    /// Constructor, setting all components to zero.
    #[inline]
    pub fn zero() -> Self {
        TypedVector2D::new(Zero::zero(), Zero::zero())
    }

    /// Convert into a 3d vector.
    #[inline]
    pub fn to_3d(&self) -> TypedVector3D<T, U> {
        vec3(self.x, self.y, Zero::zero())
    }
}

impl<T: fmt::Debug, U> fmt::Debug for TypedVector2D<T, U> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({:?},{:?})", self.x, self.y)
    }
}

impl<T: fmt::Display, U> fmt::Display for TypedVector2D<T, U> {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "({},{})", self.x, self.y)
    }
}

impl<T, U> TypedVector2D<T, U> {
    /// Constructor taking scalar values directly.
    #[inline]
    pub fn new(x: T, y: T) -> Self {
        TypedVector2D {
            x,
            y,
            _unit: PhantomData,
        }
    }
}

impl<T: Copy, U> TypedVector2D<T, U> {
    /// Constructor taking properly typed Lengths instead of scalar values.
    #[inline]
    pub fn from_lengths(x: Length<T, U>, y: Length<T, U>) -> Self {
        vec2(x.0, y.0)
    }

    /// Create a 3d vector from this one, using the specified z value.
    #[inline]
    pub fn extend(&self, z: T) -> TypedVector3D<T, U> {
        vec3(self.x, self.y, z)
    }

    /// Cast this vector into a point.
    ///
    /// Equivalent to adding this vector to the origin.
    #[inline]
    pub fn to_point(&self) -> TypedPoint2D<T, U> {
        point2(self.x, self.y)
    }

    /// Swap x and y.
    #[inline]
    pub fn yx(&self) -> Self {
        vec2(self.y, self.x)
    }

    /// Cast this vector into a size.
    #[inline]
    pub fn to_size(&self) -> TypedSize2D<T, U> {
        size2(self.x, self.y)
    }

    /// Returns self.x as a Length carrying the unit.
    #[inline]
    pub fn x_typed(&self) -> Length<T, U> {
        Length::new(self.x)
    }

    /// Returns self.y as a Length carrying the unit.
    #[inline]
    pub fn y_typed(&self) -> Length<T, U> {
        Length::new(self.y)
    }

    /// Drop the units, preserving only the numeric value.
    #[inline]
    pub fn to_untyped(&self) -> Vector2D<T> {
        vec2(self.x, self.y)
    }

    /// Tag a unit-less value with units.
    #[inline]
    pub fn from_untyped(p: &Vector2D<T>) -> Self {
        vec2(p.x, p.y)
    }

    #[inline]
    pub fn to_array(&self) -> [T; 2] {
        [self.x, self.y]
    }

    #[inline]
    pub fn to_tuple(&self) -> (T, T) {
        (self.x, self.y)
    }
}

impl<T, U> TypedVector2D<T, U>
where
    T: Trig + Copy + Sub<T, Output = T>,
{
    /// Returns the angle between this vector and the x axis between -PI and PI.
    pub fn angle_from_x_axis(&self) -> Angle<T> {
        Angle::radians(Trig::fast_atan2(self.y, self.x))
    }
}

impl<T, U> TypedVector2D<T, U>
where
    T: Copy + Mul<T, Output = T> + Add<T, Output = T> + Sub<T, Output = T>,
{
    /// Dot product.
    #[inline]
    pub fn dot(self, other: Self) -> T {
        self.x * other.x + self.y * other.y
    }

    /// Returns the norm of the cross product [self.x, self.y, 0] x [other.x, other.y, 0]..
    #[inline]
    pub fn cross(self, other: Self) -> T {
        self.x * other.y - self.y * other.x<commit_msg>Add Vector2D::to_transform()<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use super::UnknownUnit;
use approxeq::ApproxEq;
use length::Length;
#[cfg(feature = "mint")]
use mint;
use point::{TypedPoint2D, TypedPoint3D, point2, point3};
use size::{TypedSize2D, size2};
use scale::TypedScale;
use transform2d::TypedTransform2D;
use trig::Trig;
use Angle;
use num::*;
use num_traits::{Float, NumCast, Signed};
use core::fmt;
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use core::marker::PhantomData;

/// A 2d Vector tagged with a unit.
#[derive(EuclidMatrix)]
#[repr(C)]
pub struct TypedVector2D<T, U> {
    pub x: T,
    pub y: T,
    #[doc(hidden)]
    pub _unit: PhantomData<U>,
}

mint_vec!(TypedVector2D[x, y] = Vector2);

/// Default 2d vector type with no unit.
///
/// `Vector2D` provides the same methods as `TypedVector2D`.
pub type Vector2D<T> = TypedVector2D<T, UnknownUnit>;

impl<T: Copy + Zero, U> TypedVector2D<T, U> {
    /// Constructor, setting all components to zero.
    #[inline]
    pub fn zero() -> Self {
        TypedVector2D::new(Zero::zero(), Zero::zero())
    }

    /// Convert into a 3d vector.
    #[inline]
    pub fn to_3d(&self) -> TypedVector3D<T, U> {
        vec3(self.x, self.y, Zero::zero())
    }
}

impl<T: fmt::Debug, U> fmt::Debug for TypedVector2D<T, U> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({:?},{:?})", self.x, self.y)
    }
}

impl<T: fmt::Display, U> fmt::Display for TypedVector2D<T, U> {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "({},{})", self.x, self.y)
    }
}

impl<T, U> TypedVector2D<T, U> {
    /// Constructor taking scalar values directly.
    #[inline]
    pub fn new(x: T, y: T) -> Self {
        TypedVector2D {
            x,
            y,
            _unit: PhantomData,
        }
    }
}

impl<T: Copy, U> TypedVector2D<T, U> {
    /// Constructor taking properly typed Lengths instead of scalar values.
    #[inline]
    pub fn from_lengths(x: Length<T, U>, y: Length<T, U>) -> Self {
        vec2(x.0, y.0)
    }

    /// Create a 3d vector from this one, using the specified z value.
    #[inline]
    pub fn extend(&self, z: T) -> TypedVector3D<T, U> {
        vec3(self.x, self.y, z)
    }

    /// Cast this vector into a point.
    ///
    /// Equivalent to adding this vector to the origin.
    #[inline]
    pub fn to_point(&self) -> TypedPoint2D<T, U> {
        point2(self.x, self.y)
    }

    /// Swap x and y.
    #[inline]
    pub fn yx(&self) -> Self {
        vec2(self.y, self.x)
    }

    /// Cast this vector into a size.
    #[inline]
    pub fn to_size(&self) -> TypedSize2D<T, U> {
        size2(self.x, self.y)
    }

    /// Returns self.x as a Length carrying the unit.
    #[inline]
    pub fn x_typed(&self) -> Length<T, U> {
        Length::new(self.x)
    }

    /// Returns self.y as a Length carrying the unit.
    #[inline]
    pub fn y_typed(&self) -> Length<T, U> {
        Length::new(self.y)
    }

    /// Drop the units, preserving only the numeric value.
    #[inline]
    pub fn to_untyped(&self) -> Vector2D<T> {
        vec2(self.x, self.y)
    }

    /// Tag a unit-less value with units.
    #[inline]
    pub fn from_untyped(p: &Vector2D<T>) -> Self {
        vec2(p.x, p.y)
    }

    #[inline]
    pub fn to_array(&self) -> [T; 2] {
        [self.x, self.y]
    }

    #[inline]
    pub fn to_tuple(&self) -> (T, T) {
        (self.x, self.y)
    }
}

impl<T, U> TypedVector2D<T, U>
where
    T: Copy
        + Clone
        + Add<T, Output = T>
        + Mul<T, Output = T>
        + Div<T, Output = T>
        + Sub<T, Output = T>
        + Trig
        + PartialOrd
        + One
        + Zero {
    #[inline]
    pub fn to_transform(&self) -> TypedTransform2D<T, U, U> {
        TypedTransform2D::create_translation(self.x, self.y)
    }
}

impl<T, U> TypedVector2D<T, U>
where
    T: Trig + Copy + Sub<T, Output = T>,
{
    /// Returns the angle between this vector and the x axis between -PI and PI.
    pub fn angle_from_x_axis(&self) -> Angle<T> {
        Angle::radians(Trig::fast_atan2(self.y, self.x))
    }
}

impl<T, U> TypedVector2D<T, U>
where
    T: Copy + Mul<T, Output = T> + Add<T, Output = T> + Sub<T, Output = T>,
{
    /// Dot product.
    #[inline]
    pub fn dot(self, other: Self) -> T {
        self.x * other.x + self.y * other.y
    }

    /// Returns the norm of the cross product [self.x, self.y, 0] x [other.x, other.y, 0]..
    #[inline]
    pub fn cross(self, other: Self) -> T {
        self.x * other.y - self.y * other.x
{'fraction_non_alphanumeric': 0.1636325591127851, 'fraction_numerical': 0.01213643021552626, 'mean_word_length': 2.4397265203310545, 'pattern_counts': {'":': 0, '<': 80, '<?xml version=': 0, '>': 119, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1622198', 'n_tokens_mistral': 3559, 'n_tokens_neox': 3550, 'n_words': 1003}