Fix rendering to render (Bx,By,Ez). Also fix an infinite loop due to rounding errors in MHCurve

This commit is contained in:
2020-09-18 22:22:54 -07:00
parent 8a70276c78
commit 1d303df409
6 changed files with 116 additions and 34 deletions

View File

@@ -5,6 +5,7 @@ use crate::mat;
use crate::sim::Cell;
use crate::meas::AbstractMeasurement;
use font8x8::{BASIC_FONTS, GREEK_FONTS, UnicodeFonts as _};
use log::trace;
use image::{RgbImage, Rgb};
use imageproc::{pixelops, drawing};
use std::fs::File;
@@ -60,8 +61,15 @@ struct RenderSteps<'a> {
impl<'a> RenderSteps<'a> {
fn render(state: &'a SimSnapshot, measurements: &'a [Box<dyn AbstractMeasurement>]) -> RgbImage {
let mut me = Self::new(state, measurements);
me.render_b_field();
me.render_e_field();
me.render_scalar_field(10.0, false, 2, |cell| cell.mat().conductivity());
me.render_scalar_field(100.0, true, 0, |cell| cell.mat().m().mag());
if false {
me.render_b_z_field();
me.render_e_xy_field();
} else {
me.render_e_z_field();
me.render_b_xy_field();
}
me.render_measurements();
me.im
}
@@ -75,19 +83,26 @@ impl<'a> RenderSteps<'a> {
}
}
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 = self.sim.get(x, y);
let r = scale_signed_to_u8(cell.mat().m().z(), 100.0);
let b = scale_unsigned_to_u8(cell.mat().conductivity(), 10.0);
let g = scale_signed_to_u8(cell.b().z(), 1.0e-4);
self.im.put_pixel(x, y, Rgb([r, g, b]));
}
}
////////////// Ex/Ey/Bz configuration ////////////
fn render_b_z_field(&mut self) {
self.render_scalar_field(1.0e-4, true, 1, |cell| cell.b().z());
}
fn render_e_xy_field(&mut self) {
self.render_vector_field(Rgb([0xff, 0xff, 0xff]), 100.0, |cell| cell.e().xy());
// current
self.render_vector_field(Rgb([0x00, 0xa0, 0x30]), 1.0e-12, |cell| {
cell.e().xy()*cell.mat().conductivity()
});
}
////////////// Bx/By/Ez configuration ////////////
fn render_e_z_field(&mut self) {
self.render_scalar_field(100.0, true, 1, |cell| cell.e().z());
}
fn render_b_xy_field(&mut self) {
self.render_vector_field(Rgb([0xff, 0xff, 0xff]), 1.0e-4, |cell| cell.b().xy());
}
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 h = self.sim.height();
@@ -105,16 +120,23 @@ impl<'a> RenderSteps<'a> {
}
}
}
fn render_e_field(&mut self) {
self.render_vector_field(Rgb([0xff, 0xff, 0xff]), 100.0, |cell| cell.e().xy());
// current
self.render_vector_field(Rgb([0x00, 0xa0, 0x30]), 1.0e-12, |cell| {
//if cell.mat().conductivity() >= 1.0e3 {
cell.e().xy()*cell.mat().conductivity()
//} else {
// Default::default()
//}
});
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 h = self.sim.height();
for y in 0..h {
for x in 0..w {
let cell = self.sim.get(x, y);
let value = measure(cell);
let scaled = if signed {
scale_signed_to_u8(value, typical)
} else {
scale_unsigned_to_u8(value, typical)
};
let mut p = *self.im.get_pixel(x, y);
p.0[slot as usize] = scaled;
self.im.put_pixel(x, y, p);
}
}
}
fn render_measurements(&mut self) {
for (meas_no, m) in self.meas.iter().enumerate() {
@@ -269,7 +291,10 @@ impl Renderer for Y4MRenderer {
let frame = y4m::Frame::new([&*pix_y, &*pix_u, &*pix_v], None);
let enc = self.encoder.as_mut().unwrap();
enc.write_frame(&frame).unwrap()
trace!("write_frame begin");
let ret = enc.write_frame(&frame).unwrap();
trace!("write_frame end");
ret
}
}