mirror of
https://github.com/lisk77/comet.git
synced 2025-10-23 21:38:50 +00:00
feat(math): added to_point method into the InnerSpace trait and added tangent evaluation to the Bezier curve struct (changed point to vecs inside the struct as well)
This commit is contained in:
parent
d04c706a94
commit
05a4679f38
3 changed files with 929 additions and 831 deletions
|
@ -1,21 +1,18 @@
|
|||
use crate::Point;
|
||||
use crate::{InnerSpace, Point};
|
||||
|
||||
pub struct Bezier<P: Point> {
|
||||
points: Vec<P>,
|
||||
degree: usize
|
||||
pub struct Bezier<V: InnerSpace> {
|
||||
points: Vec<V>,
|
||||
degree: usize,
|
||||
}
|
||||
|
||||
impl<P: Point + Clone> Bezier<P> {
|
||||
pub fn new(points: Vec<P>) -> Self {
|
||||
impl<V: InnerSpace + Clone> Bezier<V> {
|
||||
pub fn new(points: Vec<V>) -> Self {
|
||||
let degree = points.len() - 1;
|
||||
|
||||
Self {
|
||||
points,
|
||||
degree
|
||||
}
|
||||
Self { points, degree }
|
||||
}
|
||||
|
||||
pub fn evaluate(&self, t: f32) -> P {
|
||||
pub fn evaluate(&self, t: f32) -> V {
|
||||
let mut new_points = self.points.clone();
|
||||
for i in 0..self.degree {
|
||||
for j in 0..(self.degree - i) {
|
||||
|
@ -24,4 +21,22 @@ impl<P: Point + Clone> Bezier<P> {
|
|||
}
|
||||
new_points[0].clone()
|
||||
}
|
||||
|
||||
pub fn evaluate_tangent(&self, t: f32) -> V {
|
||||
let n = self.degree as f32;
|
||||
|
||||
let mut d_pts: Vec<V> = self
|
||||
.points
|
||||
.windows(2)
|
||||
.map(|w| ((w[1] - w[0]) * n))
|
||||
.collect::<Vec<V>>();
|
||||
|
||||
for i in 0..(self.degree - 1) {
|
||||
for j in 0..(self.degree - 1 - i) {
|
||||
d_pts[j] = d_pts[j].lerp(&d_pts[j + 1], t);
|
||||
}
|
||||
}
|
||||
|
||||
d_pts[0].clone().normalize()
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
use crate::InnerSpace;
|
||||
use rand::seq::index::IndexVecIntoIter;
|
||||
|
||||
use crate::vector::{v2, v3};
|
||||
use crate::InnerSpace;
|
||||
|
||||
pub trait Point {
|
||||
fn lerp(&self, other: &Self, t: f32) -> Self;
|
||||
|
@ -9,7 +11,7 @@ pub trait Point {
|
|||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct p2 {
|
||||
x: f32,
|
||||
y: f32
|
||||
y: f32,
|
||||
}
|
||||
|
||||
impl p2 {
|
||||
|
@ -34,7 +36,7 @@ impl p2 {
|
|||
pub struct p3 {
|
||||
x: f32,
|
||||
y: f32,
|
||||
z: f32
|
||||
z: f32,
|
||||
}
|
||||
|
||||
impl p3 {
|
||||
|
@ -43,7 +45,11 @@ impl p3 {
|
|||
}
|
||||
|
||||
pub fn from_vec(v: v3) -> Self {
|
||||
Self { x: v.x(), y: v.y(), z: v.z() }
|
||||
Self {
|
||||
x: v.x(),
|
||||
y: v.y(),
|
||||
z: v.z(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn x(&self) -> f32 {
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
use crate::point::{p2, p3};
|
||||
use crate::quaternion::Quat;
|
||||
use crate::Point;
|
||||
use std::ops::*;
|
||||
|
||||
pub trait InnerSpace:
|
||||
std::fmt::Debug +
|
||||
Copy +
|
||||
Clone +
|
||||
Neg<Output = Self> +
|
||||
Mul<f32, Output = Self> +
|
||||
Div<f32, Output = Self> +
|
||||
Add<Self, Output = Self> +
|
||||
Sub<Self, Output = Self>
|
||||
std::fmt::Debug
|
||||
+ Copy
|
||||
+ Clone
|
||||
+ Neg<Output = Self>
|
||||
+ Mul<f32, Output = Self>
|
||||
+ Div<f32, Output = Self>
|
||||
+ Add<Self, Output = Self>
|
||||
+ Sub<Self, Output = Self>
|
||||
{
|
||||
fn dot(&self, other: &Self) -> f32;
|
||||
fn dist(&self, other: &Self) -> f32;
|
||||
|
@ -21,6 +22,7 @@ pub trait InnerSpace:
|
|||
fn project_onto(&self, other: &Self) -> Self;
|
||||
fn reflect(&self, normal: &Self) -> Self;
|
||||
fn lerp(&self, other: &Self, t: f32) -> Self;
|
||||
fn to_point(&self) -> impl Point;
|
||||
}
|
||||
|
||||
// ##################################################
|
||||
|
@ -31,6 +33,7 @@ pub trait InnerSpace:
|
|||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct v2 {
|
||||
x: f32,
|
||||
y: f32,
|
||||
|
@ -146,13 +149,13 @@ impl Div<f32> for v2 {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<[f32;2]> for v2 {
|
||||
fn into(self) -> [f32;2] {
|
||||
impl Into<[f32; 2]> for v2 {
|
||||
fn into(self) -> [f32; 2] {
|
||||
[self.x, self.y]
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<v2> for [f32;2] {
|
||||
impl Into<v2> for [f32; 2] {
|
||||
fn into(self) -> v2 {
|
||||
v2 {
|
||||
x: self[0],
|
||||
|
@ -165,6 +168,7 @@ impl Into<v2> for [f32;2] {
|
|||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct v2i {
|
||||
x: i64,
|
||||
y: i64,
|
||||
|
@ -180,7 +184,21 @@ impl v2i {
|
|||
}
|
||||
|
||||
pub fn from_point(p: p2) -> Self {
|
||||
Self { x: p.x() as i64, y: p.y() as i64 }
|
||||
Self {
|
||||
x: p.x() as i64,
|
||||
y: p.y() as i64,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_point(&self) -> p2 {
|
||||
p2::new(self.x as f32, self.y as f32)
|
||||
}
|
||||
|
||||
pub fn from_vec2(v: v2) -> Self {
|
||||
Self {
|
||||
x: v.x as i64,
|
||||
y: v.y as i64,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_vec2(&self) -> v2 {
|
||||
|
@ -356,14 +374,14 @@ impl From<v2> for v2i {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<[i64;2]> for v2i {
|
||||
fn into(self) -> [i64;2] {
|
||||
impl Into<[i64; 2]> for v2i {
|
||||
fn into(self) -> [i64; 2] {
|
||||
[self.x, self.y]
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<[f32;2]> for v2i {
|
||||
fn into(self) -> [f32;2] {
|
||||
impl Into<[f32; 2]> for v2i {
|
||||
fn into(self) -> [f32; 2] {
|
||||
[self.x as f32, self.y as f32]
|
||||
}
|
||||
}
|
||||
|
@ -376,6 +394,7 @@ impl Into<[f32;2]> for v2i {
|
|||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct v3 {
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
|
@ -383,10 +402,26 @@ pub struct v3 {
|
|||
}
|
||||
|
||||
impl v3 {
|
||||
pub const X: v3 = v3 { x: 1.0, y: 0.0, z: 0.0 };
|
||||
pub const Y: v3 = v3 { x: 0.0, y: 1.0, z: 0.0 };
|
||||
pub const Z: v3 = v3 { x: 0.0, y: 0.0, z: 1.0 };
|
||||
pub const ZERO: v3 = v3 { x: 0.0, y: 0.0, z: 0.0 };
|
||||
pub const X: v3 = v3 {
|
||||
x: 1.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
};
|
||||
pub const Y: v3 = v3 {
|
||||
x: 0.0,
|
||||
y: 1.0,
|
||||
z: 0.0,
|
||||
};
|
||||
pub const Z: v3 = v3 {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 1.0,
|
||||
};
|
||||
pub const ZERO: v3 = v3 {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
};
|
||||
|
||||
pub const fn new(x: f32, y: f32, z: f32) -> Self {
|
||||
v3 { x, y, z }
|
||||
|
@ -400,6 +435,10 @@ impl v3 {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn as_point(&self) -> p3 {
|
||||
p3::new(self.x as f32, self.y as f32, self.z as f32)
|
||||
}
|
||||
|
||||
pub fn x(&self) -> f32 {
|
||||
self.x
|
||||
}
|
||||
|
@ -519,13 +558,13 @@ impl Into<Quat> for v3 {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<[f32;3]> for v3 {
|
||||
fn into(self) -> [f32;3] {
|
||||
impl Into<[f32; 3]> for v3 {
|
||||
fn into(self) -> [f32; 3] {
|
||||
[self.x, self.y, self.z]
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<v3> for [f32;3] {
|
||||
impl Into<v3> for [f32; 3] {
|
||||
fn into(self) -> v3 {
|
||||
v3 {
|
||||
x: self[0],
|
||||
|
@ -535,10 +574,10 @@ impl Into<v3> for [f32;3] {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct v3i {
|
||||
pub x: i64,
|
||||
pub y: i64,
|
||||
|
@ -728,6 +767,7 @@ impl From<v3> for v3i {
|
|||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct v4 {
|
||||
x: f32,
|
||||
y: f32,
|
||||
|
@ -736,12 +776,37 @@ pub struct v4 {
|
|||
}
|
||||
|
||||
impl v4 {
|
||||
pub const X: v4 = v4 { x: 1.0, y: 0.0, z: 0.0, w: 0.0 };
|
||||
pub const Y: v4 = v4 { x: 0.0, y: 1.0, z: 0.0, w: 0.0 };
|
||||
pub const Z: v4 = v4 { x: 0.0, y: 0.0, z: 1.0, w: 0.0 };
|
||||
pub const W: v4 = v4 { x: 0.0, y: 0.0, z: 0.0, w: 1.0 };
|
||||
pub const X: v4 = v4 {
|
||||
x: 1.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
w: 0.0,
|
||||
};
|
||||
pub const Y: v4 = v4 {
|
||||
x: 0.0,
|
||||
y: 1.0,
|
||||
z: 0.0,
|
||||
w: 0.0,
|
||||
};
|
||||
pub const Z: v4 = v4 {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 1.0,
|
||||
w: 0.0,
|
||||
};
|
||||
pub const W: v4 = v4 {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
w: 1.0,
|
||||
};
|
||||
|
||||
pub const ZERO: v4 = v4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 };
|
||||
pub const ZERO: v4 = v4 {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
w: 0.0,
|
||||
};
|
||||
|
||||
pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
|
||||
v4 { x, y, z, w }
|
||||
|
@ -885,8 +950,8 @@ impl Div<f32> for v4 {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<[f32;4]> for v4 {
|
||||
fn into(self) -> [f32;4] {
|
||||
impl Into<[f32; 4]> for v4 {
|
||||
fn into(self) -> [f32; 4] {
|
||||
[self.x, self.y, self.z, self.w]
|
||||
}
|
||||
}
|
||||
|
@ -938,6 +1003,10 @@ impl InnerSpace for v2 {
|
|||
fn lerp(&self, other: &Self, t: f32) -> Self {
|
||||
*self * (1.0 - t) + *other * t
|
||||
}
|
||||
|
||||
fn to_point(&self) -> impl Point {
|
||||
p2::new(self.x, self.y)
|
||||
}
|
||||
}
|
||||
|
||||
impl InnerSpace for v3 {
|
||||
|
@ -990,6 +1059,10 @@ impl InnerSpace for v3 {
|
|||
fn lerp(&self, other: &Self, t: f32) -> Self {
|
||||
*self * (1.0 - t) + *other * t
|
||||
}
|
||||
|
||||
fn to_point(&self) -> impl Point {
|
||||
p3::new(self.x, self.y, self.z)
|
||||
}
|
||||
}
|
||||
|
||||
impl InnerSpace for v4 {
|
||||
|
@ -1045,6 +1118,10 @@ impl InnerSpace for v4 {
|
|||
fn lerp(&self, other: &Self, t: f32) -> Self {
|
||||
*self * (1.0 - t) + *other * t
|
||||
}
|
||||
|
||||
fn to_point(&self) -> impl Point {
|
||||
p3::new(self.x / self.w, self.y / self.w, self.z / self.w)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! generate_swizzles2 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue