Make the float depth compile-time configurable

This commit is contained in:
2020-09-13 22:38:00 -07:00
parent d4334565a7
commit f50dbf7d4e
9 changed files with 175 additions and 133 deletions

View File

@@ -1,10 +1,10 @@
use ansi_term::Color::RGB;
use crate::geom::Point;
use crate::{F64, Material as _, SimSnapshot, SimState};
use crate::{flt, Material as _, SimSnapshot, SimState};
use crate::mat;
use crate::sim::Cell;
use crate::meas::AbstractMeasurement;
use font8x8::{BASIC_FONTS, UnicodeFonts as _};
use font8x8::{BASIC_FONTS, GREEK_FONTS, UnicodeFonts as _};
use image::{RgbImage, Rgb};
use imageproc::{pixelops, drawing};
use std::fs::File;
@@ -14,7 +14,7 @@ use y4m;
/// Accept a value from (-\inf, \inf) and return a value in (-1, 1).
/// If the input is equal to `typical`, it will be mapped to 0.5.
/// If the input is equal to -`typical`, it will be mapped to -0.5.
fn scale_signed(x: f64, typical: f64) -> f64 {
fn scale_signed(x: flt::Pub, typical: flt::Pub) -> flt::Pub {
if x >= 0.0 {
scale_unsigned(x, typical)
} else {
@@ -24,29 +24,29 @@ fn scale_signed(x: f64, typical: f64) -> f64 {
/// Accept a value from [0, \inf) and return a value in [0, 1).
/// If the input is equal to `typical`, it will be mapped to 0.5.
fn scale_unsigned(x: f64, typical: f64) -> f64 {
fn scale_unsigned(x: flt::Pub, typical: flt::Pub) -> flt::Pub {
// f(0) => 0
// f(1) => 0.5
// f(\inf) => 1
// f(x) = 1 - 1/(x+1)
let x = F64::from_inner(x);
let typ = F64::from_inner(typical);
let y = F64::from_inner(1.0) - F64::from_inner(1.0)/(x/typ + 1.0);
let x = flt::Priv::from_inner(x);
let typ = flt::Priv::from_inner(typical);
let y = flt::Priv::from_inner(1.0) - flt::Priv::from_inner(1.0)/(x/typ + 1.0);
y.into()
}
fn scale_signed_to_u8(x: f64, typ: f64) -> u8 {
fn scale_signed_to_u8(x: flt::Pub, typ: flt::Pub) -> u8 {
let norm = 128.0 + 128.0*scale_signed(x, typ);
norm as _
}
fn scale_unsigned_to_u8(x: f64, typ: f64) -> u8 {
fn scale_unsigned_to_u8(x: flt::Pub, typ: flt::Pub) -> u8 {
let norm = 256.0*scale_unsigned(x, typ);
norm as _
}
/// Scale a vector to have magnitude between [0, 1).
fn scale_vector(x: Point, typical_mag: f64) -> Point {
fn scale_vector(x: Point, typical_mag: flt::Pub) -> Point {
let new_mag = scale_unsigned(x.mag(), typical_mag);
x.with_mag(new_mag)
}
@@ -88,7 +88,7 @@ impl<'a> RenderSteps<'a> {
}
}
}
fn render_vector_field<F: Fn(&Cell<mat::Static>) -> Point>(&mut self, color: Rgb<u8>, typical: f64, measure: F) {
fn render_vector_field<F: Fn(&Cell<mat::Static>) -> Point>(&mut self, color: Rgb<u8>, typical: flt::Pub, measure: F) {
let w = self.sim.width();
let h = self.sim.height();
let vec_spacing = 10;
@@ -98,7 +98,7 @@ impl<'a> RenderSteps<'a> {
let vec = self.field_vector(x, y, vec_spacing, &measure);
let norm_vec = scale_vector(vec, typical);
let alpha = 0.7*scale_unsigned(vec.mag_sq(), typical * 5.0);
let vec = norm_vec * (vec_spacing as f64);
let vec = norm_vec * (vec_spacing as flt::Pub);
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, color, alpha as f32);
}
@@ -120,7 +120,9 @@ impl<'a> RenderSteps<'a> {
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();
let glyph = BASIC_FONTS.get(c)
.or_else(|| GREEK_FONTS.get(c))
.unwrap_or_else(|| BASIC_FONTS.get('?').unwrap());
for (y, bmp) in glyph.iter().enumerate() {
for x in 0..8 {
if (bmp & 1 << x) != 0 {
@@ -155,7 +157,7 @@ impl<'a> RenderSteps<'a> {
// avoid division by zero
Point::new(0.0, 0.0)
} else {
field * (1.0 / ((xw*yw) as f64))
field * (1.0 / ((xw*yw) as flt::Pub))
}
}
}