diff --git a/src/bin/flat.rs b/src/bin/flat.rs index 1b9c7c3..46a11df 100644 --- a/src/bin/flat.rs +++ b/src/bin/flat.rs @@ -30,37 +30,7 @@ pub fn main() { Box::new(Inside { space: space.clone() }), ]; - gc.new_path(); - let dt = 1.0; - let mut s = boundary::Id(0); - let mut p = vec2(-500.0, 0.0); - let mut v = vec2(3.0, 1.0).normalize(); - let part = &*parts[s.0 as usize]; - gc.stroke_color(part.color()); - gc.move_to(p.x, p.y); - for _ in 0..10000 { - let part = &*parts[s.0 as usize]; - let a: Vec2 = -riemann::convolute(riemann::krist(part, p), v); - v = v + a * dt; - if let Some((id, base, dir)) = part.next(p, v, dt) { - gc.stroke(); - gc.new_path(); - let pt = part.globalize_loc(p); - gc.move_to(pt.x, pt.y); - s = id; - p = base; - v = dir; - let part = &*parts[s.0 as usize]; - let pt = part.globalize_loc(p); - gc.stroke_color(part.color()); - gc.line_to(pt.x, pt.y); - } else { - p = p + v * dt; - let pt = part.globalize_loc(p); - gc.line_to(pt.x, pt.y); - } - } - gc.stroke(); + parts.draw_fan(gc, vec2(-500.0, 0.0), vec2(1.0, 0.0), 1.0); }); }); } @@ -104,24 +74,66 @@ impl SpaceVisual for Inside { } } -fn draw_ray(gc: &mut Vec, space: &impl Metric, base: Vec2, dir: Vec2) { - let dir = space.globalize(base, dir); - gc.new_path(); - gc.move_to(base.x, base.y); - for pt in trace_iter(space, base, dir, 1.0).take(10000) { - gc.line_to(pt.x, pt.y); - if pt.abs().cmpgt(Vec2::splat(1000.0)).any() { - break; +impl Rayable for [Box] { + fn draw_ray(&self, gc: &mut Vec, base: Vec2, dir: Vec2) { + gc.new_path(); + let dt = 1.0; + let mut s = boundary::Id(0); + let mut p = base; + let mut v = dir.normalize(); + let part = &*self[s.0 as usize]; + gc.stroke_color(part.color()); + gc.move_to(p.x, p.y); + for _ in 0..10000 { + let part = &*self[s.0 as usize]; + let a: Vec2 = -riemann::convolute(riemann::krist(part, p), v); + v = v + a * dt; + if let Some((id, base, dir)) = part.next(p, v, dt) { + gc.stroke(); + gc.new_path(); + let pt = part.globalize_loc(p); + gc.move_to(pt.x, pt.y); + s = id; + p = base; + v = dir; + let part = &*self[s.0 as usize]; + let pt = part.globalize_loc(p); + gc.stroke_color(part.color()); + gc.line_to(pt.x, pt.y); + } else { + p = p + v * dt; + let pt = part.globalize_loc(p); + gc.line_to(pt.x, pt.y); + } } + gc.stroke(); } - gc.stroke(); } -fn draw_fan(gc: &mut Vec, space: &impl Metric, base: Vec2, dir: Vec2, spread: f32) { - let dir = dir.normalize(); - let v = vec2(-dir.y, dir.x); - for y in itertools_num::linspace(-spread, spread, 101) { - draw_ray(gc, space, base, dir + y * v); +trait Rayable { + fn draw_ray(&self, gc: &mut Vec, base: Vec2, dir: Vec2); + + fn draw_fan(&self, gc: &mut Vec, base: Vec2, dir: Vec2, spread: f32) { + let dir = dir.normalize(); + let v = vec2(-dir.y, dir.x); + for y in itertools_num::linspace(-spread, spread, 101) { + self.draw_ray(gc, base, dir + y * v); + } + } +} + +impl Rayable for T { + fn draw_ray(&self, gc: &mut Vec, base: Vec2, dir: Vec2) { + let dir = self.globalize(base, dir); + gc.new_path(); + gc.move_to(base.x, base.y); + for pt in trace_iter(self, base, dir, 1.0).take(10000) { + gc.line_to(pt.x, pt.y); + if pt.abs().cmpgt(Vec2::splat(1000.0)).any() { + break; + } + } + gc.stroke(); } } @@ -141,9 +153,9 @@ impl Renderable for Coil { gc.fill(); gc.line_width(0.5); gc.stroke_color(Color::Rgba(1.0, 0.5, 0.0, 1.0)); - draw_fan(gc, self, vec2(-500.0, 0.0), vec2(1.0, 0.0), 1.0); + self.draw_fan(gc, vec2(-500.0, 0.0), vec2(1.0, 0.0), 1.0); gc.stroke_color(Color::Rgba(0.0, 0.5, 1.0, 1.0)); - draw_fan(gc, self, vec2(0.0, self.r), vec2(1.0, 0.0), 1.0); + self.draw_fan(gc, vec2(0.0, self.r), vec2(1.0, 0.0), 1.0); } } @@ -157,9 +169,9 @@ impl Renderable for Rect { gc.fill(); gc.line_width(0.5); gc.stroke_color(Color::Rgba(1.0, 0.5, 0.0, 1.0)); - draw_fan(gc, self, vec2(-500.0, 0.0), vec2(1.0, 0.0), 1.0); + self.draw_fan(gc, vec2(-500.0, 0.0), vec2(1.0, 0.0), 1.0); gc.stroke_color(Color::Rgba(0.0, 0.5, 1.0, 1.0)); - draw_fan(gc, self, vec2(0.0, -0.5 * self.r.y), vec2(1.0, 1.0), 1.0); + self.draw_fan(gc, vec2(0.0, -0.5 * self.r.y), vec2(1.0, 1.0), 1.0); } }