diff options
author | Juan Manuel Tomás <jtomas1815@gmail.com> | 2021-01-17 20:25:58 -0300 |
---|---|---|
committer | Juan Manuel Tomás <jtomas1815@gmail.com> | 2021-01-17 20:25:58 -0300 |
commit | 70b5188de306b70cdf8a397dd4e0ee31f07050c8 (patch) | |
tree | 3721070393126b79a3658fe8a89f1fa98a84db44 /src/main.rs | |
parent | 18efe0d28ebcd936ea50275a351ef1c30253ea1c (diff) | |
download | bezier-70b5188de306b70cdf8a397dd4e0ee31f07050c8.tar.gz bezier-70b5188de306b70cdf8a397dd4e0ee31f07050c8.zip |
Fix curve overextending past last control point
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 68 |
1 files changed, 43 insertions, 25 deletions
diff --git a/src/main.rs b/src/main.rs index ee508e1..2c5dbcc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,4 @@ -mod lerp; -mod poly; - -use lerp::Lerp; -use poly::Poly; +use bezier::Bezier; use std::ffi::{CStr, CString}; @@ -25,7 +21,7 @@ fn shader_from_source(source: &CStr, shader_type: GLenum) -> GLuint { } } -fn compile_bezier_shader(a: Poly, b: Poly) -> GLuint { +fn compile_bezier_shader(c: Bezier) -> GLuint { let vertex_shader_source = b" #version 410 core layout (location = 0) in vec3 aPos; @@ -41,34 +37,48 @@ fn compile_bezier_shader(a: Poly, b: Poly) -> GLuint { #version 410 core out vec4 FragColor; - float pa[{sa}] = float[{sa}]({pa}); - float pb[{sb}] = float[{sb}]({pb}); + float inf = 1000000; + float vx[{s}] = float[{s}]({vx}); + float vy[{s}] = float[{s}]({vy}); + float px[{sx}] = float[{sx}]({px}); + float py[{sy}] = float[{sy}]({py}); + float thr = 32; - float eval_a(float[{sa}] v, float t) {{ + float eval_a(float[{sx}] v, float t) {{ float result = 0.0; - for (int i = 0; i < {sa}; i++) {{ + for (int i = 0; i < {sx}; i++) {{ result += v[i] * pow(t, i); }} return result; }} - float eval_b(float[{sb}] v, float t) {{ + float eval_b(float[{sy}] v, float t) {{ float result = 0.0; - for (int i = 0; i < {sb}; i++) {{ + for (int i = 0; i < {sy}; i++) {{ result += v[i] * pow(t, i); }} return result; }} + float control(vec2 pos) {{ + float closest = inf; + for (int i = 0; i < {s}; i++) {{ + float d = distance(pos, vec2(vx[i], vy[i])); + if (d < closest) {{ + closest = d; + }} + }} + return 1 - closest / thr; + }} + float inside(vec2 pos) {{ float res = 100; - float thr = 32; - float closest = 1000000; + float closest = inf; float t = 0.0; - while (t < 1.0) {{ + while (t < 1.0 - 1.0 / res) {{ 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)); + vec2 a = vec2(eval_a(px, t), eval_b(py, t)); + vec2 b = vec2(eval_a(px, step), eval_b(py, 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) {{ @@ -81,13 +91,17 @@ fn compile_bezier_shader(a: Poly, b: Poly) -> GLuint { void main() {{ float r = inside(gl_FragCoord.xy); - FragColor = vec4(r * 0.8, r * 0.2, r, 1.0); + float c = control(gl_FragCoord.xy); + FragColor = vec4(r, c, 0.0, 1.0); }} ", - sa = a.degree() + 1, - sb = b.degree() + 1, - pa = &a, - pb = &b + sx = c.px.degree() + 1, + sy = c.py.degree() + 1, + px = &c.px, + py = &c.py, + s = c.degree, + vx = c.show_x(), + vy = c.show_y(), ) .into_bytes(); @@ -112,8 +126,12 @@ fn compile_bezier_shader(a: Poly, b: Poly) -> GLuint { } fn main() { - let a = Lerp::new(vec![200.0, 500.0, 500.0]).to_poly(); - let b = Lerp::new(vec![200.0, 500.0, 200.0]).to_poly(); + let mut curve = Bezier::new(); + curve.push(200, 200); + curve.push(300, 800); + curve.push(800, 100); + curve.push(1300, 800); + curve.push(1400, 200); let sdl_context = sdl2::init().unwrap(); let video_subsystem = sdl_context.video().unwrap(); @@ -167,7 +185,7 @@ fn main() { gl::EnableVertexAttribArray(0); } - let shader_program = compile_bezier_shader(a, b); + let shader_program = compile_bezier_shader(curve); let mut event_pump = sdl_context.event_pump().unwrap(); 'running: loop { |