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:
lisk77 2025-07-26 01:14:47 +02:00
parent d04c706a94
commit 05a4679f38
3 changed files with 929 additions and 831 deletions

View file

@ -1,27 +1,42 @@
use crate::Point; use crate::{InnerSpace, Point};
pub struct Bezier<P: Point> { pub struct Bezier<V: InnerSpace> {
points: Vec<P>, points: Vec<V>,
degree: usize degree: usize,
} }
impl<P: Point + Clone> Bezier<P> { impl<V: InnerSpace + Clone> Bezier<V> {
pub fn new(points: Vec<P>) -> Self { pub fn new(points: Vec<V>) -> Self {
let degree = points.len() - 1; let degree = points.len() - 1;
Self { Self { points, degree }
points, }
degree
}
}
pub fn evaluate(&self, t: f32) -> P { pub fn evaluate(&self, t: f32) -> V {
let mut new_points = self.points.clone(); let mut new_points = self.points.clone();
for i in 0..self.degree { for i in 0..self.degree {
for j in 0..(self.degree - i) { for j in 0..(self.degree - i) {
new_points[j] = new_points[j].lerp(&new_points[j + 1], t); new_points[j] = new_points[j].lerp(&new_points[j + 1], t);
} }
} }
new_points[0].clone() 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()
}
}

View file

@ -1,108 +1,114 @@
use crate::InnerSpace; use rand::seq::index::IndexVecIntoIter;
use crate::vector::{v2, v3}; use crate::vector::{v2, v3};
use crate::InnerSpace;
pub trait Point { pub trait Point {
fn lerp(&self, other: &Self, t: f32) -> Self; fn lerp(&self, other: &Self, t: f32) -> Self;
fn to_vec(&self) -> impl InnerSpace; fn to_vec(&self) -> impl InnerSpace;
} }
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct p2 { pub struct p2 {
x: f32, x: f32,
y: f32 y: f32,
} }
impl p2 { impl p2 {
pub fn new(x: f32, y: f32) -> Self { pub fn new(x: f32, y: f32) -> Self {
p2 { x, y } p2 { x, y }
} }
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() }
} }
pub fn x(&self) -> f32 { pub fn x(&self) -> f32 {
self.x self.x
} }
pub fn y(&self) -> f32 { pub fn y(&self) -> f32 {
self.y self.y
} }
} }
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct p3 { pub struct p3 {
x: f32, x: f32,
y: f32, y: f32,
z: f32 z: f32,
} }
impl p3 { impl p3 {
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 }
} }
pub fn from_vec(v: v3) -> Self { 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 { pub fn x(&self) -> f32 {
self.x self.x
} }
pub fn y(&self) -> f32 { pub fn y(&self) -> f32 {
self.y self.y
} }
pub fn z(&self) -> f32 { pub fn z(&self) -> f32 {
self.z self.z
} }
} }
impl Point for p2 { impl Point for p2 {
fn lerp(&self, other: &Self, t: f32) -> Self { fn lerp(&self, other: &Self, t: f32) -> Self {
let x = self.x + (other.x - self.x) * t; let x = self.x + (other.x - self.x) * t;
let y = self.y + (other.y - self.y) * t; let y = self.y + (other.y - self.y) * t;
Self { x, y } Self { x, y }
} }
fn to_vec(&self) -> v2 { fn to_vec(&self) -> v2 {
v2::new(self.x, self.y) v2::new(self.x, self.y)
} }
} }
impl Point for p3 { impl Point for p3 {
fn lerp(&self, other: &Self, t: f32) -> Self { fn lerp(&self, other: &Self, t: f32) -> Self {
let x = self.x + (other.x - self.x) * t; let x = self.x + (other.x - self.x) * t;
let y = self.y + (other.y - self.y) * t; let y = self.y + (other.y - self.y) * t;
let z = self.z + (other.z - self.z) * t; let z = self.z + (other.z - self.z) * t;
Self { x, y, z } Self { x, y, z }
} }
fn to_vec(&self) -> v3 { fn to_vec(&self) -> v3 {
v3::new(self.x, self.y, self.z) v3::new(self.x, self.y, self.z)
} }
} }
impl Into<v2> for p2 { impl Into<v2> for p2 {
fn into(self) -> v2 { fn into(self) -> v2 {
self.to_vec() self.to_vec()
} }
} }
impl Into<v3> for p3 { impl Into<v3> for p3 {
fn into(self) -> v3 { fn into(self) -> v3 {
self.to_vec() self.to_vec()
} }
} }
impl From<v2> for p2 { impl From<v2> for p2 {
fn from(v: v2) -> Self { fn from(v: v2) -> Self {
Self::from_vec(v) Self::from_vec(v)
} }
} }
impl From<v3> for p3 { impl From<v3> for p3 {
fn from(v: v3) -> Self { fn from(v: v3) -> Self {
Self::from_vec(v) Self::from_vec(v)
} }
} }

File diff suppressed because it is too large Load diff