summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
authorJuan Manuel Tomás <jtomas1815@gmail.com>2021-01-17 20:25:58 -0300
committerJuan Manuel Tomás <jtomas1815@gmail.com>2021-01-17 20:25:58 -0300
commit70b5188de306b70cdf8a397dd4e0ee31f07050c8 (patch)
tree3721070393126b79a3658fe8a89f1fa98a84db44 /src/main.rs
parent18efe0d28ebcd936ea50275a351ef1c30253ea1c (diff)
downloadbezier-70b5188de306b70cdf8a397dd4e0ee31f07050c8.tar.gz
bezier-70b5188de306b70cdf8a397dd4e0ee31f07050c8.zip
Fix curve overextending past last control point
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs68
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 {