feat(math): add Vec2 and Vec4 types

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-24 19:45:28 +09:00
parent 870c412270
commit c644b784a6
3 changed files with 223 additions and 0 deletions

View File

@@ -1,2 +1,7 @@
pub mod vec2;
pub mod vec3;
pub mod vec4;
pub use vec2::Vec2;
pub use vec3::Vec3;
pub use vec4::Vec4;

View File

@@ -0,0 +1,106 @@
use std::ops::{Add, Sub, Mul, Neg};
/// 2D vector (f32)
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Vec2 {
pub x: f32,
pub y: f32,
}
impl Vec2 {
pub const ZERO: Self = Self { x: 0.0, y: 0.0 };
pub const ONE: Self = Self { x: 1.0, y: 1.0 };
pub const fn new(x: f32, y: f32) -> Self {
Self { x, y }
}
pub fn dot(self, rhs: Self) -> f32 {
self.x * rhs.x + self.y * rhs.y
}
pub fn length_squared(self) -> f32 {
self.dot(self)
}
pub fn length(self) -> f32 {
self.length_squared().sqrt()
}
pub fn normalize(self) -> Self {
let len = self.length();
Self {
x: self.x / len,
y: self.y / len,
}
}
}
impl Add for Vec2 {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self { x: self.x + rhs.x, y: self.y + rhs.y }
}
}
impl Sub for Vec2 {
type Output = Self;
fn sub(self, rhs: Self) -> Self {
Self { x: self.x - rhs.x, y: self.y - rhs.y }
}
}
impl Mul<f32> for Vec2 {
type Output = Self;
fn mul(self, rhs: f32) -> Self {
Self { x: self.x * rhs, y: self.y * rhs }
}
}
impl Neg for Vec2 {
type Output = Self;
fn neg(self) -> Self {
Self { x: -self.x, y: -self.y }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new() {
let v = Vec2::new(1.0, 2.0);
assert_eq!(v.x, 1.0);
assert_eq!(v.y, 2.0);
}
#[test]
fn test_add() {
let a = Vec2::new(1.0, 2.0);
let b = Vec2::new(3.0, 4.0);
let c = a + b;
assert_eq!(c, Vec2::new(4.0, 6.0));
}
#[test]
fn test_dot() {
let a = Vec2::new(1.0, 2.0);
let b = Vec2::new(3.0, 4.0);
assert_eq!(a.dot(b), 11.0);
}
#[test]
fn test_length() {
let v = Vec2::new(3.0, 4.0);
assert!((v.length() - 5.0).abs() < f32::EPSILON);
}
#[test]
fn test_normalize() {
let v = Vec2::new(4.0, 0.0);
let n = v.normalize();
assert!((n.length() - 1.0).abs() < 1e-6);
assert_eq!(n, Vec2::new(1.0, 0.0));
}
}

View File

@@ -0,0 +1,112 @@
use std::ops::{Add, Sub, Mul, Neg};
use crate::Vec3;
/// 4D vector (f32)
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Vec4 {
pub x: f32,
pub y: f32,
pub z: f32,
pub w: f32,
}
impl Vec4 {
pub const ZERO: Self = Self { x: 0.0, y: 0.0, z: 0.0, w: 0.0 };
pub const ONE: Self = Self { x: 1.0, y: 1.0, z: 1.0, w: 1.0 };
pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
Self { x, y, z, w }
}
pub fn from_vec3(v: Vec3, w: f32) -> Self {
Self { x: v.x, y: v.y, z: v.z, w }
}
pub fn xyz(self) -> Vec3 {
Vec3::new(self.x, self.y, self.z)
}
pub fn dot(self, rhs: Self) -> f32 {
self.x * rhs.x + self.y * rhs.y + self.z * rhs.z + self.w * rhs.w
}
pub fn length_squared(self) -> f32 {
self.dot(self)
}
pub fn length(self) -> f32 {
self.length_squared().sqrt()
}
}
impl Add for Vec4 {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self { x: self.x + rhs.x, y: self.y + rhs.y, z: self.z + rhs.z, w: self.w + rhs.w }
}
}
impl Sub for Vec4 {
type Output = Self;
fn sub(self, rhs: Self) -> Self {
Self { x: self.x - rhs.x, y: self.y - rhs.y, z: self.z - rhs.z, w: self.w - rhs.w }
}
}
impl Mul<f32> for Vec4 {
type Output = Self;
fn mul(self, rhs: f32) -> Self {
Self { x: self.x * rhs, y: self.y * rhs, z: self.z * rhs, w: self.w * rhs }
}
}
impl Neg for Vec4 {
type Output = Self;
fn neg(self) -> Self {
Self { x: -self.x, y: -self.y, z: -self.z, w: -self.w }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new() {
let v = Vec4::new(1.0, 2.0, 3.0, 4.0);
assert_eq!(v.x, 1.0);
assert_eq!(v.y, 2.0);
assert_eq!(v.z, 3.0);
assert_eq!(v.w, 4.0);
}
#[test]
fn test_from_vec3() {
let v3 = Vec3::new(1.0, 2.0, 3.0);
let v4 = Vec4::from_vec3(v3, 1.0);
assert_eq!(v4, Vec4::new(1.0, 2.0, 3.0, 1.0));
}
#[test]
fn test_xyz() {
let v4 = Vec4::new(1.0, 2.0, 3.0, 4.0);
let v3 = v4.xyz();
assert_eq!(v3, Vec3::new(1.0, 2.0, 3.0));
}
#[test]
fn test_dot() {
let a = Vec4::new(1.0, 2.0, 3.0, 4.0);
let b = Vec4::new(5.0, 6.0, 7.0, 8.0);
assert_eq!(a.dot(b), 70.0);
}
#[test]
fn test_add() {
let a = Vec4::new(1.0, 2.0, 3.0, 4.0);
let b = Vec4::new(5.0, 6.0, 7.0, 8.0);
let c = a + b;
assert_eq!(c, Vec4::new(6.0, 8.0, 10.0, 12.0));
}
}