summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lerp.rs9
-rw-r--r--src/main.rs175
-rw-r--r--src/number.rs1
-rw-r--r--src/poly.rs40
-rw-r--r--src/poly/iter.rs9
5 files changed, 102 insertions, 132 deletions
diff --git a/src/lerp.rs b/src/lerp.rs
index 1501d0f..b098f23 100644
--- a/src/lerp.rs
+++ b/src/lerp.rs
@@ -1,18 +1,17 @@
-use crate::number::Number;
use crate::poly::Poly;
pub enum Lerp {
Node(Box<Lerp>, Box<Lerp>),
- Leaf(Number, Number),
- Just(Number)
+ Leaf(f32, f32),
+ Just(f32),
}
impl Lerp {
- pub fn new(v: Vec<Number>) -> Box<Lerp> {
+ pub fn new(v: Vec<f32>) -> Box<Lerp> {
Lerp::new_s(&v[..])
}
- fn new_s(v: &[Number]) -> Box<Lerp> {
+ fn new_s(v: &[f32]) -> Box<Lerp> {
match v.len() {
0 => Box::new(Lerp::Just(0.0)),
1 => Box::new(Lerp::Just(v[0])),
diff --git a/src/main.rs b/src/main.rs
index 9f9ad9f..a9bfcf9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,8 +1,8 @@
mod lerp;
-mod number;
mod poly;
use lerp::Lerp;
+use poly::Poly;
use std::ffi::{CStr, CString};
@@ -25,6 +25,92 @@ fn shader_from_source(source: &CStr, shader_type: GLenum) -> GLuint {
}
}
+fn compile_bezier_shader(a: Poly, b: Poly) -> GLuint {
+ let vertex_shader_source = b"
+ #version 410 core
+ layout (location = 0) in vec3 aPos;
+
+ void main() {
+ gl_Position = vec4(aPos.xyz, 1.0);
+ }
+ "
+ .to_vec();
+
+ let fragment_shader_source = format!(
+ "
+ #version 410 core
+ out vec4 FragColor;
+
+ float pa[{sa}] = float[{sa}]({pa});
+ float pb[{sb}] = float[{sb}]({pb});
+
+ float eval_a(float[{sa}] v, float t) {{
+ float result = 0.0;
+ for (int i = 0; i < {sa}; i++) {{
+ result += v[i] * pow(t, i);
+ }}
+ return result;
+ }}
+
+ float eval_b(float[{sb}] v, float t) {{
+ float result = 0.0;
+ for (int i = 0; i < {sb}; i++) {{
+ result += v[i] * pow(t, i);
+ }}
+ return result;
+ }}
+
+ float inside(vec2 pos) {{
+ float res = 100;
+ float thr = 32;
+ float closest = 1000000;
+ float t = 0.0;
+ while (t < 1.0) {{
+ float step = t + 1.0 / res;
+ vec2 a = vec2(eval_a(pa, t), eval_b(pb, t));
+ vec2 b = vec2(eval_a(pa, step), eval_b(pb, step));
+ float c = pow(length(a - b), 2);
+ float d = distance(pos, a + clamp(dot(pos - a, b - a) / c, 0, 1) * (b - a));
+ if (d < closest) {{
+ closest = d;
+ }}
+ t = step;
+ }}
+ return 1 - closest / thr;
+ }}
+
+ void main() {{
+ float r = inside(gl_FragCoord.xy);
+ FragColor = vec4(r * 0.8, r * 0.2, r, 1.0);
+ }}
+ ",
+ sa = a.degree() + 1,
+ sb = b.degree() + 1,
+ pa = &a,
+ pb = &b
+ )
+ .into_bytes();
+
+ let shader_program: GLuint;
+ unsafe {
+ let vertex_shader = shader_from_source(
+ &CString::from_vec_unchecked(vertex_shader_source),
+ gl::VERTEX_SHADER,
+ );
+ let fragment_shader = shader_from_source(
+ &CString::from_vec_unchecked(fragment_shader_source),
+ gl::FRAGMENT_SHADER,
+ );
+ shader_program = gl::CreateProgram();
+ gl::AttachShader(shader_program, vertex_shader);
+ gl::AttachShader(shader_program, fragment_shader);
+ gl::LinkProgram(shader_program);
+ gl::DeleteShader(vertex_shader);
+ gl::DeleteShader(fragment_shader);
+ }
+ shader_program
+}
+
fn main() {
let a = lerp::lp(Lerp::new(vec![200.0, 500.0, 500.0]));
let b = lerp::lp(Lerp::new(vec![200.0, 500.0, 200.0]));
@@ -56,75 +142,10 @@ fn main() {
}
let vertices: [f32; 18] = [
- 1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, 1.0, 0.0,
- 1.0, -1.0, 0.0, -1.0, -1.0, 0.0, -1.0, 1.0, 0.0,
+ 1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0, -1.0, 1.0,
+ 0.0,
];
- let vertex_shader_source = b"
- #version 410 core
- layout (location = 0) in vec3 aPos;
-
- void main() {
- gl_Position = vec4(aPos.xyz, 1.0);
- }
- "
- .to_vec();
-
- let fragment_shader_source = String::from(format!(
- "
-#version 410 core
-out vec4 FragColor;
-
-float pa[{sa}] = float[{sa}]({pa});
-float pb[{sb}] = float[{sb}]({pb});
-
-float eval_a(float[{sa}] v, float t) {{
- float result = 0.0;
- for (int i = 0; i < {sa}; i++) {{
- result += v[i] * pow(t, i);
- }}
- return result;
-}}
-
-float eval_b(float[{sb}] v, float t) {{
- float result = 0.0;
- for (int i = 0; i < {sb}; i++) {{
- result += v[i] * pow(t, i);
- }}
- return result;
-}}
-
-float inside(vec2 pos) {{
- float res = 100;
- float thr = 32;
- float closest = 1000000;
- float t = 0.0;
- while (t < 1.0) {{
- float step = t + 1.0 / res;
- vec2 a = vec2(eval_a(pa, t), eval_b(pb, t));
- vec2 b = vec2(eval_a(pa, step), eval_b(pb, step));
- float c = pow(length(a - b), 2);
- float d = distance(pos, a + clamp(dot(pos - a, b - a) / c, 0, 1) * (b - a));
- if (d < closest) {{
- closest = d;
- }}
- t = step;
- }}
- return 1 - closest / thr;
-}}
-
-void main() {{
- float r = inside(gl_FragCoord.xy);
- FragColor = vec4(r * 0.8, r * 0.2, r, 1.0);
-}}
- ",
- sa = a.degree() + 1,
- sb = b.degree() + 1,
- pa = &a,
- pb = &b
- ))
- .into_bytes();
-
let mut vbo: GLuint = 0;
let mut vao: GLuint = 0;
unsafe {
@@ -149,23 +170,7 @@ void main() {{
gl::EnableVertexAttribArray(0);
}
- let mut shader_program: GLuint = 0;
- unsafe {
- let vertex_shader = shader_from_source(
- &CString::from_vec_unchecked(vertex_shader_source),
- gl::VERTEX_SHADER,
- );
- let fragment_shader = shader_from_source(
- &CString::from_vec_unchecked(fragment_shader_source),
- gl::FRAGMENT_SHADER,
- );
- shader_program = gl::CreateProgram();
- gl::AttachShader(shader_program, vertex_shader);
- gl::AttachShader(shader_program, fragment_shader);
- gl::LinkProgram(shader_program);
- gl::DeleteShader(vertex_shader);
- gl::DeleteShader(fragment_shader);
- }
+ let shader_program = compile_bezier_shader(a, b);
let mut event_pump = sdl_context.event_pump().unwrap();
'running: loop {
diff --git a/src/number.rs b/src/number.rs
deleted file mode 100644
index cd5d47f..0000000
--- a/src/number.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub type Number = f32;
diff --git a/src/poly.rs b/src/poly.rs
index bae3a15..c76e481 100644
--- a/src/poly.rs
+++ b/src/poly.rs
@@ -1,18 +1,17 @@
mod iter;
-use crate::number::Number;
use iter::Iter;
use std::fmt;
use std::ops::{Add, Mul, Sub};
#[derive(PartialEq, Debug, Clone)]
pub struct Poly {
- data: Vec<Number>,
+ data: Vec<f32>,
degree: usize,
}
impl Poly {
- pub fn new(data: Vec<Number>) -> Poly {
+ pub fn new(data: Vec<f32>) -> Poly {
let mut i = data.len() - 1;
while data[i] == 0.0 && i > 0 {
i -= 1;
@@ -20,16 +19,6 @@ impl Poly {
Poly { data, degree: i }
}
- fn mono(degree: usize, coefficient: Number) -> Poly {
- if coefficient != 0.0 {
- let mut p = vec![0.0; degree + 1];
- p[degree] = coefficient;
- Poly::new(p)
- } else {
- Poly::new(vec![0.0])
- }
- }
-
pub fn degree(&self) -> usize {
self.degree
}
@@ -37,15 +26,6 @@ impl Poly {
fn iter(&self) -> Iter {
Iter::new(self.data.clone(), self.degree())
}
-
- fn is_zero(&self) -> bool {
- for i in 0..self.data.len() {
- if self.data[i] != 0.0 {
- return false;
- }
- }
- true
- }
}
impl Add for &Poly {
@@ -71,7 +51,7 @@ impl Mul for &Poly {
let mut r = Vec::new();
for i in 0..other.degree() + 1 {
let mut prefix = vec![0.0; i];
- let mut suffix: Vec<Number> = self
+ let mut suffix: Vec<f32> = self
.iter()
.take(self.degree() + 1)
.map(|x| x * other.data[i])
@@ -122,20 +102,8 @@ mod tests {
}
#[test]
- fn poly_is_zero() {
- let p = Poly::new(vec![0.0; 5]);
- assert_eq!(p.is_zero(), true);
- }
-
- #[test]
- fn poly_is_not_zero() {
- let p = Poly::mono(5, 8.0);
- assert_eq!(p.is_zero(), false);
- }
-
- #[test]
fn degree_is_five() {
- let p = Poly::mono(5, 2.0);
+ let p = Poly::new(vec![0.0, 0.0, 0.0, 0.0, 0.0, 2.0]);
assert_eq!(p.degree(), 5);
}
diff --git a/src/poly/iter.rs b/src/poly/iter.rs
index 059d7e3..90cc4b5 100644
--- a/src/poly/iter.rs
+++ b/src/poly/iter.rs
@@ -1,15 +1,14 @@
-use crate::number::Number;
use std::cmp;
use std::iter::{Take, Zip};
pub struct Iter {
index: usize,
- data: Vec<Number>,
+ data: Vec<f32>,
degree: usize,
}
impl Iter {
- pub fn new(data: Vec<Number>, degree: usize) -> Iter {
+ pub fn new(data: Vec<f32>, degree: usize) -> Iter {
Iter {
index: 0,
data,
@@ -26,9 +25,9 @@ impl Iter {
}
impl Iterator for Iter {
- type Item = Number;
+ type Item = f32;
- fn next(&mut self) -> Option<Number> {
+ fn next(&mut self) -> Option<f32> {
self.index += 1;
if self.index <= self.data.len() {
Some(self.data[self.index - 1])