Make vector field rendering logic generic
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
use ansi_term::Color::RGB;
|
use ansi_term::Color::RGB;
|
||||||
use crate::geom::Point;
|
use crate::geom::Point;
|
||||||
use crate::{Material as _, SimSnapshot, SimState};
|
use crate::{Material as _, SimSnapshot, SimState};
|
||||||
|
use crate::mat;
|
||||||
|
use crate::sim::Cell;
|
||||||
use crate::meas::AbstractMeasurement;
|
use crate::meas::AbstractMeasurement;
|
||||||
use decorum::R64;
|
use decorum::R64;
|
||||||
use font8x8::{BASIC_FONTS, UnicodeFonts as _};
|
use font8x8::{BASIC_FONTS, UnicodeFonts as _};
|
||||||
@@ -87,23 +89,26 @@ impl<'a> RenderSteps<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn render_e_field(&mut self) {
|
fn render_vector_field<F: Fn(&Cell<mat::Static>) -> Point>(&mut self, color: Rgb<u8>, measure: F) {
|
||||||
let w = self.sim.width();
|
let w = self.sim.width();
|
||||||
let h = self.sim.height();
|
let h = self.sim.height();
|
||||||
let evec_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 {
|
||||||
if x % evec_spacing == 0 && y % evec_spacing == 0 {
|
if x % vec_spacing == 0 && y % vec_spacing == 0 {
|
||||||
let evec = self.e_vector(x, y, evec_spacing);
|
let vec = self.field_vector(x, y, vec_spacing, &measure);
|
||||||
let norm_vec = scale_vector(evec, 100.0);
|
let norm_vec = scale_vector(vec, 100.0);
|
||||||
let alpha = scale_unsigned(evec.mag_sq(), 500.0);
|
let alpha = scale_unsigned(vec.mag_sq(), 500.0);
|
||||||
let vec = norm_vec * (evec_spacing as f64);
|
let vec = norm_vec * (vec_spacing as f64);
|
||||||
let center = Point::new(x as _, y as _) + Point::new(evec_spacing as _, evec_spacing as _)*0.5;
|
let center = Point::new(x as _, y as _) + Point::new(vec_spacing as _, vec_spacing as _)*0.5;
|
||||||
self.im.draw_field_arrow(center, vec, Rgb([0xff, 0xff, 0xff]), alpha as f32);
|
self.im.draw_field_arrow(center, vec, color, alpha as f32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn render_e_field(&mut self) {
|
||||||
|
self.render_vector_field(Rgb([0xff, 0xff, 0xff]), |cell| cell.e());
|
||||||
|
}
|
||||||
fn render_measurements(&mut self) {
|
fn render_measurements(&mut self) {
|
||||||
for (meas_no, m) in self.meas.iter().enumerate() {
|
for (meas_no, m) in self.meas.iter().enumerate() {
|
||||||
let meas_string = m.eval(self.sim);
|
let meas_string = m.eval(self.sim);
|
||||||
@@ -124,8 +129,8 @@ impl<'a> RenderSteps<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn e_vector(&self, xidx: u32, yidx: u32, size: u32) -> Point {
|
fn field_vector<F: Fn(&Cell<mat::Static>) -> Point>(&self, xidx: u32, yidx: u32, size: u32, measure: &F) -> Point {
|
||||||
let mut e = Point::default();
|
let mut field = Point::default();
|
||||||
let w = self.sim.width();
|
let w = self.sim.width();
|
||||||
let h = self.sim.height();
|
let h = self.sim.height();
|
||||||
let xstart = xidx.min(w);
|
let xstart = xidx.min(w);
|
||||||
@@ -134,7 +139,7 @@ impl<'a> RenderSteps<'a> {
|
|||||||
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 {
|
||||||
e += self.sim.get(x, y).e();
|
field += measure(self.sim.get(x, y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let xw = xend - xstart;
|
let xw = xend - xstart;
|
||||||
@@ -143,7 +148,7 @@ impl<'a> RenderSteps<'a> {
|
|||||||
// avoid division by zero
|
// avoid division by zero
|
||||||
Point::new(0.0, 0.0)
|
Point::new(0.0, 0.0)
|
||||||
} else {
|
} else {
|
||||||
e * (1.0 / ((xw*yw) as f64))
|
field * (1.0 / ((xw*yw) as f64))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user