rustraight 0.6.4

A simple 2D game library for Rust, inspired by DXLib
// geometry2d.rs — 2D空間の座標・方向を表す軽量なVec2型と、回転・法線などの基本演算を提供する。

use std::ops::{Add, Div, Mul, Neg, Sub};

/// 2次元ベクトル。
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Vec2 {
    pub x: f32,
    pub y: f32,
}

impl Vec2 {
    pub const ZERO: Vec2 = Vec2 { x: 0.0, y: 0.0 };

    pub const fn new(x: f32, y: f32) -> Self {
        Self { x, y }
    }

    pub fn dot(self, rhs: Vec2) -> f32 {
        self.x * rhs.x + self.y * rhs.y
    }

    /// 2Dの疑似外積(符号付き面積の2倍)。向き判定(左右どちらに曲がるか等)に使う。
    pub fn cross(self, rhs: Vec2) -> f32 {
        self.x * rhs.y - self.y * rhs.x
    }

    pub fn length_squared(self) -> f32 {
        self.dot(self)
    }

    pub fn length(self) -> f32 {
        self.length_squared().sqrt()
    }

    /// 単位ベクトル化する。長さが0に近い場合のガードは無い
    /// (呼び出し側がゼロベクトルを渡さないことを前提とする)。
    pub fn normalize(self) -> Vec2 {
        self / self.length()
    }

    /// 反時計回りに90度回転したベクトル(法線ベクトルの計算に使う)。
    pub fn perp(self) -> Vec2 {
        Vec2::new(-self.y, self.x)
    }

    /// 原点を中心に `radians` ラジアン回転したベクトルを返す。
    pub fn rotate(self, radians: f32) -> Vec2 {
        let (s, c) = radians.sin_cos();
        Vec2::new(self.x * c - self.y * s, self.x * s + self.y * c)
    }

    /// 角度から単位ベクトルを作る(`(cos(radians), sin(radians))`)。
    pub fn from_angle(radians: f32) -> Vec2 {
        let (s, c) = radians.sin_cos();
        Vec2::new(c, s)
    }
}

impl Add<Vec2> for Vec2 {
    type Output = Vec2;
    fn add(self, rhs: Vec2) -> Vec2 {
        Vec2::new(self.x + rhs.x, self.y + rhs.y)
    }
}

impl Sub<Vec2> for Vec2 {
    type Output = Vec2;
    fn sub(self, rhs: Vec2) -> Vec2 {
        Vec2::new(self.x - rhs.x, self.y - rhs.y)
    }
}

/// スカラー倍(一様スケール)。
impl Mul<f32> for Vec2 {
    type Output = Vec2;
    fn mul(self, rhs: f32) -> Vec2 {
        Vec2::new(self.x * rhs, self.y * rhs)
    }
}

/// 要素ごとの積(軸ごとに異なる拡大率をかけたい場合に使う)。
impl Mul<Vec2> for Vec2 {
    type Output = Vec2;
    fn mul(self, rhs: Vec2) -> Vec2 {
        Vec2::new(self.x * rhs.x, self.y * rhs.y)
    }
}

impl Div<f32> for Vec2 {
    type Output = Vec2;
    fn div(self, rhs: f32) -> Vec2 {
        Vec2::new(self.x / rhs, self.y / rhs)
    }
}

impl Neg for Vec2 {
    type Output = Vec2;
    fn neg(self) -> Vec2 {
        Vec2::new(-self.x, -self.y)
    }
}

impl From<Vec2> for [f32; 2] {
    fn from(v: Vec2) -> [f32; 2] {
        [v.x, v.y]
    }
}

impl From<[f32; 2]> for Vec2 {
    fn from(v: [f32; 2]) -> Vec2 {
        Vec2::new(v[0], v[1])
    }
}