diff --git a/src/render.rs b/src/render.rs index 878f3ef..d7e077c 100644 --- a/src/render.rs +++ b/src/render.rs @@ -50,66 +50,72 @@ fn scale_vector(x: Point, typical_mag: f64) -> Point { x.with_mag(new_mag) } -struct RenderSteps(RgbImage); +struct RenderSteps<'a> { + im: RgbImage, + sim: &'a SimSnapshot, + meas: &'a [Box], +} -impl RenderSteps { - fn render(state: &SimSnapshot, measurements: &[Box]) -> RgbImage { - let w = state.width(); - let h = state.height(); - let mut me = RenderSteps(RgbImage::new(w, h)); - me.render_b_field(state); - me.render_e_field(state); - me.render_measurements(state, measurements); - me.0 +impl<'a> RenderSteps<'a> { + fn render(state: &'a SimSnapshot, measurements: &'a [Box]) -> RgbImage { + let mut me = Self::new(state, measurements); + me.render_b_field(); + me.render_e_field(); + me.render_measurements(); + me.im } - fn width(&self) -> u32 { - self.0.width() + fn new(sim: &'a SimSnapshot, meas: &'a [Box]) -> Self { + let w = sim.width(); + let h = sim.height(); + RenderSteps { + im: RgbImage::new(w, h), + sim, + meas + } } - fn height(&self) -> u32 { - self.0.height() - } - fn render_b_field(&mut self, state: &SimSnapshot) { - let w = self.width(); - let h = self.height(); + + fn render_b_field(&mut self) { + let w = self.sim.width(); + let h = self.sim.height(); for y in 0..h { for x in 0..w { - let cell = state.get(x, y); + let cell = self.sim.get(x, y); let r = scale_signed_to_u8(cell.mat().mz(), 100.0); let b = scale_unsigned_to_u8(cell.mat().conductivity(), 10.0); let g = scale_signed_to_u8(cell.bz(), 1.0e-4); - self.0.put_pixel(x, y, Rgb([r, g, b])); + self.im.put_pixel(x, y, Rgb([r, g, b])); } } } - fn render_e_field(&mut self, state: &SimSnapshot) { - let w = self.width(); - let h = self.height(); + fn render_e_field(&mut self) { + let w = self.sim.width(); + let h = self.sim.height(); let evec_spacing = 10; for y in 0..h { for x in 0..w { if x % evec_spacing == 0 && y % evec_spacing == 0 { - let evec = self.e_vector(state, x, y, evec_spacing); + let evec = self.e_vector(x, y, evec_spacing); let norm_vec = scale_vector(evec, 100.0); let alpha = scale_unsigned(evec.mag_sq(), 500.0); let vec = norm_vec * (evec_spacing as f64); let center = Point::new(x as _, y as _) + Point::new(evec_spacing as _, evec_spacing as _)*0.5; - self.0.draw_field_arrow(center, vec, Rgb([0xff, 0xff, 0xff]), alpha as f32); + self.im.draw_field_arrow(center, vec, Rgb([0xff, 0xff, 0xff]), alpha as f32); } } } } - fn render_measurements(&mut self, state: &SimSnapshot, measurements: &[Box]) { - for (meas_no, m) in measurements.iter().enumerate() { - let meas_string = m.eval(state); + fn render_measurements(&mut self) { + for (meas_no, m) in self.meas.iter().enumerate() { + let meas_string = m.eval(self.sim); for (i, c) in meas_string.chars().enumerate() { let glyph = BASIC_FONTS.get(c).unwrap(); for (y, bmp) in glyph.iter().enumerate() { for x in 0..8 { if (bmp & 1 << x) != 0 { let real_x = 2 + i as u32*8 + x; - let real_y = y as u32 + self.height() - 10 - meas_no as u32 * 8; - if real_x < self.width() { - self.0.put_pixel(real_x, real_y, Rgb([0, 0, 0])); + let real_y = y as u32 + self.im.height() - 10 - meas_no as u32 * 8; + if real_x < self.im.width() { + self.im.put_pixel(real_x, real_y, Rgb([0, 0, 0])); } } } @@ -118,17 +124,17 @@ impl RenderSteps { } } - fn e_vector(&self, state: &SimSnapshot, xidx: u32, yidx: u32, size: u32) -> Point { + fn e_vector(&self, xidx: u32, yidx: u32, size: u32) -> Point { let mut e = Point::default(); - let w = self.width(); - let h = self.height(); + let w = self.sim.width(); + let h = self.sim.height(); let xstart = xidx.min(w); let ystart = yidx.min(h); let xend = (xstart + size).min(w); let yend = (ystart + size).min(h); for y in ystart..yend { for x in xstart..xend { - e += state.get(x, y).e(); + e += self.sim.get(x, y).e(); } } let xw = xend - xstart;