Convert render system to sample the simulation at a fixed resolution; no more decimation

This commit is contained in:
2020-09-25 19:40:49 -07:00
parent 341acf367d
commit a931252e9c

View File

@@ -60,7 +60,9 @@ struct RenderSteps<'a> {
impl<'a> RenderSteps<'a> { impl<'a> RenderSteps<'a> {
fn render(state: &'a SimSnapshot, measurements: &'a [Box<dyn AbstractMeasurement>]) -> RgbImage { fn render(state: &'a SimSnapshot, measurements: &'a [Box<dyn AbstractMeasurement>]) -> RgbImage {
let mut me = Self::new(state, measurements); let width = 768;
let height = width * state.height() / state.width();
let mut me = Self::new(state, measurements, width, height);
me.render_scalar_field(10.0, false, 2, |cell| cell.mat().conductivity().mag()); me.render_scalar_field(10.0, false, 2, |cell| cell.mat().conductivity().mag());
me.render_scalar_field(100.0, true, 0, |cell| cell.mat().m().mag()); me.render_scalar_field(100.0, true, 0, |cell| cell.mat().m().mag());
if false { if false {
@@ -73,16 +75,20 @@ impl<'a> RenderSteps<'a> {
me.render_measurements(); me.render_measurements();
me.im me.im
} }
fn new(sim: &'a SimSnapshot, meas: &'a [Box<dyn AbstractMeasurement>]) -> Self { fn new(sim: &'a SimSnapshot, meas: &'a [Box<dyn AbstractMeasurement>], width: u32, height: u32) -> Self {
let w = sim.width();
let h = sim.height();
RenderSteps { RenderSteps {
im: RgbImage::new(w, h), im: RgbImage::new(width, height),
sim, sim,
meas meas
} }
} }
fn get_at_px(&self, x_px: u32, y_px: u32) -> &Cell {
let x_sim = x_px * self.sim.width() / self.im.width();
let y_sim = y_px * self.sim.height() / self.im.height();
self.sim.get((x_sim, y_sim).into())
}
////////////// Ex/Ey/Bz configuration //////////// ////////////// Ex/Ey/Bz configuration ////////////
fn render_b_z_field(&mut self) { fn render_b_z_field(&mut self) {
self.render_scalar_field(1.0e-4, true, 1, |cell| cell.b().z()); self.render_scalar_field(1.0e-4, true, 1, |cell| cell.b().z());
@@ -104,8 +110,8 @@ impl<'a> RenderSteps<'a> {
} }
fn render_vector_field<F: Fn(&Cell<mat::Static>) -> Point>(&mut self, color: Rgb<u8>, typical: Flt, measure: F) { fn render_vector_field<F: Fn(&Cell<mat::Static>) -> Point>(&mut self, color: Rgb<u8>, typical: Flt, measure: F) {
let w = self.sim.width(); let w = self.im.width();
let h = self.sim.height(); let h = self.im.height();
let vec_spacing = 10; let vec_spacing = 10;
for y in 0..h { for y in 0..h {
for x in 0..w { for x in 0..w {
@@ -121,11 +127,11 @@ impl<'a> RenderSteps<'a> {
} }
} }
fn render_scalar_field<F: Fn(&Cell<mat::Static>) -> Flt>(&mut self, typical: Flt, signed: bool, slot: u32, measure: F) { fn render_scalar_field<F: Fn(&Cell<mat::Static>) -> Flt>(&mut self, typical: Flt, signed: bool, slot: u32, measure: F) {
let w = self.sim.width(); let w = self.im.width();
let h = self.sim.height(); let h = self.im.height();
for y in 0..h { for y in 0..h {
for x in 0..w { for x in 0..w {
let cell = self.sim.get((x, y).into()); let cell = self.get_at_px(x, y);
let value = measure(cell); let value = measure(cell);
let scaled = if signed { let scaled = if signed {
scale_signed_to_u8(value, typical) scale_signed_to_u8(value, typical)
@@ -162,15 +168,15 @@ impl<'a> RenderSteps<'a> {
fn field_vector<F: Fn(&Cell<mat::Static>) -> Point>(&self, xidx: u32, yidx: u32, size: u32, measure: &F) -> Point { fn field_vector<F: Fn(&Cell<mat::Static>) -> Point>(&self, xidx: u32, yidx: u32, size: u32, measure: &F) -> Point {
let mut field = Point::default(); let mut field = Point::default();
let w = self.sim.width(); let w = self.im.width();
let h = self.sim.height(); let h = self.im.height();
let xstart = xidx.min(w); let xstart = xidx.min(w);
let ystart = yidx.min(h); let ystart = yidx.min(h);
let xend = (xstart + size).min(w); let xend = (xstart + size).min(w);
let yend = (ystart + size).min(h); let yend = (ystart + size).min(h);
for y in ystart..yend { for y in ystart..yend {
for x in xstart..xend { for x in xstart..xend {
field += measure(self.sim.get((x, y).into())); field += measure(self.get_at_px(x, y));
} }
} }
let xw = xend - xstart; let xw = xend - xstart;
@@ -211,25 +217,25 @@ pub trait Renderer {
} }
} }
pub struct NumericTermRenderer; // pub struct NumericTermRenderer;
//
impl Renderer for NumericTermRenderer { // impl Renderer for NumericTermRenderer {
fn render(&mut self, state: &SimSnapshot, _measurements: &[Box<dyn AbstractMeasurement>]) { // fn render(&mut self, state: &SimSnapshot, _measurements: &[Box<dyn AbstractMeasurement>]) {
for y in 0..state.height() { // for y in 0..state.height() {
for x in 0..state.width() { // for x in 0..state.width() {
let cell = state.get((x, y).into()); // let cell = state.get((x, y).into());
print!(" {:>10.1e}", cell.ex()); // print!(" {:>10.1e}", cell.ex());
} // }
print!("\n"); // print!("\n");
for x in 0..state.width() { // for x in 0..state.width() {
let cell = state.get((x, y).into()); // let cell = state.get((x, y).into());
print!("{:>10.1e} {:>10.1e}", cell.ey(), cell.bz()); // print!("{:>10.1e} {:>10.1e}", cell.ey(), cell.bz());
} // }
print!("\n"); // print!("\n");
} // }
print!("\n"); // print!("\n");
} // }
} // }
pub struct ColorTermRenderer; pub struct ColorTermRenderer;
@@ -316,16 +322,7 @@ impl MultiRenderer {
} }
pub fn render(&mut self, state: &SimState, measurements: &[Box<dyn AbstractMeasurement>]) { pub fn render(&mut self, state: &SimState, measurements: &[Box<dyn AbstractMeasurement>]) {
let max_width = 1980; //< TODO: make configurable Renderer::render(self, &state.snapshot(1), measurements);
//let max_width = 100;
if state.width() > max_width {
let dec = (state.width() + max_width - 1) / max_width;
let snap = state.snapshot(dec);
// XXX: measurements are messed up by rescaling
Renderer::render(self, &snap, &[]);
} else {
Renderer::render(self, &state.snapshot(1), measurements);
}
} }
} }