1#![no_std]
2#![feature(core_intrinsics)]
3use {
4 core::intrinsics::{powf32, sinf32},
5 mem_64::Vec,
6};
7
8pub trait Points {
9 fn points(&self) -> Vec<&[f32; 2]>;
10}
11
12pub type Matrix<const M: usize, const N: usize> = [[f32; N]; M];
13
14pub fn ortho([left, bottom]: [f32; 2], [right, top]: [f32; 2]) -> Matrix<4, 4> {
15 [
16 [2.0 / (right - left), 0.0, 0.0, 0.0],
17 [0.0, 2.0 / (top - bottom), 0.0, 0.0],
18 [0.0, 0.0, 1.0, 0.0],
19 [
20 -(right + left) / (right - left),
21 -(top + bottom) / (top - bottom),
22 0.0,
23 1.0,
24 ],
25 ]
26}
27
28pub type Spline = Vec<Bezier>;
29
30impl Points for Spline {
31 fn points(&self) -> Vec<&[f32; 2]> {
32 self.iter().flat_map(|bezier| bezier.0.iter()).collect()
33 }
34}
35
36pub struct Bezier(Vec<[f32; 2]>);
37
38impl From<&[[f32; 2]]> for Bezier {
39 fn from(src: &[[f32; 2]]) -> Self {
40 Bezier(src.into())
41 }
42}
43
44impl Bezier {
45 fn subdivide(&self, n: usize) -> Vec<[f32; 2]> {
46 (0..=n)
47 .map(|x| {
48 let t = x as f32 / n as f32;
49 let mut point = [0.0, 0.0];
50 let k = self.0.len() - 1;
51
52 for v in 0..=k {
53 let b = factorial(k) as f32 / (factorial(v) * factorial(k - v)) as f32
54 * powf(t, v as f32)
55 * powf(1.0 - t, (k - v) as f32);
56
57 point[0] += b * self.0[v][0];
58 point[1] += b * self.0[v][1];
59 }
60
61 point
62 })
63 .collect()
64 }
65}
66
67pub trait Curve<Domain, Image> {
68 fn plot(&self, start: Domain, end: Domain, n: usize) -> Vec<Image>;
69}
70
71pub fn powf(a: f32, b: f32) -> f32 {
72 unsafe { powf32(a, b) }
73}
74
75pub fn sin(x: f32) -> f32 {
76 unsafe { sinf32(x) }
77}
78
79pub fn factorial(n: usize) -> usize {
80 match n {
81 0 | 1 => 1,
82 _ => factorial(n - 1) * n,
83 }
84}
85
86impl<F> Curve<f32, [f32; 2]> for F
87where
88 F: Fn(f32) -> f32,
89{
90 fn plot(&self, start: f32, end: f32, n: usize) -> Vec<[f32; 2]> {
91 let dx = (end - start) / n as f32;
92 let mut curve = Vec::with_capacity(n + 1);
93
94 for point in (0..=n).map(|x| {
95 let x = x as f32;
96 [start + (x * dx), self(start + (x * dx))]
97 }) {
98 curve.push(point);
99 }
100 curve
101 }
102}