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> {
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 {
let degree = points.len() - 1;
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 {
let mut new_points = self.points.clone();
for i in 0..self.degree {
for j in 0..(self.degree - i) {
new_points[j] = new_points[j].lerp(&new_points[j + 1], t);
}
}
new_points[0].clone()
}
}
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) {
new_points[j] = new_points[j].lerp(&new_points[j + 1], t);
}
}
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::InnerSpace;
pub trait Point {
fn lerp(&self, other: &Self, t: f32) -> Self;
fn to_vec(&self) -> impl InnerSpace;
fn lerp(&self, other: &Self, t: f32) -> Self;
fn to_vec(&self) -> impl InnerSpace;
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct p2 {
x: f32,
y: f32
x: f32,
y: f32,
}
impl p2 {
pub fn new(x: f32, y: f32) -> Self {
p2 { x, y }
}
pub fn new(x: f32, y: f32) -> Self {
p2 { x, y }
}
pub fn from_vec(v: v2) -> Self {
Self { x: v.x(), y: v.y() }
}
pub fn from_vec(v: v2) -> Self {
Self { x: v.x(), y: v.y() }
}
pub fn x(&self) -> f32 {
self.x
}
pub fn x(&self) -> f32 {
self.x
}
pub fn y(&self) -> f32 {
self.y
}
pub fn y(&self) -> f32 {
self.y
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct p3 {
x: f32,
y: f32,
z: f32
x: f32,
y: f32,
z: f32,
}
impl p3 {
pub fn new(x: f32, y: f32, z: f32) -> Self {
p3 { x, y, z }
}
pub fn new(x: f32, y: f32, z: f32) -> Self {
p3 { x, y, z }
}
pub fn from_vec(v: v3) -> Self {
Self { x: v.x(), y: v.y(), z: v.z() }
}
pub fn from_vec(v: v3) -> Self {
Self {
x: v.x(),
y: v.y(),
z: v.z(),
}
}
pub fn x(&self) -> f32 {
self.x
}
pub fn x(&self) -> f32 {
self.x
}
pub fn y(&self) -> f32 {
self.y
}
pub fn y(&self) -> f32 {
self.y
}
pub fn z(&self) -> f32 {
self.z
}
pub fn z(&self) -> f32 {
self.z
}
}
impl Point for p2 {
fn lerp(&self, other: &Self, t: f32) -> Self {
let x = self.x + (other.x - self.x) * t;
let y = self.y + (other.y - self.y) * t;
Self { x, y }
}
fn lerp(&self, other: &Self, t: f32) -> Self {
let x = self.x + (other.x - self.x) * t;
let y = self.y + (other.y - self.y) * t;
Self { x, y }
}
fn to_vec(&self) -> v2 {
v2::new(self.x, self.y)
}
fn to_vec(&self) -> v2 {
v2::new(self.x, self.y)
}
}
impl Point for p3 {
fn lerp(&self, other: &Self, t: f32) -> Self {
let x = self.x + (other.x - self.x) * t;
let y = self.y + (other.y - self.y) * t;
let z = self.z + (other.z - self.z) * t;
Self { x, y, z }
}
fn lerp(&self, other: &Self, t: f32) -> Self {
let x = self.x + (other.x - self.x) * t;
let y = self.y + (other.y - self.y) * t;
let z = self.z + (other.z - self.z) * t;
Self { x, y, z }
}
fn to_vec(&self) -> v3 {
v3::new(self.x, self.y, self.z)
}
fn to_vec(&self) -> v3 {
v3::new(self.x, self.y, self.z)
}
}
impl Into<v2> for p2 {
fn into(self) -> v2 {
self.to_vec()
}
fn into(self) -> v2 {
self.to_vec()
}
}
impl Into<v3> for p3 {
fn into(self) -> v3 {
self.to_vec()
}
fn into(self) -> v3 {
self.to_vec()
}
}
impl From<v2> for p2 {
fn from(v: v2) -> Self {
Self::from_vec(v)
}
fn from(v: v2) -> Self {
Self::from_vec(v)
}
}
impl From<v3> for p3 {
fn from(v: v3) -> Self {
Self::from_vec(v)
}
}
fn from(v: v3) -> Self {
Self::from_vec(v)
}
}

File diff suppressed because it is too large Load diff