mirror of
https://github.com/lisk77/comet.git
synced 2025-10-23 21:38:50 +00:00
docs(math): added more documentation for bezier, matrix, noise, point, polynomial, quaternion and vector
This commit is contained in:
parent
30c6327997
commit
5f97d3a881
8 changed files with 399 additions and 239 deletions
|
@ -1,11 +1,13 @@
|
|||
use crate::{InnerSpace, Point};
|
||||
|
||||
/// Representation of a Bezier curve of degree n in any (2-4) dimensions.
|
||||
pub struct Bezier<V: InnerSpace> {
|
||||
points: Vec<V>,
|
||||
degree: usize,
|
||||
}
|
||||
|
||||
impl<V: InnerSpace + Clone> Bezier<V> {
|
||||
/// Creates a new Bezier curve with the given control points.
|
||||
pub fn new(points: Vec<V>) -> Self {
|
||||
let degree = points.len() - 1;
|
||||
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
pub use point::*;
|
||||
pub use vector::*;
|
||||
pub use matrix::*;
|
||||
//! This crate provides a set of mathematical utilities for game development.
|
||||
//! It includes definitions for points, vectors, matrices, quaternions, bezier curves, easing functions, noise generation, polynomials, and interpolation utilities.
|
||||
|
||||
pub use bezier::*;
|
||||
pub use easings::*;
|
||||
pub use polynomial::*;
|
||||
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 easings;
|
||||
pub mod noise;
|
||||
pub mod polynomial;
|
||||
pub mod interpolation;
|
||||
pub mod matrix;
|
||||
pub mod noise;
|
||||
pub mod point;
|
||||
pub mod polynomial;
|
||||
pub mod quaternion;
|
||||
pub mod vector;
|
||||
|
|
|
@ -9,6 +9,7 @@ trait LinearTransformation {
|
|||
// # MATRIX 2D #
|
||||
// ##################################################
|
||||
|
||||
/// Representation of a 2x2 matrix.
|
||||
#[repr(C)]
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct m2 {
|
||||
|
@ -19,6 +20,7 @@ pub struct m2 {
|
|||
}
|
||||
|
||||
impl m2 {
|
||||
/// The zero matrix.
|
||||
pub const ZERO: Self = Self {
|
||||
x00: 0.0,
|
||||
x01: 0.0,
|
||||
|
@ -26,6 +28,7 @@ impl m2 {
|
|||
x11: 0.0,
|
||||
};
|
||||
|
||||
/// The identity matrix.
|
||||
pub const IDENTITY: Self = Self {
|
||||
x00: 1.0,
|
||||
x01: 0.0,
|
||||
|
@ -33,10 +36,12 @@ impl m2 {
|
|||
x11: 1.0,
|
||||
};
|
||||
|
||||
/// Creates a new 2x2 matrix with the given elements.
|
||||
pub fn new(x00: f32, x01: f32, x10: f32, x11: f32) -> Self {
|
||||
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 {
|
||||
Self {
|
||||
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 {
|
||||
Self {
|
||||
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> {
|
||||
match (row, col) {
|
||||
(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) {
|
||||
match (row, col) {
|
||||
(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> {
|
||||
match index {
|
||||
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> {
|
||||
match index {
|
||||
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 {
|
||||
Self {
|
||||
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 {
|
||||
m3::new(
|
||||
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 #
|
||||
// ##################################################
|
||||
|
||||
/// Representation of a 3x3 matrix.
|
||||
#[repr(C)]
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct m3 {
|
||||
|
@ -208,6 +221,7 @@ pub struct m3 {
|
|||
}
|
||||
|
||||
impl m3 {
|
||||
/// The zero matrix.
|
||||
pub const ZERO: Self = Self {
|
||||
x00: 0.0,
|
||||
x01: 0.0,
|
||||
|
@ -220,6 +234,7 @@ impl m3 {
|
|||
x22: 0.0,
|
||||
};
|
||||
|
||||
/// The identity matrix.
|
||||
pub const IDENTITY: Self = Self {
|
||||
x00: 1.0,
|
||||
x01: 0.0,
|
||||
|
@ -232,6 +247,7 @@ impl m3 {
|
|||
x22: 1.0,
|
||||
};
|
||||
|
||||
/// Creates a new 3x3 matrix with the given elements.
|
||||
pub fn new(
|
||||
x00: 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 {
|
||||
Self {
|
||||
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 {
|
||||
Self {
|
||||
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> {
|
||||
match (row, col) {
|
||||
(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) {
|
||||
match (row, col) {
|
||||
(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> {
|
||||
match index {
|
||||
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> {
|
||||
match index {
|
||||
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 {
|
||||
Self {
|
||||
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 {
|
||||
m4::new(
|
||||
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 #
|
||||
// ##################################################
|
||||
|
||||
/// Representation of a 4x4 matrix.
|
||||
#[repr(C)]
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct m4 {
|
||||
|
@ -492,6 +517,7 @@ pub struct m4 {
|
|||
}
|
||||
|
||||
impl m4 {
|
||||
/// The zero matrix.
|
||||
pub const ZERO: Self = Self {
|
||||
x00: 0.0,
|
||||
x01: 0.0,
|
||||
|
@ -511,6 +537,7 @@ impl m4 {
|
|||
x33: 0.0,
|
||||
};
|
||||
|
||||
/// The identity matrix.
|
||||
pub const IDENTITY: Self = Self {
|
||||
x00: 1.0,
|
||||
x01: 0.0,
|
||||
|
@ -530,6 +557,7 @@ impl m4 {
|
|||
x33: 1.0,
|
||||
};
|
||||
|
||||
/// The OpenGL conversion matrix.
|
||||
pub const OPENGL_CONV: Self = Self {
|
||||
x00: 1.0,
|
||||
x01: 0.0,
|
||||
|
@ -549,6 +577,7 @@ impl m4 {
|
|||
x33: 1.0,
|
||||
};
|
||||
|
||||
/// Creates a new matrix with the given elements.
|
||||
pub fn new(
|
||||
x00: 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 {
|
||||
Self {
|
||||
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 {
|
||||
Self {
|
||||
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> {
|
||||
match (row, col) {
|
||||
(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) {
|
||||
match (row, col) {
|
||||
(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> {
|
||||
match index {
|
||||
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> {
|
||||
match index {
|
||||
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 {
|
||||
Self {
|
||||
x00: self.x00,
|
||||
|
@ -714,6 +750,7 @@ impl m4 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Generates the orthographic projection matrix.
|
||||
pub fn orthographic_projection(
|
||||
left: f32,
|
||||
right: f32,
|
||||
|
|
|
@ -32,26 +32,30 @@ pub trait NoiseGenerator {
|
|||
fn generate_image(&self) -> DynamicImage;
|
||||
}
|
||||
|
||||
/// White noise generator.
|
||||
pub struct WhiteNoise {
|
||||
size: (usize, usize),
|
||||
}
|
||||
|
||||
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 {
|
||||
Self {
|
||||
size: (width, height),
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the width of the noise image.
|
||||
pub fn set_width(&mut self, width: usize) {
|
||||
self.size.0 = width;
|
||||
}
|
||||
|
||||
/// Sets the height of the noise image.
|
||||
pub fn set_height(&mut self, height: usize) {
|
||||
self.size.1 = height;
|
||||
}
|
||||
|
||||
/// Sets the size of the noise image.
|
||||
pub fn set_size(&mut self, width: usize, height: usize) {
|
||||
self.size = (width, height);
|
||||
}
|
||||
|
@ -113,6 +117,7 @@ impl NoiseGenerator for WhiteNoise {
|
|||
}
|
||||
}
|
||||
|
||||
/// Perlin noise generator.
|
||||
pub struct PerlinNoise {
|
||||
size: (usize, usize),
|
||||
frequency: f64,
|
||||
|
@ -120,6 +125,7 @@ pub struct 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 {
|
||||
Self {
|
||||
size: (width, height),
|
||||
|
@ -128,22 +134,27 @@ impl PerlinNoise {
|
|||
}
|
||||
}
|
||||
|
||||
/// Set the width of the noise image.
|
||||
pub fn set_width(&mut self, width: usize) {
|
||||
self.size.0 = width;
|
||||
}
|
||||
|
||||
/// Set the height of the noise image.
|
||||
pub fn set_height(&mut self, height: usize) {
|
||||
self.size.1 = height;
|
||||
}
|
||||
|
||||
/// Set the size of the noise image.
|
||||
pub fn set_size(&mut self, width: usize, height: usize) {
|
||||
self.size = (width, height);
|
||||
}
|
||||
|
||||
/// Set the frequency of the noise.
|
||||
pub fn set_frequency(&mut self, frequency: f64) {
|
||||
self.frequency = frequency;
|
||||
}
|
||||
|
||||
/// Set the seed for the random number generator.
|
||||
pub fn set_seed(&mut self, seed: u32) {
|
||||
self.seed = seed;
|
||||
}
|
||||
|
@ -169,7 +180,7 @@ impl PerlinNoise {
|
|||
let mut noise = vec![0.0; self.size.0 * self.size.1];
|
||||
let mut amplitude = 1.0;
|
||||
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 y in 0..self.size.1 {
|
||||
|
@ -181,11 +192,10 @@ impl PerlinNoise {
|
|||
}
|
||||
}
|
||||
max_value += amplitude;
|
||||
amplitude *= persistence; // Reduce amplitude for next octave
|
||||
frequency *= 2.0; // Double frequency for next octave
|
||||
amplitude *= persistence;
|
||||
frequency *= 2.0;
|
||||
}
|
||||
|
||||
// Normalize the noise to the range [0, 1]
|
||||
noise
|
||||
.iter_mut()
|
||||
.for_each(|value| *value /= max_value as f32);
|
||||
|
@ -250,6 +260,7 @@ impl PerlinNoise {
|
|||
}
|
||||
}
|
||||
|
||||
/// Value noise generator.
|
||||
pub struct ValueNoise {
|
||||
size: (usize, usize),
|
||||
frequency: f64,
|
||||
|
@ -257,6 +268,7 @@ pub struct 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 {
|
||||
Self {
|
||||
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> {
|
||||
let mut noise = Vec::with_capacity(self.size.0 * self.size.1);
|
||||
let mut max_amplitude = 0.0;
|
||||
let mut amplitude = 0.5;
|
||||
|
||||
// Calculate max amplitude for normalization
|
||||
for _ in 0..4 {
|
||||
max_amplitude += amplitude;
|
||||
amplitude *= 0.5;
|
||||
|
@ -311,17 +323,9 @@ impl ValueNoise {
|
|||
let mut f = 0.0;
|
||||
let mut amplitude = 0.5;
|
||||
|
||||
/*for _ in 0..4 { // 4 octaves*/
|
||||
f += amplitude * self.noise(uv);
|
||||
|
||||
// Double frequency for next octave
|
||||
uv = (uv.0 * 2.0, uv.1 * 2.0);
|
||||
|
||||
// Reduce amplitude (persistence)
|
||||
amplitude *= 0.5;
|
||||
/*}*/
|
||||
|
||||
// Normalize and convert to [0, 1]
|
||||
f = ((f / max_amplitude) + 1.0) * 0.5;
|
||||
|
||||
noise.push(f);
|
||||
|
@ -331,12 +335,12 @@ impl ValueNoise {
|
|||
noise
|
||||
}
|
||||
|
||||
/// Generates value noise with multiple octaves as a `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 max_amplitude = 0.0;
|
||||
let mut amplitude = 1.0;
|
||||
|
||||
// Calculate max amplitude for normalization
|
||||
for _ in 0..octaves {
|
||||
max_amplitude += amplitude;
|
||||
amplitude *= persistence;
|
||||
|
@ -344,7 +348,6 @@ impl ValueNoise {
|
|||
|
||||
for y in 0..self.size.1 {
|
||||
for x in 0..self.size.0 {
|
||||
// Convert to UV space and scale by frequency
|
||||
let mut uv = (
|
||||
x as f32 / self.size.0 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 {
|
||||
f += amplitude * self.noise(uv);
|
||||
|
||||
// Double frequency for next octave
|
||||
uv = (uv.0 * 2.0, uv.1 * 2.0);
|
||||
|
||||
// Reduce amplitude (persistence)
|
||||
amplitude *= persistence as f32;
|
||||
}
|
||||
|
||||
// Normalize and convert to [0, 1]
|
||||
f = ((f / max_amplitude as f32) + 1.0) * 0.5;
|
||||
|
||||
noise.push(f);
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use rand::seq::index::IndexVecIntoIter;
|
||||
|
||||
use crate::vector::{v2, v3};
|
||||
use crate::InnerSpace;
|
||||
|
||||
|
@ -8,6 +6,7 @@ pub trait Point {
|
|||
fn to_vec(&self) -> impl InnerSpace;
|
||||
}
|
||||
|
||||
/// Representation of a 2D point.
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct p2 {
|
||||
x: f32,
|
||||
|
@ -15,23 +14,28 @@ pub struct p2 {
|
|||
}
|
||||
|
||||
impl p2 {
|
||||
/// Creates a new 2D point with the given elements.
|
||||
pub fn new(x: f32, y: f32) -> Self {
|
||||
p2 { x, y }
|
||||
}
|
||||
|
||||
/// Creates a new 2D point from a 2D vector.
|
||||
pub fn from_vec(v: v2) -> Self {
|
||||
Self { x: v.x(), y: v.y() }
|
||||
}
|
||||
|
||||
/// Returns the x-component of the point.
|
||||
pub fn x(&self) -> f32 {
|
||||
self.x
|
||||
}
|
||||
|
||||
/// Returns the y-component of the point.
|
||||
pub fn y(&self) -> f32 {
|
||||
self.y
|
||||
}
|
||||
}
|
||||
|
||||
/// Representation of a 3D point.
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct p3 {
|
||||
x: f32,
|
||||
|
@ -40,10 +44,12 @@ pub struct p3 {
|
|||
}
|
||||
|
||||
impl p3 {
|
||||
/// Creates a new 3D point with the given elements.
|
||||
pub fn new(x: f32, y: f32, z: f32) -> Self {
|
||||
p3 { x, y, z }
|
||||
}
|
||||
|
||||
/// Creates a new 3D point from a 3D vector.
|
||||
pub fn from_vec(v: v3) -> Self {
|
||||
Self {
|
||||
x: v.x(),
|
||||
|
@ -52,14 +58,17 @@ impl p3 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the x-component of the point.
|
||||
pub fn x(&self) -> f32 {
|
||||
self.x
|
||||
}
|
||||
|
||||
/// Returns the y-component of the point.
|
||||
pub fn y(&self) -> f32 {
|
||||
self.y
|
||||
}
|
||||
|
||||
/// Returns the z-component of the point.
|
||||
pub fn z(&self) -> f32 {
|
||||
self.z
|
||||
}
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
use std::ops::*;
|
||||
|
||||
/// Representation of a polynomial of degree `n`.
|
||||
pub struct Polynomial {
|
||||
coefficients: Vec<f32>,
|
||||
degree: usize
|
||||
degree: usize,
|
||||
}
|
||||
|
||||
impl Polynomial {
|
||||
/// Creates a new polynomial from a list of coefficients.
|
||||
pub fn new(coefficients: Vec<f32>) -> Self {
|
||||
let degree = coefficients.len() - 1;
|
||||
Self {
|
||||
coefficients,
|
||||
degree
|
||||
degree,
|
||||
}
|
||||
}
|
||||
|
||||
/// Evaluates the polynomial at a given point.
|
||||
pub fn evaluate(&self, x: f32) -> f32 {
|
||||
let mut result = 0.0;
|
||||
for c in &self.coefficients {
|
||||
|
@ -22,6 +25,7 @@ impl Polynomial {
|
|||
result
|
||||
}
|
||||
|
||||
/// Differentiates the polynomial.
|
||||
pub fn differentiate(&self) -> Self {
|
||||
let mut new_coefficients = Vec::new();
|
||||
for (i, &c) in self.coefficients.iter().enumerate() {
|
||||
|
@ -32,6 +36,7 @@ impl Polynomial {
|
|||
Self::new(new_coefficients)
|
||||
}
|
||||
|
||||
/// Integrates the polynomial.
|
||||
pub fn integrate(&self) -> Self {
|
||||
let mut new_coefficients = Vec::new();
|
||||
new_coefficients.push(0.0);
|
||||
|
@ -49,8 +54,16 @@ impl Add for Polynomial {
|
|||
let mut new_coefficients = Vec::new();
|
||||
let mut i = 0;
|
||||
while i < self.coefficients.len() || i < other.coefficients.len() {
|
||||
let a = if i < self.coefficients.len() { self.coefficients[i] } else { 0.0 };
|
||||
let b = if i < other.coefficients.len() { other.coefficients[i] } else { 0.0 };
|
||||
let a = if i < self.coefficients.len() {
|
||||
self.coefficients[i]
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
let b = if i < other.coefficients.len() {
|
||||
other.coefficients[i]
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
new_coefficients.push(a + b);
|
||||
i += 1;
|
||||
}
|
||||
|
@ -65,8 +78,16 @@ impl Sub for Polynomial {
|
|||
let mut new_coefficients = Vec::new();
|
||||
let mut i = 0;
|
||||
while i < self.coefficients.len() || i < other.coefficients.len() {
|
||||
let a = if i < self.coefficients.len() { self.coefficients[i] } else { 0.0 };
|
||||
let b = if i < other.coefficients.len() { other.coefficients[i] } else { 0.0 };
|
||||
let a = if i < self.coefficients.len() {
|
||||
self.coefficients[i]
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
let b = if i < other.coefficients.len() {
|
||||
other.coefficients[i]
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
new_coefficients.push(a - b);
|
||||
i += 1;
|
||||
}
|
||||
|
@ -111,7 +132,9 @@ impl Div for Polynomial {
|
|||
|
||||
impl std::fmt::Display for Polynomial {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let terms: Vec<String> = self.coefficients.iter()
|
||||
let terms: Vec<String> = self
|
||||
.coefficients
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, &c)| c != 0.0)
|
||||
.map(|(i, &c)| {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::ops::*;
|
||||
use std::ops::Mul;
|
||||
use crate::vector::v3;
|
||||
use std::ops::Mul;
|
||||
use std::ops::*;
|
||||
|
||||
/// Representation of a quaternion in scalar/vector form
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
|
@ -10,20 +10,22 @@ pub struct Quat {
|
|||
}
|
||||
|
||||
impl Quat {
|
||||
pub const fn zero() -> Self {
|
||||
Self {
|
||||
/// The zero quaternion.
|
||||
const ZERO: Self = Self {
|
||||
s: 0.0,
|
||||
v: v3 {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// Creates a new quaternion from a scalar and a vector.
|
||||
pub const fn new(s: f32, v: v3) -> Self {
|
||||
Self { s, v }
|
||||
}
|
||||
|
||||
/// Returns the conjugate of the quaternion.
|
||||
pub fn conjugate(&self) -> Self {
|
||||
Self {
|
||||
s: self.s,
|
||||
|
@ -31,11 +33,15 @@ impl Quat {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the normalized version of the quaternion.
|
||||
pub fn normalize(&self) -> Self {
|
||||
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();
|
||||
Self::new(self.s*inverse_squareroot, self.v*inverse_squareroot)
|
||||
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();
|
||||
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,
|
||||
|
@ -105,8 +111,8 @@ impl Mul<Quat> for f32 {
|
|||
|
||||
fn mul(self, quat: Quat) -> Quat {
|
||||
Quat {
|
||||
s: self*quat.s,
|
||||
v: self*quat.v,
|
||||
s: self * quat.s,
|
||||
v: self * quat.v,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -116,12 +122,18 @@ impl Mul<Quat> for Quat {
|
|||
|
||||
fn mul(self, other: 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
|
||||
- self.v.x * other.v.x
|
||||
- self.v.y * other.v.y
|
||||
- self.v.z * other.v.z,
|
||||
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,
|
||||
}
|
||||
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,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -131,8 +143,8 @@ impl Mul<f32> for Quat {
|
|||
|
||||
fn mul(self, scalar: f32) -> Quat {
|
||||
Quat {
|
||||
s: self.s*scalar,
|
||||
v: self.v*scalar,
|
||||
s: self.s * scalar,
|
||||
v: self.v * scalar,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,8 +154,8 @@ impl Div<f32> for Quat {
|
|||
|
||||
fn div(self, scalar: f32) -> Quat {
|
||||
Quat {
|
||||
s: self.s/scalar,
|
||||
v: self.v/scalar,
|
||||
s: self.s / scalar,
|
||||
v: self.v / scalar,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,7 +29,7 @@ pub trait InnerSpace:
|
|||
// # VECTOR 2D #
|
||||
// ##################################################
|
||||
|
||||
/// Representation of a 2D Vector
|
||||
/// Representation of a 2D vector
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
|
@ -40,30 +40,39 @@ pub struct v2 {
|
|||
}
|
||||
|
||||
impl v2 {
|
||||
/// The unit vector along the x-axis.
|
||||
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 };
|
||||
/// The zero vector.
|
||||
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 {
|
||||
v2 { x, y }
|
||||
}
|
||||
|
||||
/// Creates a new vector from a point.
|
||||
pub fn from_point(p: p2) -> Self {
|
||||
Self { x: p.x(), y: p.y() }
|
||||
}
|
||||
|
||||
/// Gets the x-component of the vector.
|
||||
pub fn x(&self) -> f32 {
|
||||
self.x
|
||||
}
|
||||
|
||||
/// Gets the y-component of the vector.
|
||||
pub fn y(&self) -> f32 {
|
||||
self.y
|
||||
}
|
||||
|
||||
/// Sets the x-component of the vector.
|
||||
pub fn set_x(&mut self, new_x: f32) {
|
||||
self.x = new_x;
|
||||
}
|
||||
|
||||
/// Sets the y-component of the vector.
|
||||
pub fn set_y(&mut self, new_y: f32) {
|
||||
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)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
|
@ -175,14 +184,19 @@ pub struct v2i {
|
|||
}
|
||||
|
||||
impl v2i {
|
||||
/// The unit vector in the x direction.
|
||||
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 };
|
||||
/// The zero vector.
|
||||
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 {
|
||||
v2i { x, y }
|
||||
}
|
||||
|
||||
/// Creates a new vector from a point.
|
||||
pub fn from_point(p: p2) -> Self {
|
||||
Self {
|
||||
x: p.x() as i64,
|
||||
|
@ -190,10 +204,12 @@ impl v2i {
|
|||
}
|
||||
}
|
||||
|
||||
/// Creates a 2D point from the vector.
|
||||
pub fn as_point(&self) -> p2 {
|
||||
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 {
|
||||
Self {
|
||||
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 {
|
||||
v2 {
|
||||
x: self.x as f32,
|
||||
|
@ -208,26 +225,32 @@ impl v2i {
|
|||
}
|
||||
}
|
||||
|
||||
/// Gets the x component of the vector.
|
||||
pub fn x(&self) -> i64 {
|
||||
self.x
|
||||
}
|
||||
|
||||
/// Gets the y component of the vector.
|
||||
pub fn y(&self) -> i64 {
|
||||
self.y
|
||||
}
|
||||
|
||||
/// Sets the x component of the vector.
|
||||
pub fn set_x(&mut self, new_x: i64) {
|
||||
self.x = new_x;
|
||||
}
|
||||
|
||||
/// Sets the y component of the vector.
|
||||
pub fn set_y(&mut self, new_y: i64) {
|
||||
self.y = new_y;
|
||||
}
|
||||
|
||||
/// Gets the length of the vector.
|
||||
pub fn length(&self) -> 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 {
|
||||
let factor = 1.0 / self.length() as f32;
|
||||
v2i {
|
||||
|
@ -236,6 +259,8 @@ impl v2i {
|
|||
}
|
||||
}
|
||||
|
||||
/// Swizzles the vector components.
|
||||
/// (x,y) -> (x,x)
|
||||
pub fn xx(&self) -> Self {
|
||||
Self {
|
||||
x: self.x,
|
||||
|
@ -243,6 +268,8 @@ impl v2i {
|
|||
}
|
||||
}
|
||||
|
||||
/// Swizzles the vector components.
|
||||
/// (x,y) -> (x,y)
|
||||
pub fn xy(&self) -> Self {
|
||||
Self {
|
||||
x: self.x,
|
||||
|
@ -250,6 +277,8 @@ impl v2i {
|
|||
}
|
||||
}
|
||||
|
||||
/// Swizzles the vector components.
|
||||
/// (x,y) -> (y,x)
|
||||
pub fn yx(&self) -> Self {
|
||||
Self {
|
||||
x: self.y,
|
||||
|
@ -257,6 +286,8 @@ impl v2i {
|
|||
}
|
||||
}
|
||||
|
||||
/// Swizzles the vector components.
|
||||
/// (x,y) -> (y,y)
|
||||
pub fn yy(&self) -> Self {
|
||||
Self {
|
||||
x: self.y,
|
||||
|
@ -390,7 +421,7 @@ impl Into<[f32; 2]> for v2i {
|
|||
// # VECTOR 3D #
|
||||
// ##################################################
|
||||
|
||||
/// Representation of a 3D Vector
|
||||
/// Representation of a 3D vector
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
|
@ -402,31 +433,37 @@ pub struct v3 {
|
|||
}
|
||||
|
||||
impl v3 {
|
||||
/// The unit vector along the x-axis.
|
||||
pub const X: v3 = v3 {
|
||||
x: 1.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
};
|
||||
/// The unit vector along the y-axis.
|
||||
pub const Y: v3 = v3 {
|
||||
x: 0.0,
|
||||
y: 1.0,
|
||||
z: 0.0,
|
||||
};
|
||||
/// The unit vector along the z-axis.
|
||||
pub const Z: v3 = v3 {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 1.0,
|
||||
};
|
||||
/// The zero vector.
|
||||
pub const ZERO: v3 = v3 {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
};
|
||||
|
||||
/// Creates a new vector with the given components.
|
||||
pub const fn new(x: f32, y: f32, z: f32) -> Self {
|
||||
v3 { x, y, z }
|
||||
}
|
||||
|
||||
/// Creates a new vector from a point.
|
||||
pub fn from_point(p: p3) -> Self {
|
||||
Self {
|
||||
x: p.x(),
|
||||
|
@ -435,30 +472,37 @@ impl v3 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Creates a new point from a vector.
|
||||
pub fn as_point(&self) -> p3 {
|
||||
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 {
|
||||
self.x
|
||||
}
|
||||
|
||||
/// Gets the y-component of the vector.
|
||||
pub fn y(&self) -> f32 {
|
||||
self.y
|
||||
}
|
||||
|
||||
/// Gets the z-component of the vector.
|
||||
pub fn z(&self) -> f32 {
|
||||
self.z
|
||||
}
|
||||
|
||||
/// Sets the x-component of the vector.
|
||||
pub fn set_x(&mut self, new_x: f32) {
|
||||
self.x = new_x;
|
||||
}
|
||||
|
||||
/// Sets the y-component of the vector.
|
||||
pub fn set_y(&mut self, new_y: f32) {
|
||||
self.y = new_y;
|
||||
}
|
||||
|
||||
/// Sets the z-component of the vector.
|
||||
pub fn set_z(&mut self, new_z: f32) {
|
||||
self.z = new_z;
|
||||
}
|
||||
|
@ -574,6 +618,7 @@ impl Into<v3> for [f32; 3] {
|
|||
}
|
||||
}
|
||||
|
||||
/// Representation of a 3D integer vector
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
|
@ -585,15 +630,21 @@ pub struct v3i {
|
|||
}
|
||||
|
||||
impl v3i {
|
||||
/// The unit vector in the x-direction.
|
||||
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 };
|
||||
/// The unit vector in the z-direction.
|
||||
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 };
|
||||
|
||||
/// Creates a new vector with the given components.
|
||||
pub const fn new(x: i64, y: i64, z: i64) -> Self {
|
||||
v3i { x, y, z }
|
||||
}
|
||||
|
||||
/// Creates a new vector from a point.
|
||||
pub fn from_point(p: p3) -> Self {
|
||||
Self {
|
||||
x: p.x() as i64,
|
||||
|
@ -602,34 +653,42 @@ impl v3i {
|
|||
}
|
||||
}
|
||||
|
||||
/// Gets the x-component of the vector.
|
||||
pub fn x(&self) -> i64 {
|
||||
self.x
|
||||
}
|
||||
|
||||
/// Gets the y-component of the vector.
|
||||
pub fn y(&self) -> i64 {
|
||||
self.y
|
||||
}
|
||||
|
||||
/// Gets the z-component of the vector.
|
||||
pub fn z(&self) -> i64 {
|
||||
self.z
|
||||
}
|
||||
|
||||
/// Sets the x-component of the vector.
|
||||
pub fn set_x(&mut self, new_x: i64) {
|
||||
self.x = new_x;
|
||||
}
|
||||
|
||||
/// Sets the y-component of the vector.
|
||||
pub fn set_y(&mut self, new_y: i64) {
|
||||
self.y = new_y;
|
||||
}
|
||||
|
||||
/// Sets the z-component of the vector.
|
||||
pub fn set_z(&mut self, new_z: i64) {
|
||||
self.z = new_z;
|
||||
}
|
||||
|
||||
/// Calculates the length of the vector.
|
||||
pub fn length(&self) -> 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 {
|
||||
let factor = 1 / self.length();
|
||||
v3i {
|
||||
|
@ -763,7 +822,7 @@ impl From<v3> for v3i {
|
|||
// # VECTOR 4D #
|
||||
// ##################################################
|
||||
|
||||
/// Representation of a 4D Vector
|
||||
/// Representation of a 4D vector
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
|
@ -776,24 +835,31 @@ pub struct v4 {
|
|||
}
|
||||
|
||||
impl v4 {
|
||||
/// The unit vector along the x-axis.
|
||||
pub const X: v4 = v4 {
|
||||
x: 1.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
w: 0.0,
|
||||
};
|
||||
|
||||
/// The unit vector along the y-axis.
|
||||
pub const Y: v4 = v4 {
|
||||
x: 0.0,
|
||||
y: 1.0,
|
||||
z: 0.0,
|
||||
w: 0.0,
|
||||
};
|
||||
|
||||
/// The unit vector along the z-axis.
|
||||
pub const Z: v4 = v4 {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 1.0,
|
||||
w: 0.0,
|
||||
};
|
||||
|
||||
/// The unit vector along the w-axis.
|
||||
pub const W: v4 = v4 {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
|
@ -801,6 +867,7 @@ impl v4 {
|
|||
w: 1.0,
|
||||
};
|
||||
|
||||
/// The zero vector.
|
||||
pub const ZERO: v4 = v4 {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
|
@ -808,38 +875,47 @@ impl v4 {
|
|||
w: 0.0,
|
||||
};
|
||||
|
||||
/// Creates a new vector with the given components.
|
||||
pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
|
||||
v4 { x, y, z, w }
|
||||
}
|
||||
|
||||
/// Gets the x-component of the vector.
|
||||
pub fn x(&self) -> f32 {
|
||||
self.x
|
||||
}
|
||||
|
||||
/// Gets the y-component of the vector.
|
||||
pub fn y(&self) -> f32 {
|
||||
self.y
|
||||
}
|
||||
|
||||
/// Gets the z-component of the vector.
|
||||
pub fn z(&self) -> f32 {
|
||||
self.z
|
||||
}
|
||||
|
||||
/// Gets the w-component of the vector.
|
||||
pub fn w(&self) -> f32 {
|
||||
self.w
|
||||
}
|
||||
|
||||
/// Sets the x-component of the vector.
|
||||
pub fn set_x(&mut self, new_x: f32) {
|
||||
self.x = new_x;
|
||||
}
|
||||
|
||||
/// Sets the y-component of the vector.
|
||||
pub fn set_y(&mut self, new_y: f32) {
|
||||
self.y = new_y;
|
||||
}
|
||||
|
||||
/// Sets the z-component of the vector.
|
||||
pub fn set_z(&mut self, new_z: f32) {
|
||||
self.z = new_z;
|
||||
}
|
||||
|
||||
/// Sets the w-component of the vector.
|
||||
pub fn set_w(&mut self, new_w: f32) {
|
||||
self.w = new_w;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue