docs(math): added more documentation for bezier, matrix, noise, point, polynomial, quaternion and vector

This commit is contained in:
lisk77 2025-08-14 09:27:07 +02:00
parent 30c6327997
commit 5f97d3a881
8 changed files with 399 additions and 239 deletions

View file

@ -1,11 +1,13 @@
use crate::{InnerSpace, Point}; use crate::{InnerSpace, Point};
/// Representation of a Bezier curve of degree n in any (2-4) dimensions.
pub struct Bezier<V: InnerSpace> { pub struct Bezier<V: InnerSpace> {
points: Vec<V>, points: Vec<V>,
degree: usize, degree: usize,
} }
impl<V: InnerSpace + Clone> Bezier<V> { impl<V: InnerSpace + Clone> Bezier<V> {
/// Creates a new Bezier curve with the given control points.
pub fn new(points: Vec<V>) -> Self { pub fn new(points: Vec<V>) -> Self {
let degree = points.len() - 1; let degree = points.len() - 1;

View file

@ -1,17 +1,20 @@
pub use point::*; //! This crate provides a set of mathematical utilities for game development.
pub use vector::*; //! It includes definitions for points, vectors, matrices, quaternions, bezier curves, easing functions, noise generation, polynomials, and interpolation utilities.
pub use matrix::*;
pub use bezier::*; pub use bezier::*;
pub use easings::*; pub use easings::*;
pub use polynomial::*;
pub use interpolation::*; pub use interpolation::*;
pub use matrix::*;
pub use point::*;
pub use polynomial::*;
pub use vector::*;
pub mod point;
pub mod vector;
pub mod matrix;
pub mod quaternion;
pub mod bezier; pub mod bezier;
pub mod easings; pub mod easings;
pub mod interpolation;
pub mod matrix;
pub mod noise; pub mod noise;
pub mod point;
pub mod polynomial; pub mod polynomial;
pub mod interpolation; pub mod quaternion;
pub mod vector;

View file

@ -9,6 +9,7 @@ trait LinearTransformation {
// # MATRIX 2D # // # MATRIX 2D #
// ################################################## // ##################################################
/// Representation of a 2x2 matrix.
#[repr(C)] #[repr(C)]
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct m2 { pub struct m2 {
@ -19,6 +20,7 @@ pub struct m2 {
} }
impl m2 { impl m2 {
/// The zero matrix.
pub const ZERO: Self = Self { pub const ZERO: Self = Self {
x00: 0.0, x00: 0.0,
x01: 0.0, x01: 0.0,
@ -26,6 +28,7 @@ impl m2 {
x11: 0.0, x11: 0.0,
}; };
/// The identity matrix.
pub const IDENTITY: Self = Self { pub const IDENTITY: Self = Self {
x00: 1.0, x00: 1.0,
x01: 0.0, x01: 0.0,
@ -33,10 +36,12 @@ impl m2 {
x11: 1.0, x11: 1.0,
}; };
/// Creates a new 2x2 matrix with the given elements.
pub fn new(x00: f32, x01: f32, x10: f32, x11: f32) -> Self { pub fn new(x00: f32, x01: f32, x10: f32, x11: f32) -> Self {
Self { x00, x01, x10, x11 } Self { x00, x01, x10, x11 }
} }
/// Creates a new 2x2 matrix with the given vectors as its columns.
pub fn from_cols(col1: v2, col2: v2) -> Self { pub fn from_cols(col1: v2, col2: v2) -> Self {
Self { Self {
x00: col1.x(), x00: col1.x(),
@ -46,6 +51,7 @@ impl m2 {
} }
} }
/// Creates a new 2x2 matrix with the given vectors as its rows.
pub fn from_rows(row1: v2, row2: v2) -> Self { pub fn from_rows(row1: v2, row2: v2) -> Self {
Self { Self {
x00: row1.x(), x00: row1.x(),
@ -55,6 +61,7 @@ impl m2 {
} }
} }
/// Gets the element at the specified row and column.
pub fn get(&self, row: usize, col: usize) -> Option<f32> { pub fn get(&self, row: usize, col: usize) -> Option<f32> {
match (row, col) { match (row, col) {
(0, 0) => Some(self.x00), (0, 0) => Some(self.x00),
@ -65,6 +72,7 @@ impl m2 {
} }
} }
/// Sets the element at the specified row and column.
pub fn set(&mut self, row: usize, col: usize, value: f32) { pub fn set(&mut self, row: usize, col: usize, value: f32) {
match (row, col) { match (row, col) {
(0, 0) => self.x00 = value, (0, 0) => self.x00 = value,
@ -75,6 +83,7 @@ impl m2 {
} }
} }
/// Gets the entire column at the specified index.
pub fn col(&self, index: usize) -> Option<v2> { pub fn col(&self, index: usize) -> Option<v2> {
match index { match index {
0 => Some(v2::new(self.x00, self.x01)), 0 => Some(v2::new(self.x00, self.x01)),
@ -83,6 +92,7 @@ impl m2 {
} }
} }
/// Gets the entire row at the specified index.
pub fn row(&self, index: usize) -> Option<v2> { pub fn row(&self, index: usize) -> Option<v2> {
match index { match index {
0 => Some(v2::new(self.x00, self.x10)), 0 => Some(v2::new(self.x00, self.x10)),
@ -91,6 +101,7 @@ impl m2 {
} }
} }
/// Returns the transpose of the matrix.
pub fn transpose(&self) -> Self { pub fn transpose(&self) -> Self {
Self { Self {
x00: self.x00, x00: self.x00,
@ -100,6 +111,7 @@ impl m2 {
} }
} }
/// Returns a matrix with the same elements as the original matrix but in homogeneous form.
pub fn to_homogeneous(&self) -> m3 { pub fn to_homogeneous(&self) -> m3 {
m3::new( m3::new(
self.x00, self.x01, 0.0, self.x10, self.x11, 0.0, 0.0, 0.0, 1.0, self.x00, self.x01, 0.0, self.x10, self.x11, 0.0, 0.0, 0.0, 1.0,
@ -193,6 +205,7 @@ impl Into<[[f32; 2]; 2]> for m2 {
// # MATRIX 3D # // # MATRIX 3D #
// ################################################## // ##################################################
/// Representation of a 3x3 matrix.
#[repr(C)] #[repr(C)]
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct m3 { pub struct m3 {
@ -208,6 +221,7 @@ pub struct m3 {
} }
impl m3 { impl m3 {
/// The zero matrix.
pub const ZERO: Self = Self { pub const ZERO: Self = Self {
x00: 0.0, x00: 0.0,
x01: 0.0, x01: 0.0,
@ -220,6 +234,7 @@ impl m3 {
x22: 0.0, x22: 0.0,
}; };
/// The identity matrix.
pub const IDENTITY: Self = Self { pub const IDENTITY: Self = Self {
x00: 1.0, x00: 1.0,
x01: 0.0, x01: 0.0,
@ -232,6 +247,7 @@ impl m3 {
x22: 1.0, x22: 1.0,
}; };
/// Creates a new 3x3 matrix with the given elements.
pub fn new( pub fn new(
x00: f32, x00: f32,
x01: f32, x01: f32,
@ -256,6 +272,7 @@ impl m3 {
} }
} }
/// Creates a new 3x3 matrix from the given columns.
pub fn from_cols(col1: v3, col2: v3, col3: v3) -> Self { pub fn from_cols(col1: v3, col2: v3, col3: v3) -> Self {
Self { Self {
x00: col1.x(), x00: col1.x(),
@ -270,6 +287,7 @@ impl m3 {
} }
} }
/// Creates a new 3x3 matrix from the given rows.
pub fn from_rows(row1: v3, row2: v3, row3: v3) -> Self { pub fn from_rows(row1: v3, row2: v3, row3: v3) -> Self {
Self { Self {
x00: row1.x(), x00: row1.x(),
@ -284,6 +302,7 @@ impl m3 {
} }
} }
/// Gets the element at the given row and column.
pub fn get(&self, row: usize, col: usize) -> Option<f32> { pub fn get(&self, row: usize, col: usize) -> Option<f32> {
match (row, col) { match (row, col) {
(0, 0) => Some(self.x00), (0, 0) => Some(self.x00),
@ -299,6 +318,7 @@ impl m3 {
} }
} }
/// Sets the element at the given row and column.
pub fn set(&mut self, row: usize, col: usize, value: f32) { pub fn set(&mut self, row: usize, col: usize, value: f32) {
match (row, col) { match (row, col) {
(0, 0) => self.x00 = value, (0, 0) => self.x00 = value,
@ -314,6 +334,7 @@ impl m3 {
} }
} }
/// Gets the entire column at the given index.
pub fn col(&self, index: usize) -> Option<v3> { pub fn col(&self, index: usize) -> Option<v3> {
match index { match index {
0 => Some(v3::new(self.x00, self.x01, self.x02)), 0 => Some(v3::new(self.x00, self.x01, self.x02)),
@ -323,6 +344,7 @@ impl m3 {
} }
} }
/// Gets the entire row at the given index.
pub fn row(&self, index: usize) -> Option<v3> { pub fn row(&self, index: usize) -> Option<v3> {
match index { match index {
0 => Some(v3::new(self.x00, self.x10, self.x20)), 0 => Some(v3::new(self.x00, self.x10, self.x20)),
@ -332,6 +354,7 @@ impl m3 {
} }
} }
/// Returns the transpose of the matrix.
pub fn transpose(&self) -> Self { pub fn transpose(&self) -> Self {
Self { Self {
x00: self.x00, x00: self.x00,
@ -346,6 +369,7 @@ impl m3 {
} }
} }
/// Returns a matrix with the same elements as the original matrix but in homogeneous form.
pub fn to_homogeneous(&self) -> m4 { pub fn to_homogeneous(&self) -> m4 {
m4::new( m4::new(
self.x00, self.x01, self.x02, 0.0, self.x10, self.x11, self.x12, 0.0, self.x20, self.x00, self.x01, self.x02, 0.0, self.x10, self.x11, self.x12, 0.0, self.x20,
@ -470,6 +494,7 @@ impl Into<[[f32; 3]; 3]> for m3 {
// # MATRIX 4D # // # MATRIX 4D #
// ################################################## // ##################################################
/// Representation of a 4x4 matrix.
#[repr(C)] #[repr(C)]
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct m4 { pub struct m4 {
@ -492,6 +517,7 @@ pub struct m4 {
} }
impl m4 { impl m4 {
/// The zero matrix.
pub const ZERO: Self = Self { pub const ZERO: Self = Self {
x00: 0.0, x00: 0.0,
x01: 0.0, x01: 0.0,
@ -511,6 +537,7 @@ impl m4 {
x33: 0.0, x33: 0.0,
}; };
/// The identity matrix.
pub const IDENTITY: Self = Self { pub const IDENTITY: Self = Self {
x00: 1.0, x00: 1.0,
x01: 0.0, x01: 0.0,
@ -530,6 +557,7 @@ impl m4 {
x33: 1.0, x33: 1.0,
}; };
/// The OpenGL conversion matrix.
pub const OPENGL_CONV: Self = Self { pub const OPENGL_CONV: Self = Self {
x00: 1.0, x00: 1.0,
x01: 0.0, x01: 0.0,
@ -549,6 +577,7 @@ impl m4 {
x33: 1.0, x33: 1.0,
}; };
/// Creates a new matrix with the given elements.
pub fn new( pub fn new(
x00: f32, x00: f32,
x01: f32, x01: f32,
@ -587,6 +616,7 @@ impl m4 {
} }
} }
/// Creates a new matrix from the given columns.
pub fn from_cols(col1: v4, col2: v4, col3: v4, col4: v4) -> Self { pub fn from_cols(col1: v4, col2: v4, col3: v4, col4: v4) -> Self {
Self { Self {
x00: col1.x(), x00: col1.x(),
@ -608,6 +638,7 @@ impl m4 {
} }
} }
/// Creates a new matrix from the given rows.
pub fn from_rows(row1: v4, row2: v4, row3: v4, row4: v4) -> Self { pub fn from_rows(row1: v4, row2: v4, row3: v4, row4: v4) -> Self {
Self { Self {
x00: row1.x(), x00: row1.x(),
@ -629,6 +660,7 @@ impl m4 {
} }
} }
/// Gets the element at the given row and column.
pub fn get(&self, row: usize, col: usize) -> Option<f32> { pub fn get(&self, row: usize, col: usize) -> Option<f32> {
match (row, col) { match (row, col) {
(0, 0) => Some(self.x00), (0, 0) => Some(self.x00),
@ -651,6 +683,7 @@ impl m4 {
} }
} }
/// Sets the element at the given row and column.
pub fn set(&mut self, row: usize, col: usize, value: f32) { pub fn set(&mut self, row: usize, col: usize, value: f32) {
match (row, col) { match (row, col) {
(0, 0) => self.x00 = value, (0, 0) => self.x00 = value,
@ -673,6 +706,7 @@ impl m4 {
} }
} }
/// Gets the entire column at the given index.
pub fn col(&self, index: usize) -> Option<v4> { pub fn col(&self, index: usize) -> Option<v4> {
match index { match index {
0 => Some(v4::new(self.x00, self.x01, self.x02, self.x03)), 0 => Some(v4::new(self.x00, self.x01, self.x02, self.x03)),
@ -683,6 +717,7 @@ impl m4 {
} }
} }
/// Gets the entire row at the given index.
pub fn row(&self, index: usize) -> Option<v4> { pub fn row(&self, index: usize) -> Option<v4> {
match index { match index {
0 => Some(v4::new(self.x00, self.x10, self.x20, self.x30)), 0 => Some(v4::new(self.x00, self.x10, self.x20, self.x30)),
@ -693,6 +728,7 @@ impl m4 {
} }
} }
/// Returns the transpose of the matrix.
pub fn transpose(&self) -> Self { pub fn transpose(&self) -> Self {
Self { Self {
x00: self.x00, x00: self.x00,
@ -714,6 +750,7 @@ impl m4 {
} }
} }
/// Generates the orthographic projection matrix.
pub fn orthographic_projection( pub fn orthographic_projection(
left: f32, left: f32,
right: f32, right: f32,

View file

@ -32,26 +32,30 @@ pub trait NoiseGenerator {
fn generate_image(&self) -> DynamicImage; fn generate_image(&self) -> DynamicImage;
} }
/// White noise generator.
pub struct WhiteNoise { pub struct WhiteNoise {
size: (usize, usize), size: (usize, usize),
} }
impl WhiteNoise { impl WhiteNoise {
/// Creates a white noise generator ideal for multiple uses. /// Creates a white noise generator with the given parameters.
pub fn new(width: usize, height: usize) -> Self { pub fn new(width: usize, height: usize) -> Self {
Self { Self {
size: (width, height), size: (width, height),
} }
} }
/// Sets the width of the noise image.
pub fn set_width(&mut self, width: usize) { pub fn set_width(&mut self, width: usize) {
self.size.0 = width; self.size.0 = width;
} }
/// Sets the height of the noise image.
pub fn set_height(&mut self, height: usize) { pub fn set_height(&mut self, height: usize) {
self.size.1 = height; self.size.1 = height;
} }
/// Sets the size of the noise image.
pub fn set_size(&mut self, width: usize, height: usize) { pub fn set_size(&mut self, width: usize, height: usize) {
self.size = (width, height); self.size = (width, height);
} }
@ -113,6 +117,7 @@ impl NoiseGenerator for WhiteNoise {
} }
} }
/// Perlin noise generator.
pub struct PerlinNoise { pub struct PerlinNoise {
size: (usize, usize), size: (usize, usize),
frequency: f64, frequency: f64,
@ -120,6 +125,7 @@ pub struct PerlinNoise {
} }
impl PerlinNoise { impl PerlinNoise {
/// Create a new Perlin noise generator with the given parameters.
pub fn new(width: usize, height: usize, frequency: f64, seed: u32) -> Self { pub fn new(width: usize, height: usize, frequency: f64, seed: u32) -> Self {
Self { Self {
size: (width, height), size: (width, height),
@ -128,22 +134,27 @@ impl PerlinNoise {
} }
} }
/// Set the width of the noise image.
pub fn set_width(&mut self, width: usize) { pub fn set_width(&mut self, width: usize) {
self.size.0 = width; self.size.0 = width;
} }
/// Set the height of the noise image.
pub fn set_height(&mut self, height: usize) { pub fn set_height(&mut self, height: usize) {
self.size.1 = height; self.size.1 = height;
} }
/// Set the size of the noise image.
pub fn set_size(&mut self, width: usize, height: usize) { pub fn set_size(&mut self, width: usize, height: usize) {
self.size = (width, height); self.size = (width, height);
} }
/// Set the frequency of the noise.
pub fn set_frequency(&mut self, frequency: f64) { pub fn set_frequency(&mut self, frequency: f64) {
self.frequency = frequency; self.frequency = frequency;
} }
/// Set the seed for the random number generator.
pub fn set_seed(&mut self, seed: u32) { pub fn set_seed(&mut self, seed: u32) {
self.seed = seed; self.seed = seed;
} }
@ -169,7 +180,7 @@ impl PerlinNoise {
let mut noise = vec![0.0; self.size.0 * self.size.1]; let mut noise = vec![0.0; self.size.0 * self.size.1];
let mut amplitude = 1.0; let mut amplitude = 1.0;
let mut frequency = self.frequency; let mut frequency = self.frequency;
let mut max_value = 0.0; // Used for normalization let mut max_value = 0.0;
for _ in 0..octaves { for _ in 0..octaves {
for y in 0..self.size.1 { for y in 0..self.size.1 {
@ -181,11 +192,10 @@ impl PerlinNoise {
} }
} }
max_value += amplitude; max_value += amplitude;
amplitude *= persistence; // Reduce amplitude for next octave amplitude *= persistence;
frequency *= 2.0; // Double frequency for next octave frequency *= 2.0;
} }
// Normalize the noise to the range [0, 1]
noise noise
.iter_mut() .iter_mut()
.for_each(|value| *value /= max_value as f32); .for_each(|value| *value /= max_value as f32);
@ -250,6 +260,7 @@ impl PerlinNoise {
} }
} }
/// Value noise generator.
pub struct ValueNoise { pub struct ValueNoise {
size: (usize, usize), size: (usize, usize),
frequency: f64, frequency: f64,
@ -257,6 +268,7 @@ pub struct ValueNoise {
} }
impl ValueNoise { impl ValueNoise {
/// Create a new Perlin noise generator with the given parameters.
pub fn new(width: usize, height: usize, frequency: f64, seed: u32) -> Self { pub fn new(width: usize, height: usize, frequency: f64, seed: u32) -> Self {
Self { Self {
size: (width, height), size: (width, height),
@ -290,12 +302,12 @@ impl ValueNoise {
) )
} }
/// Generates value noise as a `Vec<f32>`. Size of the vector is `width * height`.
pub fn generate(&self) -> Vec<f32> { pub fn generate(&self) -> Vec<f32> {
let mut noise = Vec::with_capacity(self.size.0 * self.size.1); let mut noise = Vec::with_capacity(self.size.0 * self.size.1);
let mut max_amplitude = 0.0; let mut max_amplitude = 0.0;
let mut amplitude = 0.5; let mut amplitude = 0.5;
// Calculate max amplitude for normalization
for _ in 0..4 { for _ in 0..4 {
max_amplitude += amplitude; max_amplitude += amplitude;
amplitude *= 0.5; amplitude *= 0.5;
@ -311,17 +323,9 @@ impl ValueNoise {
let mut f = 0.0; let mut f = 0.0;
let mut amplitude = 0.5; let mut amplitude = 0.5;
/*for _ in 0..4 { // 4 octaves*/
f += amplitude * self.noise(uv); f += amplitude * self.noise(uv);
// Double frequency for next octave
uv = (uv.0 * 2.0, uv.1 * 2.0); uv = (uv.0 * 2.0, uv.1 * 2.0);
// Reduce amplitude (persistence)
amplitude *= 0.5; amplitude *= 0.5;
/*}*/
// Normalize and convert to [0, 1]
f = ((f / max_amplitude) + 1.0) * 0.5; f = ((f / max_amplitude) + 1.0) * 0.5;
noise.push(f); noise.push(f);
@ -331,12 +335,12 @@ impl ValueNoise {
noise noise
} }
/// Generates value noise with multiple octaves as a `Vec<f32>`.
pub fn generate_with_octaves(&self, octaves: u32, persistence: f64) -> Vec<f32> { pub fn generate_with_octaves(&self, octaves: u32, persistence: f64) -> Vec<f32> {
let mut noise = Vec::with_capacity(self.size.0 * self.size.1); let mut noise = Vec::with_capacity(self.size.0 * self.size.1);
let mut max_amplitude = 0.0; let mut max_amplitude = 0.0;
let mut amplitude = 1.0; let mut amplitude = 1.0;
// Calculate max amplitude for normalization
for _ in 0..octaves { for _ in 0..octaves {
max_amplitude += amplitude; max_amplitude += amplitude;
amplitude *= persistence; amplitude *= persistence;
@ -344,7 +348,6 @@ impl ValueNoise {
for y in 0..self.size.1 { for y in 0..self.size.1 {
for x in 0..self.size.0 { for x in 0..self.size.0 {
// Convert to UV space and scale by frequency
let mut uv = ( let mut uv = (
x as f32 / self.size.0 as f32 * self.frequency as f32, x as f32 / self.size.0 as f32 * self.frequency as f32,
y as f32 / self.size.1 as f32 * self.frequency as f32, y as f32 / self.size.1 as f32 * self.frequency as f32,
@ -355,15 +358,10 @@ impl ValueNoise {
for _ in 0..octaves { for _ in 0..octaves {
f += amplitude * self.noise(uv); f += amplitude * self.noise(uv);
// Double frequency for next octave
uv = (uv.0 * 2.0, uv.1 * 2.0); uv = (uv.0 * 2.0, uv.1 * 2.0);
// Reduce amplitude (persistence)
amplitude *= persistence as f32; amplitude *= persistence as f32;
} }
// Normalize and convert to [0, 1]
f = ((f / max_amplitude as f32) + 1.0) * 0.5; f = ((f / max_amplitude as f32) + 1.0) * 0.5;
noise.push(f); noise.push(f);

View file

@ -1,5 +1,3 @@
use rand::seq::index::IndexVecIntoIter;
use crate::vector::{v2, v3}; use crate::vector::{v2, v3};
use crate::InnerSpace; use crate::InnerSpace;
@ -8,6 +6,7 @@ pub trait Point {
fn to_vec(&self) -> impl InnerSpace; fn to_vec(&self) -> impl InnerSpace;
} }
/// Representation of a 2D point.
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct p2 { pub struct p2 {
x: f32, x: f32,
@ -15,23 +14,28 @@ pub struct p2 {
} }
impl p2 { impl p2 {
/// Creates a new 2D point with the given elements.
pub fn new(x: f32, y: f32) -> Self { pub fn new(x: f32, y: f32) -> Self {
p2 { x, y } p2 { x, y }
} }
/// Creates a new 2D point from a 2D vector.
pub fn from_vec(v: v2) -> Self { pub fn from_vec(v: v2) -> Self {
Self { x: v.x(), y: v.y() } Self { x: v.x(), y: v.y() }
} }
/// Returns the x-component of the point.
pub fn x(&self) -> f32 { pub fn x(&self) -> f32 {
self.x self.x
} }
/// Returns the y-component of the point.
pub fn y(&self) -> f32 { pub fn y(&self) -> f32 {
self.y self.y
} }
} }
/// Representation of a 3D point.
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct p3 { pub struct p3 {
x: f32, x: f32,
@ -40,10 +44,12 @@ pub struct p3 {
} }
impl p3 { impl p3 {
/// Creates a new 3D point with the given elements.
pub fn new(x: f32, y: f32, z: f32) -> Self { pub fn new(x: f32, y: f32, z: f32) -> Self {
p3 { x, y, z } p3 { x, y, z }
} }
/// Creates a new 3D point from a 3D vector.
pub fn from_vec(v: v3) -> Self { pub fn from_vec(v: v3) -> Self {
Self { Self {
x: v.x(), x: v.x(),
@ -52,14 +58,17 @@ impl p3 {
} }
} }
/// Returns the x-component of the point.
pub fn x(&self) -> f32 { pub fn x(&self) -> f32 {
self.x self.x
} }
/// Returns the y-component of the point.
pub fn y(&self) -> f32 { pub fn y(&self) -> f32 {
self.y self.y
} }
/// Returns the z-component of the point.
pub fn z(&self) -> f32 { pub fn z(&self) -> f32 {
self.z self.z
} }

View file

@ -1,129 +1,152 @@
use std::ops::*; use std::ops::*;
/// Representation of a polynomial of degree `n`.
pub struct Polynomial { pub struct Polynomial {
coefficients: Vec<f32>, coefficients: Vec<f32>,
degree: usize degree: usize,
} }
impl Polynomial { impl Polynomial {
pub fn new(coefficients: Vec<f32>) -> Self { /// Creates a new polynomial from a list of coefficients.
let degree = coefficients.len() - 1; pub fn new(coefficients: Vec<f32>) -> Self {
Self { let degree = coefficients.len() - 1;
coefficients, Self {
degree coefficients,
} degree,
} }
}
pub fn evaluate(&self, x: f32) -> f32 { /// Evaluates the polynomial at a given point.
let mut result = 0.0; pub fn evaluate(&self, x: f32) -> f32 {
for c in &self.coefficients { let mut result = 0.0;
result = result * x + c; for c in &self.coefficients {
} result = result * x + c;
result }
} result
}
pub fn differentiate(&self) -> Self { /// Differentiates the polynomial.
let mut new_coefficients = Vec::new(); pub fn differentiate(&self) -> Self {
for (i, &c) in self.coefficients.iter().enumerate() { let mut new_coefficients = Vec::new();
if i != 0 { for (i, &c) in self.coefficients.iter().enumerate() {
new_coefficients.push(c * i as f32); if i != 0 {
} new_coefficients.push(c * i as f32);
} }
Self::new(new_coefficients) }
} Self::new(new_coefficients)
}
pub fn integrate(&self) -> Self { /// Integrates the polynomial.
let mut new_coefficients = Vec::new(); pub fn integrate(&self) -> Self {
new_coefficients.push(0.0); let mut new_coefficients = Vec::new();
for (i, &c) in self.coefficients.iter().enumerate() { new_coefficients.push(0.0);
new_coefficients.push(c / (i + 1) as f32); for (i, &c) in self.coefficients.iter().enumerate() {
} new_coefficients.push(c / (i + 1) as f32);
Self::new(new_coefficients) }
} Self::new(new_coefficients)
}
} }
impl Add for Polynomial { impl Add for Polynomial {
type Output = Self; type Output = Self;
fn add(self, other: Self) -> Self { fn add(self, other: Self) -> Self {
let mut new_coefficients = Vec::new(); let mut new_coefficients = Vec::new();
let mut i = 0; let mut i = 0;
while i < self.coefficients.len() || i < other.coefficients.len() { while i < self.coefficients.len() || i < other.coefficients.len() {
let a = if i < self.coefficients.len() { self.coefficients[i] } else { 0.0 }; let a = if i < self.coefficients.len() {
let b = if i < other.coefficients.len() { other.coefficients[i] } else { 0.0 }; self.coefficients[i]
new_coefficients.push(a + b); } else {
i += 1; 0.0
} };
Self::new(new_coefficients) let b = if i < other.coefficients.len() {
} other.coefficients[i]
} else {
0.0
};
new_coefficients.push(a + b);
i += 1;
}
Self::new(new_coefficients)
}
} }
impl Sub for Polynomial { impl Sub for Polynomial {
type Output = Self; type Output = Self;
fn sub(self, other: Self) -> Self { fn sub(self, other: Self) -> Self {
let mut new_coefficients = Vec::new(); let mut new_coefficients = Vec::new();
let mut i = 0; let mut i = 0;
while i < self.coefficients.len() || i < other.coefficients.len() { while i < self.coefficients.len() || i < other.coefficients.len() {
let a = if i < self.coefficients.len() { self.coefficients[i] } else { 0.0 }; let a = if i < self.coefficients.len() {
let b = if i < other.coefficients.len() { other.coefficients[i] } else { 0.0 }; self.coefficients[i]
new_coefficients.push(a - b); } else {
i += 1; 0.0
} };
Self::new(new_coefficients) let b = if i < other.coefficients.len() {
} other.coefficients[i]
} else {
0.0
};
new_coefficients.push(a - b);
i += 1;
}
Self::new(new_coefficients)
}
} }
impl Mul for Polynomial { impl Mul for Polynomial {
type Output = Self; type Output = Self;
fn mul(self, other: Self) -> Self { fn mul(self, other: Self) -> Self {
let mut new_coefficients = vec![0.0; self.degree + other.degree + 1]; let mut new_coefficients = vec![0.0; self.degree + other.degree + 1];
for (i, &a) in self.coefficients.iter().enumerate() { for (i, &a) in self.coefficients.iter().enumerate() {
for (j, &b) in other.coefficients.iter().enumerate() { for (j, &b) in other.coefficients.iter().enumerate() {
new_coefficients[i + j] += a * b; new_coefficients[i + j] += a * b;
} }
} }
Self::new(new_coefficients) Self::new(new_coefficients)
} }
} }
impl Div for Polynomial { impl Div for Polynomial {
type Output = Self; type Output = Self;
fn div(self, other: Self) -> Self { fn div(self, other: Self) -> Self {
let mut new_coefficients = vec![0.0; self.degree - other.degree + 1]; let mut new_coefficients = vec![0.0; self.degree - other.degree + 1];
let mut dividend = self.coefficients.clone(); let mut dividend = self.coefficients.clone();
let divisor = other.coefficients.clone(); let divisor = other.coefficients.clone();
while dividend.len() >= divisor.len() { while dividend.len() >= divisor.len() {
let mut quotient = vec![0.0; dividend.len() - divisor.len() + 1]; let mut quotient = vec![0.0; dividend.len() - divisor.len() + 1];
let mut i = dividend.len() - divisor.len(); let mut i = dividend.len() - divisor.len();
quotient[i] = dividend.last().unwrap() / divisor.last().unwrap(); quotient[i] = dividend.last().unwrap() / divisor.last().unwrap();
for (j, &d) in divisor.iter().enumerate() { for (j, &d) in divisor.iter().enumerate() {
dividend[i + j] -= quotient[i] * d; dividend[i + j] -= quotient[i] * d;
} }
new_coefficients[i] = quotient[i]; new_coefficients[i] = quotient[i];
dividend.pop(); dividend.pop();
} }
Self::new(new_coefficients) Self::new(new_coefficients)
} }
} }
impl std::fmt::Display for Polynomial { impl std::fmt::Display for Polynomial {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let terms: Vec<String> = self.coefficients.iter() let terms: Vec<String> = self
.enumerate() .coefficients
.filter(|(_, &c)| c != 0.0) .iter()
.map(|(i, &c)| { .enumerate()
if i == 0 { .filter(|(_, &c)| c != 0.0)
format!("{}", c) .map(|(i, &c)| {
} else if i == 1 { if i == 0 {
format!("{}x", c) format!("{}", c)
} else { } else if i == 1 {
format!("{}x^{}", c, i) format!("{}x", c)
} } else {
}) format!("{}x^{}", c, i)
.collect(); }
write!(f, "{}", terms.join(" + ")) })
} .collect();
} write!(f, "{}", terms.join(" + "))
}
}

View file

@ -1,149 +1,161 @@
use std::ops::*;
use std::ops::Mul;
use crate::vector::v3; use crate::vector::v3;
use std::ops::Mul;
use std::ops::*;
/// Representation of a quaternion in scalar/vector form /// Representation of a quaternion in scalar/vector form
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct Quat { pub struct Quat {
pub s: f32, pub s: f32,
pub v: v3, pub v: v3,
} }
impl Quat { impl Quat {
pub const fn zero() -> Self { /// The zero quaternion.
Self { const ZERO: Self = Self {
s: 0.0, s: 0.0,
v: v3 { v: v3 {
x: 0.0, x: 0.0,
y: 0.0, y: 0.0,
z: 0.0, z: 0.0,
}, },
} };
}
pub const fn new(s: f32, v: v3) -> Self {
Self { s, v }
}
pub fn conjugate(&self) -> Self { /// Creates a new quaternion from a scalar and a vector.
Self { pub const fn new(s: f32, v: v3) -> Self {
s: self.s, Self { s, v }
v: self.v * (-1.0), }
}
}
pub fn normalize(&self) -> Self { /// Returns the conjugate of the quaternion.
let inverse_squareroot = 1.0/(self.s*self.s + self.v.x*self.v.x + self.v.y*self.v.y + self.v.z*self.v.z).sqrt(); pub fn conjugate(&self) -> Self {
Self::new(self.s*inverse_squareroot, self.v*inverse_squareroot) Self {
} s: self.s,
v: self.v * (-1.0),
}
}
pub fn into_vec(&self) -> v3 { /// Returns the normalized version of the quaternion.
v3 { pub fn normalize(&self) -> Self {
x: self.v.x, let inverse_squareroot = 1.0
y: self.v.y, / (self.s * self.s + self.v.x * self.v.x + self.v.y * self.v.y + self.v.z * self.v.z)
z: self.v.z, .sqrt();
} Self::new(self.s * inverse_squareroot, self.v * inverse_squareroot)
} }
/// Converts the quaternion into a vector.
pub fn into_vec(&self) -> v3 {
v3 {
x: self.v.x,
y: self.v.y,
z: self.v.z,
}
}
} }
impl Add<Quat> for Quat { impl Add<Quat> for Quat {
type Output = Quat; type Output = Quat;
fn add(self, other: Quat) -> Quat { fn add(self, other: Quat) -> Quat {
Quat { Quat {
s: self.s + other.s, s: self.s + other.s,
v: self.v + other.v, v: self.v + other.v,
} }
} }
} }
impl Sub<Quat> for Quat { impl Sub<Quat> for Quat {
type Output = Quat; type Output = Quat;
fn sub(self, other: Quat) -> Quat { fn sub(self, other: Quat) -> Quat {
Quat { Quat {
s: self.s - other.s, s: self.s - other.s,
v: self.v - other.v, v: self.v - other.v,
} }
} }
} }
impl Neg for Quat { impl Neg for Quat {
type Output = Quat; type Output = Quat;
fn neg(self) -> Quat { fn neg(self) -> Quat {
Quat { Quat {
s: -self.s, s: -self.s,
v: -self.v, v: -self.v,
} }
} }
} }
impl Add<f32> for Quat { impl Add<f32> for Quat {
type Output = Quat; type Output = Quat;
fn add(self, scalar: f32) -> Quat { fn add(self, scalar: f32) -> Quat {
Quat { Quat {
s: self.s + scalar, s: self.s + scalar,
v: self.v, v: self.v,
} }
} }
} }
impl Sub<f32> for Quat { impl Sub<f32> for Quat {
type Output = Quat; type Output = Quat;
fn sub(self, scalar: f32) -> Quat { fn sub(self, scalar: f32) -> Quat {
Quat { Quat {
s: self.s - scalar, s: self.s - scalar,
v: self.v, v: self.v,
} }
} }
} }
impl Mul<Quat> for f32 { impl Mul<Quat> for f32 {
type Output = Quat; type Output = Quat;
fn mul(self, quat: Quat) -> Quat { fn mul(self, quat: Quat) -> Quat {
Quat { Quat {
s: self*quat.s, s: self * quat.s,
v: self*quat.v, v: self * quat.v,
} }
} }
} }
impl Mul<Quat> for Quat { impl Mul<Quat> for Quat {
type Output = Quat; type Output = Quat;
fn mul(self, other: Quat) -> Quat { fn mul(self, other: Quat) -> Quat {
Quat { Quat {
s: self.s*other.s - self.v.x*other.v.x - self.v.y*other.v.y - self.v.z*other.v.z, s: self.s * other.s
v: v3 { - self.v.x * other.v.x
x: self.s*other.v.x + self.v.x*other.s + self.v.y*other.v.z - self.v.z*other.v.y, - self.v.y * other.v.y
y: self.s*other.v.y + self.v.y*other.s + self.v.z*other.v.x - self.v.x*other.v.z, - self.v.z * other.v.z,
z: self.s*other.v.z + self.v.z*other.s + self.v.x*other.v.y - self.v.y*other.v.x, v: v3 {
} x: self.s * other.v.x + self.v.x * other.s + self.v.y * other.v.z
} - self.v.z * other.v.y,
} y: self.s * other.v.y + self.v.y * other.s + self.v.z * other.v.x
- self.v.x * other.v.z,
z: self.s * other.v.z + self.v.z * other.s + self.v.x * other.v.y
- self.v.y * other.v.x,
},
}
}
} }
impl Mul<f32> for Quat { impl Mul<f32> for Quat {
type Output = Quat; type Output = Quat;
fn mul(self, scalar: f32) -> Quat { fn mul(self, scalar: f32) -> Quat {
Quat { Quat {
s: self.s*scalar, s: self.s * scalar,
v: self.v*scalar, v: self.v * scalar,
} }
} }
} }
impl Div<f32> for Quat { impl Div<f32> for Quat {
type Output = Quat; type Output = Quat;
fn div(self, scalar: f32) -> Quat { fn div(self, scalar: f32) -> Quat {
Quat { Quat {
s: self.s/scalar, s: self.s / scalar,
v: self.v/scalar, v: self.v / scalar,
} }
} }
} }

View file

@ -29,7 +29,7 @@ pub trait InnerSpace:
// # VECTOR 2D # // # VECTOR 2D #
// ################################################## // ##################################################
/// Representation of a 2D Vector /// Representation of a 2D vector
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Default)] #[derive(Debug, Clone, Copy, PartialEq, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@ -40,30 +40,39 @@ pub struct v2 {
} }
impl v2 { impl v2 {
/// The unit vector along the x-axis.
pub const X: v2 = v2 { x: 1.0, y: 0.0 }; pub const X: v2 = v2 { x: 1.0, y: 0.0 };
/// The unit vector along the y-axis.
pub const Y: v2 = v2 { x: 0.0, y: 1.0 }; pub const Y: v2 = v2 { x: 0.0, y: 1.0 };
/// The zero vector.
pub const ZERO: v2 = v2 { x: 0.0, y: 0.0 }; pub const ZERO: v2 = v2 { x: 0.0, y: 0.0 };
/// Creates a new vector with the given components.
pub const fn new(x: f32, y: f32) -> Self { pub const fn new(x: f32, y: f32) -> Self {
v2 { x, y } v2 { x, y }
} }
/// Creates a new vector from a point.
pub fn from_point(p: p2) -> Self { pub fn from_point(p: p2) -> Self {
Self { x: p.x(), y: p.y() } Self { x: p.x(), y: p.y() }
} }
/// Gets the x-component of the vector.
pub fn x(&self) -> f32 { pub fn x(&self) -> f32 {
self.x self.x
} }
/// Gets the y-component of the vector.
pub fn y(&self) -> f32 { pub fn y(&self) -> f32 {
self.y self.y
} }
/// Sets the x-component of the vector.
pub fn set_x(&mut self, new_x: f32) { pub fn set_x(&mut self, new_x: f32) {
self.x = new_x; self.x = new_x;
} }
/// Sets the y-component of the vector.
pub fn set_y(&mut self, new_y: f32) { pub fn set_y(&mut self, new_y: f32) {
self.y = new_y; self.y = new_y;
} }
@ -164,7 +173,7 @@ impl Into<v2> for [f32; 2] {
} }
} }
/// Representation of a 2D integer Vector /// Representation of a 2D integer vector
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Default)] #[derive(Debug, Clone, Copy, PartialEq, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@ -175,14 +184,19 @@ pub struct v2i {
} }
impl v2i { impl v2i {
/// The unit vector in the x direction.
pub const X: v2i = v2i { x: 1, y: 0 }; pub const X: v2i = v2i { x: 1, y: 0 };
/// The unit vector in the y direction.
pub const Y: v2i = v2i { x: 0, y: 1 }; pub const Y: v2i = v2i { x: 0, y: 1 };
/// The zero vector.
pub const ZERO: v2i = v2i { x: 0, y: 0 }; pub const ZERO: v2i = v2i { x: 0, y: 0 };
/// Creates a new vector with the given components.
pub const fn new(x: i64, y: i64) -> Self { pub const fn new(x: i64, y: i64) -> Self {
v2i { x, y } v2i { x, y }
} }
/// Creates a new vector from a point.
pub fn from_point(p: p2) -> Self { pub fn from_point(p: p2) -> Self {
Self { Self {
x: p.x() as i64, x: p.x() as i64,
@ -190,10 +204,12 @@ impl v2i {
} }
} }
/// Creates a 2D point from the vector.
pub fn as_point(&self) -> p2 { pub fn as_point(&self) -> p2 {
p2::new(self.x as f32, self.y as f32) p2::new(self.x as f32, self.y as f32)
} }
/// Creates a integer 2D vector from a floating point 2D vector.
pub fn from_vec2(v: v2) -> Self { pub fn from_vec2(v: v2) -> Self {
Self { Self {
x: v.x as i64, x: v.x as i64,
@ -201,6 +217,7 @@ impl v2i {
} }
} }
/// Creates a floating point 2D vector from the integer vector.
pub fn as_vec2(&self) -> v2 { pub fn as_vec2(&self) -> v2 {
v2 { v2 {
x: self.x as f32, x: self.x as f32,
@ -208,26 +225,32 @@ impl v2i {
} }
} }
/// Gets the x component of the vector.
pub fn x(&self) -> i64 { pub fn x(&self) -> i64 {
self.x self.x
} }
/// Gets the y component of the vector.
pub fn y(&self) -> i64 { pub fn y(&self) -> i64 {
self.y self.y
} }
/// Sets the x component of the vector.
pub fn set_x(&mut self, new_x: i64) { pub fn set_x(&mut self, new_x: i64) {
self.x = new_x; self.x = new_x;
} }
/// Sets the y component of the vector.
pub fn set_y(&mut self, new_y: i64) { pub fn set_y(&mut self, new_y: i64) {
self.y = new_y; self.y = new_y;
} }
/// Gets the length of the vector.
pub fn length(&self) -> i64 { pub fn length(&self) -> i64 {
((self.x * self.x + self.y * self.y) as f32).sqrt() as i64 ((self.x * self.x + self.y * self.y) as f32).sqrt() as i64
} }
/// Calculates the normalized version of the vector.
pub fn normalize(&self) -> Self { pub fn normalize(&self) -> Self {
let factor = 1.0 / self.length() as f32; let factor = 1.0 / self.length() as f32;
v2i { v2i {
@ -236,6 +259,8 @@ impl v2i {
} }
} }
/// Swizzles the vector components.
/// (x,y) -> (x,x)
pub fn xx(&self) -> Self { pub fn xx(&self) -> Self {
Self { Self {
x: self.x, x: self.x,
@ -243,6 +268,8 @@ impl v2i {
} }
} }
/// Swizzles the vector components.
/// (x,y) -> (x,y)
pub fn xy(&self) -> Self { pub fn xy(&self) -> Self {
Self { Self {
x: self.x, x: self.x,
@ -250,6 +277,8 @@ impl v2i {
} }
} }
/// Swizzles the vector components.
/// (x,y) -> (y,x)
pub fn yx(&self) -> Self { pub fn yx(&self) -> Self {
Self { Self {
x: self.y, x: self.y,
@ -257,6 +286,8 @@ impl v2i {
} }
} }
/// Swizzles the vector components.
/// (x,y) -> (y,y)
pub fn yy(&self) -> Self { pub fn yy(&self) -> Self {
Self { Self {
x: self.y, x: self.y,
@ -390,7 +421,7 @@ impl Into<[f32; 2]> for v2i {
// # VECTOR 3D # // # VECTOR 3D #
// ################################################## // ##################################################
/// Representation of a 3D Vector /// Representation of a 3D vector
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Default)] #[derive(Debug, Clone, Copy, PartialEq, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@ -402,31 +433,37 @@ pub struct v3 {
} }
impl v3 { impl v3 {
/// The unit vector along the x-axis.
pub const X: v3 = v3 { pub const X: v3 = v3 {
x: 1.0, x: 1.0,
y: 0.0, y: 0.0,
z: 0.0, z: 0.0,
}; };
/// The unit vector along the y-axis.
pub const Y: v3 = v3 { pub const Y: v3 = v3 {
x: 0.0, x: 0.0,
y: 1.0, y: 1.0,
z: 0.0, z: 0.0,
}; };
/// The unit vector along the z-axis.
pub const Z: v3 = v3 { pub const Z: v3 = v3 {
x: 0.0, x: 0.0,
y: 0.0, y: 0.0,
z: 1.0, z: 1.0,
}; };
/// The zero vector.
pub const ZERO: v3 = v3 { pub const ZERO: v3 = v3 {
x: 0.0, x: 0.0,
y: 0.0, y: 0.0,
z: 0.0, z: 0.0,
}; };
/// Creates a new vector with the given components.
pub const fn new(x: f32, y: f32, z: f32) -> Self { pub const fn new(x: f32, y: f32, z: f32) -> Self {
v3 { x, y, z } v3 { x, y, z }
} }
/// Creates a new vector from a point.
pub fn from_point(p: p3) -> Self { pub fn from_point(p: p3) -> Self {
Self { Self {
x: p.x(), x: p.x(),
@ -435,30 +472,37 @@ impl v3 {
} }
} }
/// Creates a new point from a vector.
pub fn as_point(&self) -> p3 { pub fn as_point(&self) -> p3 {
p3::new(self.x as f32, self.y as f32, self.z as f32) p3::new(self.x as f32, self.y as f32, self.z as f32)
} }
/// Gets the x-component of the vector.
pub fn x(&self) -> f32 { pub fn x(&self) -> f32 {
self.x self.x
} }
/// Gets the y-component of the vector.
pub fn y(&self) -> f32 { pub fn y(&self) -> f32 {
self.y self.y
} }
/// Gets the z-component of the vector.
pub fn z(&self) -> f32 { pub fn z(&self) -> f32 {
self.z self.z
} }
/// Sets the x-component of the vector.
pub fn set_x(&mut self, new_x: f32) { pub fn set_x(&mut self, new_x: f32) {
self.x = new_x; self.x = new_x;
} }
/// Sets the y-component of the vector.
pub fn set_y(&mut self, new_y: f32) { pub fn set_y(&mut self, new_y: f32) {
self.y = new_y; self.y = new_y;
} }
/// Sets the z-component of the vector.
pub fn set_z(&mut self, new_z: f32) { pub fn set_z(&mut self, new_z: f32) {
self.z = new_z; self.z = new_z;
} }
@ -574,6 +618,7 @@ impl Into<v3> for [f32; 3] {
} }
} }
/// Representation of a 3D integer vector
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Default)] #[derive(Debug, Clone, Copy, PartialEq, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@ -585,15 +630,21 @@ pub struct v3i {
} }
impl v3i { impl v3i {
/// The unit vector in the x-direction.
pub const X: v3i = v3i { x: 1, y: 0, z: 0 }; pub const X: v3i = v3i { x: 1, y: 0, z: 0 };
/// The unit vector in the y-direction.
pub const Y: v3i = v3i { x: 0, y: 1, z: 0 }; pub const Y: v3i = v3i { x: 0, y: 1, z: 0 };
/// The unit vector in the z-direction.
pub const Z: v3i = v3i { x: 0, y: 0, z: 1 }; pub const Z: v3i = v3i { x: 0, y: 0, z: 1 };
/// The zero vector.
pub const ZERO: v3i = v3i { x: 0, y: 0, z: 0 }; pub const ZERO: v3i = v3i { x: 0, y: 0, z: 0 };
/// Creates a new vector with the given components.
pub const fn new(x: i64, y: i64, z: i64) -> Self { pub const fn new(x: i64, y: i64, z: i64) -> Self {
v3i { x, y, z } v3i { x, y, z }
} }
/// Creates a new vector from a point.
pub fn from_point(p: p3) -> Self { pub fn from_point(p: p3) -> Self {
Self { Self {
x: p.x() as i64, x: p.x() as i64,
@ -602,34 +653,42 @@ impl v3i {
} }
} }
/// Gets the x-component of the vector.
pub fn x(&self) -> i64 { pub fn x(&self) -> i64 {
self.x self.x
} }
/// Gets the y-component of the vector.
pub fn y(&self) -> i64 { pub fn y(&self) -> i64 {
self.y self.y
} }
/// Gets the z-component of the vector.
pub fn z(&self) -> i64 { pub fn z(&self) -> i64 {
self.z self.z
} }
/// Sets the x-component of the vector.
pub fn set_x(&mut self, new_x: i64) { pub fn set_x(&mut self, new_x: i64) {
self.x = new_x; self.x = new_x;
} }
/// Sets the y-component of the vector.
pub fn set_y(&mut self, new_y: i64) { pub fn set_y(&mut self, new_y: i64) {
self.y = new_y; self.y = new_y;
} }
/// Sets the z-component of the vector.
pub fn set_z(&mut self, new_z: i64) { pub fn set_z(&mut self, new_z: i64) {
self.z = new_z; self.z = new_z;
} }
/// Calculates the length of the vector.
pub fn length(&self) -> i64 { pub fn length(&self) -> i64 {
((self.x * self.x + self.y * self.y + self.z * self.z) as f32).sqrt() as i64 ((self.x * self.x + self.y * self.y + self.z * self.z) as f32).sqrt() as i64
} }
/// Normalizes the vector.
pub fn normalize(&self) -> Self { pub fn normalize(&self) -> Self {
let factor = 1 / self.length(); let factor = 1 / self.length();
v3i { v3i {
@ -763,7 +822,7 @@ impl From<v3> for v3i {
// # VECTOR 4D # // # VECTOR 4D #
// ################################################## // ##################################################
/// Representation of a 4D Vector /// Representation of a 4D vector
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Default)] #[derive(Debug, Clone, Copy, PartialEq, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@ -776,24 +835,31 @@ pub struct v4 {
} }
impl v4 { impl v4 {
/// The unit vector along the x-axis.
pub const X: v4 = v4 { pub const X: v4 = v4 {
x: 1.0, x: 1.0,
y: 0.0, y: 0.0,
z: 0.0, z: 0.0,
w: 0.0, w: 0.0,
}; };
/// The unit vector along the y-axis.
pub const Y: v4 = v4 { pub const Y: v4 = v4 {
x: 0.0, x: 0.0,
y: 1.0, y: 1.0,
z: 0.0, z: 0.0,
w: 0.0, w: 0.0,
}; };
/// The unit vector along the z-axis.
pub const Z: v4 = v4 { pub const Z: v4 = v4 {
x: 0.0, x: 0.0,
y: 0.0, y: 0.0,
z: 1.0, z: 1.0,
w: 0.0, w: 0.0,
}; };
/// The unit vector along the w-axis.
pub const W: v4 = v4 { pub const W: v4 = v4 {
x: 0.0, x: 0.0,
y: 0.0, y: 0.0,
@ -801,6 +867,7 @@ impl v4 {
w: 1.0, w: 1.0,
}; };
/// The zero vector.
pub const ZERO: v4 = v4 { pub const ZERO: v4 = v4 {
x: 0.0, x: 0.0,
y: 0.0, y: 0.0,
@ -808,38 +875,47 @@ impl v4 {
w: 0.0, w: 0.0,
}; };
/// Creates a new vector with the given components.
pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self { pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
v4 { x, y, z, w } v4 { x, y, z, w }
} }
/// Gets the x-component of the vector.
pub fn x(&self) -> f32 { pub fn x(&self) -> f32 {
self.x self.x
} }
/// Gets the y-component of the vector.
pub fn y(&self) -> f32 { pub fn y(&self) -> f32 {
self.y self.y
} }
/// Gets the z-component of the vector.
pub fn z(&self) -> f32 { pub fn z(&self) -> f32 {
self.z self.z
} }
/// Gets the w-component of the vector.
pub fn w(&self) -> f32 { pub fn w(&self) -> f32 {
self.w self.w
} }
/// Sets the x-component of the vector.
pub fn set_x(&mut self, new_x: f32) { pub fn set_x(&mut self, new_x: f32) {
self.x = new_x; self.x = new_x;
} }
/// Sets the y-component of the vector.
pub fn set_y(&mut self, new_y: f32) { pub fn set_y(&mut self, new_y: f32) {
self.y = new_y; self.y = new_y;
} }
/// Sets the z-component of the vector.
pub fn set_z(&mut self, new_z: f32) { pub fn set_z(&mut self, new_z: f32) {
self.z = new_z; self.z = new_z;
} }
/// Sets the w-component of the vector.
pub fn set_w(&mut self, new_w: f32) { pub fn set_w(&mut self, new_w: f32) {
self.w = new_w; self.w = new_w;
} }