Split the metric into two functions
This commit is contained in:
parent
08fbff38fa
commit
4e6c3b19ae
|
|
@ -543,16 +543,46 @@ struct Rect {
|
|||
}
|
||||
|
||||
impl Rect {
|
||||
fn γ(&self) -> f32 { self.external_halflength / self.internal_halflength }
|
||||
fn a(&self) -> f32 { -(self.γ() - 1.0) / self.internal_halflength }
|
||||
fn b(&self) -> f32 { 2.0 * self.γ() - 1.0 }
|
||||
fn fx(&self) -> fns::RectX { fns::RectX { min: self.inner_radius, max: self.outer_radius } }
|
||||
fn fy(&self) -> fns::RectY { fns::RectY { internal: self.internal_halflength, external: self.external_halflength } }
|
||||
|
||||
fn root(&self, x: f32) -> f32 { (self.b().powi(2) + 4.0 * self.a() * x).sqrt() }
|
||||
fn d(&self, u: f32) -> f32 { 2.0 * self.a() * u + self.b() }
|
||||
pub fn x(&self, u: f32) -> f32 { (self.a() * u.abs() + self.b()) * u }
|
||||
pub fn u(&self, x: f32) -> f32 { 0.5 * x.signum() * (-self.b() + self.root(x.abs())) / self.a() }
|
||||
pub fn dx(&self, u: f32, du: f32) -> f32 { du * self.d(u.abs()) }
|
||||
pub fn du(&self, x: f32, dx: f32) -> f32 { dx / self.root(x.abs()) }
|
||||
pub fn x(&self, u: f32) -> f32 { self.fy().x(u) }
|
||||
pub fn u(&self, x: f32) -> f32 { self.fy().u(x) }
|
||||
pub fn dx(&self, u: f32, du: f32) -> f32 { self.fy().dx(u, du) }
|
||||
pub fn du(&self, x: f32, dx: f32) -> f32 { self.fy().du(x, dx) }
|
||||
}
|
||||
|
||||
mod fns {
|
||||
pub struct RectX {
|
||||
pub min: f32,
|
||||
pub max: f32,
|
||||
}
|
||||
|
||||
impl RectX {
|
||||
pub fn value(&self, x: f32) -> f32 { ((x.abs() - self.min) / (self.max - self.min)).clamp(0.0, 1.0) }
|
||||
pub fn derivative(&self, x: f32) -> f32 { if x.abs() > self.min && x.abs() < self.max { x.signum() / (self.max - self.min) } else { 0.0 } }
|
||||
}
|
||||
|
||||
pub struct RectY {
|
||||
pub internal: f32,
|
||||
pub external: f32,
|
||||
}
|
||||
|
||||
impl RectY {
|
||||
fn γ(&self) -> f32 { self.external / self.internal }
|
||||
fn a(&self) -> f32 { -(self.γ() - 1.0) / self.internal }
|
||||
fn b(&self) -> f32 { 2.0 * self.γ() - 1.0 }
|
||||
|
||||
fn root(&self, x: f32) -> f32 { (self.b().powi(2) + 4.0 * self.a() * x).sqrt() }
|
||||
fn d(&self, u: f32) -> f32 { 2.0 * self.a() * u + self.b() }
|
||||
pub fn x(&self, u: f32) -> f32 { (self.a() * u.abs() + self.b()) * u }
|
||||
pub fn u(&self, x: f32) -> f32 { 0.5 * x.signum() * (-self.b() + self.root(x.abs())) / self.a() }
|
||||
pub fn dx(&self, u: f32, du: f32) -> f32 { du * self.d(u.abs()) }
|
||||
pub fn du(&self, x: f32, dx: f32) -> f32 { dx / self.root(x.abs()) }
|
||||
|
||||
pub fn value(&self, x: f32) -> f32 { if x.abs() <= self.external { 1.0 / self.root(x.abs()) } else { 1.0 } }
|
||||
pub fn derivative(&self, x: f32) -> f32 { if x.abs() <= self.external { -2.0 * x.signum() * self.a() * self.root(x.abs()).powi(-3) } else { 0.0 } }
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -606,9 +636,8 @@ impl FloatExt2 for (f32, f32) {
|
|||
|
||||
impl Metric for Rect {
|
||||
fn sqrt_at(&self, pos: Vec2) -> Decomp2 {
|
||||
let y = pos.y.abs();
|
||||
let sx = ((pos.x.abs() - self.inner_radius) / (self.outer_radius - self.inner_radius)).clamp(0.0, 1.0);
|
||||
let sy = if y <= self.external_halflength { 1.0 / self.root(y) } else { 1.0 };
|
||||
let sx = self.fx().value(pos.x);
|
||||
let sy = self.fy().value(pos.y);
|
||||
assert!(sx.is_finite());
|
||||
assert!(sy.is_finite());
|
||||
assert!(sy > 0.0);
|
||||
|
|
@ -619,13 +648,11 @@ impl Metric for Rect {
|
|||
}
|
||||
|
||||
fn part_derivs_at(&self, pos: Vec2) -> Tens2 {
|
||||
let x = pos.x.abs();
|
||||
let y = pos.y.abs();
|
||||
let sx = ((x - self.inner_radius) / (self.outer_radius - self.inner_radius)).clamp(0.0, 1.0);
|
||||
let sy = if y <= self.external_halflength { 1.0 / self.root(y) } else { 1.0 };
|
||||
let sx = self.fx().value(pos.x);
|
||||
let sy = self.fy().value(pos.y);
|
||||
let s = (sy, 1.0).lerp(sx);
|
||||
let dsx_dx = if x > self.inner_radius && x < self.outer_radius { pos.x.signum() / (self.outer_radius - self.inner_radius) } else { 0.0 };
|
||||
let dsy_dy = if y <= self.external_halflength { -2.0 * pos.y.signum() * self.a() * sy.powi(3) } else { 0.0 };
|
||||
let dsx_dx = self.fx().derivative(pos.x);
|
||||
let dsy_dy = self.fy().derivative(pos.y);
|
||||
let ds2_dx = 2.0 * s * (1.0 - sy) * dsx_dx;
|
||||
let ds2_dy = 2.0 * s * (1.0 - sx) * dsy_dy;
|
||||
[
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user