The Big Rename
This commit is contained in:
parent
ae152f6d7d
commit
53075e0906
|
|
@ -29,7 +29,7 @@ pub fn main() {
|
||||||
with_2d_graphics(move || {
|
with_2d_graphics(move || {
|
||||||
let canvas = create_drawing_window("Refraction");
|
let canvas = create_drawing_window("Refraction");
|
||||||
canvas.draw(|gc| {
|
canvas.draw(|gc| {
|
||||||
let tube = Rect {
|
let tube = Tube {
|
||||||
inner_radius: 30.0,
|
inner_radius: 30.0,
|
||||||
outer_radius: 50.0,
|
outer_radius: 50.0,
|
||||||
internal_halflength: 100.0,
|
internal_halflength: 100.0,
|
||||||
|
|
@ -53,7 +53,7 @@ pub fn main() {
|
||||||
r: 20.0,
|
r: 20.0,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let space = Space { rect: tube, objs };
|
let space = Space { tube, objs };
|
||||||
|
|
||||||
gc.canvas_height(500.0);
|
gc.canvas_height(500.0);
|
||||||
gc.transform(Transform2D::rotate(FRAC_PI_2));
|
gc.transform(Transform2D::rotate(FRAC_PI_2));
|
||||||
|
|
@ -118,7 +118,7 @@ struct Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Space {
|
struct Space {
|
||||||
rect: Rect,
|
tube: Tube,
|
||||||
objs: Vec<Object>,
|
objs: Vec<Object>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -143,11 +143,11 @@ struct FlatTraceResult {
|
||||||
|
|
||||||
impl Space {
|
impl Space {
|
||||||
fn which_subspace(&self, pt: Vec2) -> Subspace {
|
fn which_subspace(&self, pt: Vec2) -> Subspace {
|
||||||
if pt.y.abs() > self.rect.external_halflength {
|
if pt.y.abs() > self.tube.external_halflength {
|
||||||
Outer
|
Outer
|
||||||
} else if pt.x.abs() > self.rect.outer_radius {
|
} else if pt.x.abs() > self.tube.outer_radius {
|
||||||
Outer
|
Outer
|
||||||
} else if pt.x.abs() > self.rect.inner_radius {
|
} else if pt.x.abs() > self.tube.inner_radius {
|
||||||
Boundary
|
Boundary
|
||||||
} else {
|
} else {
|
||||||
Inner
|
Inner
|
||||||
|
|
@ -155,17 +155,17 @@ impl Space {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flat_to_global(&self, at: Vec2) -> Mat2 {
|
fn flat_to_global(&self, at: Vec2) -> Mat2 {
|
||||||
Mat2::from(self.rect.sqrt_at(at).inverse())
|
Mat2::from(self.tube.sqrt_at(at).inverse())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn global_to_flat(&self, at: Vec2) -> Mat2 {
|
fn global_to_flat(&self, at: Vec2) -> Mat2 {
|
||||||
Mat2::from(self.rect.sqrt_at(at))
|
Mat2::from(self.tube.sqrt_at(at))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Выполняет один шаг трассировки. Работает в любой части пространства, но вне Boundary доступны более эффективные методы.
|
/// Выполняет один шаг трассировки. Работает в любой части пространства, но вне Boundary доступны более эффективные методы.
|
||||||
/// ray задаётся в основной СК.
|
/// ray задаётся в основной СК.
|
||||||
fn trace_step(&self, ray: Ray) -> Ray {
|
fn trace_step(&self, ray: Ray) -> Ray {
|
||||||
let a: Vec2 = -riemann::contract2(riemann::krist(&self.rect, ray.pos), ray.dir);
|
let a: Vec2 = -riemann::contract2(riemann::krist(&self.tube, ray.pos), ray.dir);
|
||||||
let v = ray.dir + a;
|
let v = ray.dir + a;
|
||||||
let p = ray.pos + v;
|
let p = ray.pos + v;
|
||||||
Ray { pos: p, dir: v }
|
Ray { pos: p, dir: v }
|
||||||
|
|
@ -174,7 +174,7 @@ impl Space {
|
||||||
/// Выполняет один шаг перемещения. Работает в любой части пространства.
|
/// Выполняет один шаг перемещения. Работает в любой части пространства.
|
||||||
/// off задаётся в локальной СК. Рекомендуется считать небольшими шагами.
|
/// off задаётся в локальной СК. Рекомендуется считать небольшими шагами.
|
||||||
fn move_step(&self, loc: Location, off: Vec2) -> Location {
|
fn move_step(&self, loc: Location, off: Vec2) -> Location {
|
||||||
let corr = Mat2::IDENTITY - riemann::contract(riemann::krist(&self.rect, loc.pos), loc.rot * off);
|
let corr = Mat2::IDENTITY - riemann::contract(riemann::krist(&self.tube, loc.pos), loc.rot * off);
|
||||||
let p = loc.pos + corr * loc.rot * off;
|
let p = loc.pos + corr * loc.rot * off;
|
||||||
Location { pos: p, rot: corr * loc.rot }
|
Location { pos: p, rot: corr * loc.rot }
|
||||||
}
|
}
|
||||||
|
|
@ -185,7 +185,7 @@ impl Space {
|
||||||
|
|
||||||
fn trace_inner(&self, ray: Ray) -> FlatTraceResult {
|
fn trace_inner(&self, ray: Ray) -> FlatTraceResult {
|
||||||
assert_eq!(self.which_subspace(ray.pos), Inner);
|
assert_eq!(self.which_subspace(ray.pos), Inner);
|
||||||
let cell = RectInside { rect: self.rect };
|
let cell = TubeInside { tube: self.tube };
|
||||||
let ray = cell.ray_to_local(ray);
|
let ray = cell.ray_to_local(ray);
|
||||||
let objs = self.list_objects_inner();
|
let objs = self.list_objects_inner();
|
||||||
let dist = cell.to_boundary(ray).expect("Can't get outta here!");
|
let dist = cell.to_boundary(ray).expect("Can't get outta here!");
|
||||||
|
|
@ -197,7 +197,7 @@ impl Space {
|
||||||
|
|
||||||
fn trace_outer(&self, ray: Ray) -> FlatTraceResult {
|
fn trace_outer(&self, ray: Ray) -> FlatTraceResult {
|
||||||
assert_eq!(self.which_subspace(ray.pos), Outer);
|
assert_eq!(self.which_subspace(ray.pos), Outer);
|
||||||
let cell = basic_shapes::Rect { size: vec2(self.rect.outer_radius, self.rect.external_halflength) };
|
let cell = basic_shapes::Rect { size: vec2(self.tube.outer_radius, self.tube.external_halflength) };
|
||||||
let objs = self.list_objects_outer();
|
let objs = self.list_objects_outer();
|
||||||
let lim = cell.trace_into(ray);
|
let lim = cell.trace_into(ray);
|
||||||
let dist = lim.unwrap_or(f32::INFINITY);
|
let dist = lim.unwrap_or(f32::INFINITY);
|
||||||
|
|
@ -224,8 +224,8 @@ impl Space {
|
||||||
Outer => loc,
|
Outer => loc,
|
||||||
Inner => {
|
Inner => {
|
||||||
let Vec2 { x, y } = loc.pos; // в основной СК
|
let Vec2 { x, y } = loc.pos; // в основной СК
|
||||||
let y = self.rect.u(y) + y.signum() * (self.rect.external_halflength - self.rect.internal_halflength);
|
let y = self.tube.u(y) + y.signum() * (self.tube.external_halflength - self.tube.internal_halflength);
|
||||||
let m = Mat2::from_cols_array(&[1., 0., 0., self.rect.du(y)]);
|
let m = Mat2::from_cols_array(&[1., 0., 0., self.tube.du(y)]);
|
||||||
Location {
|
Location {
|
||||||
pos: vec2(x, y), // в плоском продолжении СК Outer на область Inner
|
pos: vec2(x, y), // в плоском продолжении СК Outer на область Inner
|
||||||
rot: m * loc.rot,
|
rot: m * loc.rot,
|
||||||
|
|
@ -240,9 +240,9 @@ impl Space {
|
||||||
match self.which_subspace(pos) {
|
match self.which_subspace(pos) {
|
||||||
Inner | Outer => {
|
Inner | Outer => {
|
||||||
// NB: не работает для частей Outer с |y| < external_halflength. Но они и не нужны.
|
// NB: не работает для частей Outer с |y| < external_halflength. Но они и не нужны.
|
||||||
let m = Mat2::from_cols_array(&[1., 0., 0., self.rect.du(pos.y)]);
|
let m = Mat2::from_cols_array(&[1., 0., 0., self.tube.du(pos.y)]);
|
||||||
Location {
|
Location {
|
||||||
pos: vec2(pos.x, self.rect.u(pos.y)), // в плоской СК для Inner или её продолжении на Outer
|
pos: vec2(pos.x, self.tube.u(pos.y)), // в плоской СК для Inner или её продолжении на Outer
|
||||||
rot: m * rot,
|
rot: m * rot,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -275,7 +275,7 @@ impl Space {
|
||||||
match self.which_subspace(a) {
|
match self.which_subspace(a) {
|
||||||
Outer => vec![b],
|
Outer => vec![b],
|
||||||
Inner => {
|
Inner => {
|
||||||
let cell = RectInside { rect: self.rect };
|
let cell = TubeInside { tube: self.tube };
|
||||||
let n = ((b - a).length() / step) as usize + 1;
|
let n = ((b - a).length() / step) as usize + 1;
|
||||||
let a = cell.pos_to_local(a);
|
let a = cell.pos_to_local(a);
|
||||||
let b = cell.pos_to_local(b);
|
let b = cell.pos_to_local(b);
|
||||||
|
|
@ -288,10 +288,10 @@ impl Space {
|
||||||
|
|
||||||
fn draw_ray_2(gc: &mut Vec<Draw>, space: &Space, base: Vec2, dir: Vec2) {
|
fn draw_ray_2(gc: &mut Vec<Draw>, space: &Space, base: Vec2, dir: Vec2) {
|
||||||
let mut hits = Vec::<Draw>::new();
|
let mut hits = Vec::<Draw>::new();
|
||||||
let dir = space.rect.globalize(base, dir);
|
let dir = space.tube.globalize(base, dir);
|
||||||
gc.new_path();
|
gc.new_path();
|
||||||
gc.move_to(base.x, base.y);
|
gc.move_to(base.x, base.y);
|
||||||
let mut ray = Ray { pos: base, dir: space.rect.normalize_vec_at(base, dir) * DT };
|
let mut ray = Ray { pos: base, dir: space.tube.normalize_vec_at(base, dir) * DT };
|
||||||
for _ in 0..10000 {
|
for _ in 0..10000 {
|
||||||
ray = space.trace_step(ray);
|
ray = space.trace_step(ray);
|
||||||
gc.line_to(ray.pos.x, ray.pos.y);
|
gc.line_to(ray.pos.x, ray.pos.y);
|
||||||
|
|
@ -315,7 +315,7 @@ fn draw_ray_2(gc: &mut Vec<Draw>, space: &Space, base: Vec2, dir: Vec2) {
|
||||||
for hit in ret.objects {
|
for hit in ret.objects {
|
||||||
let obj = space.objs[hit.id as usize];
|
let obj = space.objs[hit.id as usize];
|
||||||
hits.move_to(obj.loc.pos.x, obj.loc.pos.y);
|
hits.move_to(obj.loc.pos.x, obj.loc.pos.y);
|
||||||
for pt in trace_iter(&space.rect, obj.loc.pos, obj.loc.rot * hit.rel.pos, hit.rel.pos.length() / 100.0).take(100) {
|
for pt in trace_iter(&space.tube, obj.loc.pos, obj.loc.rot * hit.rel.pos, hit.rel.pos.length() / 100.0).take(100) {
|
||||||
hits.line_to(pt.x, pt.y);
|
hits.line_to(pt.x, pt.y);
|
||||||
}
|
}
|
||||||
hits.circle(hit.pos.x, hit.pos.y, 1.5);
|
hits.circle(hit.pos.x, hit.pos.y, 1.5);
|
||||||
|
|
@ -324,7 +324,7 @@ fn draw_ray_2(gc: &mut Vec<Draw>, space: &Space, base: Vec2, dir: Vec2) {
|
||||||
assert!(diff >= 0.0);
|
assert!(diff >= 0.0);
|
||||||
let t = (-rel.dot(dir) + diff.sqrt()) / dir.length_squared();
|
let t = (-rel.dot(dir) + diff.sqrt()) / dir.length_squared();
|
||||||
let rel2 = hit.rel.forward(t).pos;
|
let rel2 = hit.rel.forward(t).pos;
|
||||||
let pos2 = trace_iter(&space.rect, obj.loc.pos, obj.loc.rot * rel2, rel2.length() / 100.0).nth(100).unwrap();
|
let pos2 = trace_iter(&space.tube, obj.loc.pos, obj.loc.rot * rel2, rel2.length() / 100.0).nth(100).unwrap();
|
||||||
hits.move_to(pos2.x - 1.0, pos2.y - 1.0);
|
hits.move_to(pos2.x - 1.0, pos2.y - 1.0);
|
||||||
hits.line_to(pos2.x + 1.0, pos2.y + 1.0);
|
hits.line_to(pos2.x + 1.0, pos2.y + 1.0);
|
||||||
hits.move_to(pos2.x - 1.0, pos2.y + 1.0);
|
hits.move_to(pos2.x - 1.0, pos2.y + 1.0);
|
||||||
|
|
@ -379,8 +379,8 @@ fn draw_track(gc: &mut Vec<Draw>, space: &Space, start: Vec2, dir: Vec2) {
|
||||||
const SCALE: f32 = 5.0;
|
const SCALE: f32 = 5.0;
|
||||||
const STEP: f32 = 2.0 * SCALE;
|
const STEP: f32 = 2.0 * SCALE;
|
||||||
// let mut loc = Location { pos: start, rot: Mat2::IDENTITY };
|
// let mut loc = Location { pos: start, rot: Mat2::IDENTITY };
|
||||||
// let dir = space.rect.globalize(start, dir);
|
// let dir = space.tube.globalize(start, dir);
|
||||||
// let v = space.rect.normalize(start, dir);
|
// let v = space.tube.normalize(start, dir);
|
||||||
let mut loc = Location { pos: start, rot: mat2(dir, vec2(-dir.y, dir.x)) };
|
let mut loc = Location { pos: start, rot: mat2(dir, vec2(-dir.y, dir.x)) };
|
||||||
let v = vec2(1.0, 0.0);
|
let v = vec2(1.0, 0.0);
|
||||||
let mut draw = |loc: &Location| {
|
let mut draw = |loc: &Location| {
|
||||||
|
|
@ -420,7 +420,7 @@ trait Renderable {
|
||||||
fn render(&self, gc: &mut Vec<Draw>);
|
fn render(&self, gc: &mut Vec<Draw>);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderable for Rect {
|
impl Renderable for Tube {
|
||||||
fn render(&self, gc: &mut Vec<Draw>) {
|
fn render(&self, gc: &mut Vec<Draw>) {
|
||||||
gc.new_path();
|
gc.new_path();
|
||||||
gc.rect(-self.outer_radius, -self.external_halflength, self.outer_radius, self.external_halflength);
|
gc.rect(-self.outer_radius, -self.external_halflength, self.outer_radius, self.external_halflength);
|
||||||
|
|
@ -579,49 +579,49 @@ trait FlatCell: std::fmt::Debug {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct RectInside {
|
struct TubeInside {
|
||||||
rect: Rect,
|
tube: Tube,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlatCell for RectInside {
|
impl FlatCell for TubeInside {
|
||||||
fn pos_to_global(&self, pos: Vec2) -> Vec2 {
|
fn pos_to_global(&self, pos: Vec2) -> Vec2 {
|
||||||
vec2(pos.x, self.rect.x(pos.y))
|
vec2(pos.x, self.tube.x(pos.y))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pos_to_local(&self, pos: Vec2) -> Vec2 {
|
fn pos_to_local(&self, pos: Vec2) -> Vec2 {
|
||||||
vec2(pos.x, self.rect.u(pos.y))
|
vec2(pos.x, self.tube.u(pos.y))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ray_to_global(&self, ray: Ray) -> Ray {
|
fn ray_to_global(&self, ray: Ray) -> Ray {
|
||||||
Ray {
|
Ray {
|
||||||
pos: self.pos_to_global(ray.pos),
|
pos: self.pos_to_global(ray.pos),
|
||||||
dir: vec2(ray.dir.x, self.rect.dx(ray.pos.y) * ray.dir.y),
|
dir: vec2(ray.dir.x, self.tube.dx(ray.pos.y) * ray.dir.y),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ray_to_local(&self, ray: Ray) -> Ray {
|
fn ray_to_local(&self, ray: Ray) -> Ray {
|
||||||
Ray {
|
Ray {
|
||||||
pos: self.pos_to_local(ray.pos),
|
pos: self.pos_to_local(ray.pos),
|
||||||
dir: vec2(ray.dir.x, self.rect.du(ray.pos.y) * ray.dir.y),
|
dir: vec2(ray.dir.x, self.tube.du(ray.pos.y) * ray.dir.y),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_bounds(&self) -> (Vec2, Vec2) {
|
fn local_bounds(&self) -> (Vec2, Vec2) {
|
||||||
(vec2(-self.rect.inner_radius, -self.rect.internal_halflength), vec2(self.rect.inner_radius, self.rect.internal_halflength))
|
(vec2(-self.tube.inner_radius, -self.tube.internal_halflength), vec2(self.tube.inner_radius, self.tube.internal_halflength))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
struct Rect {
|
struct Tube {
|
||||||
outer_radius: f32,
|
outer_radius: f32,
|
||||||
inner_radius: f32,
|
inner_radius: f32,
|
||||||
external_halflength: f32,
|
external_halflength: f32,
|
||||||
internal_halflength: f32,
|
internal_halflength: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rect {
|
impl Tube {
|
||||||
fn fx(&self) -> fns::RectX { fns::RectX { min: self.inner_radius, max: self.outer_radius } }
|
fn fx(&self) -> fns::TubeX { fns::TubeX { min: self.inner_radius, max: self.outer_radius } }
|
||||||
fn fy(&self) -> fns::RectY { fns::RectY { internal: self.internal_halflength, external: self.external_halflength } }
|
fn fy(&self) -> fns::TubeY { fns::TubeY { internal: self.internal_halflength, external: self.external_halflength } }
|
||||||
|
|
||||||
pub fn x(&self, u: f32) -> f32 { self.fy().x(u) }
|
pub fn x(&self, u: f32) -> f32 { self.fy().x(u) }
|
||||||
pub fn u(&self, x: f32) -> f32 { self.fy().u(x) }
|
pub fn u(&self, x: f32) -> f32 { self.fy().u(x) }
|
||||||
|
|
@ -635,17 +635,17 @@ mod fns {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use approx::abs_diff_eq;
|
use approx::abs_diff_eq;
|
||||||
|
|
||||||
pub struct RectX {
|
pub struct TubeX {
|
||||||
pub min: f32,
|
pub min: f32,
|
||||||
pub max: f32,
|
pub max: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RectX {
|
impl TubeX {
|
||||||
pub fn value(&self, x: f32) -> f32 { (self.min, self.max).inverse_lerp(x.abs()).clamp(0.0, 1.0) }
|
pub fn value(&self, x: f32) -> f32 { (self.min, self.max).inverse_lerp(x.abs()).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 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 struct TubeY {
|
||||||
pub internal: f32,
|
pub internal: f32,
|
||||||
pub external: f32,
|
pub external: f32,
|
||||||
}
|
}
|
||||||
|
|
@ -660,7 +660,7 @@ mod fns {
|
||||||
if t.abs() <= lim { f(t) } else { val }
|
if t.abs() <= lim { f(t) } else { val }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RectY {
|
impl TubeY {
|
||||||
fn a(&self) -> f32 { -(self.external - self.internal) / self.internal.powi(2) }
|
fn a(&self) -> f32 { -(self.external - self.internal) / self.internal.powi(2) }
|
||||||
fn b(&self) -> f32 { 2.0 * self.external / self.internal - 1.0 }
|
fn b(&self) -> f32 { 2.0 * self.external / self.internal - 1.0 }
|
||||||
fn root(&self, x: f32) -> f32 { (self.b().powi(2) + 4.0 * self.a() * x.abs()).sqrt() }
|
fn root(&self, x: f32) -> f32 { (self.b().powi(2) + 4.0 * self.a() * x.abs()).sqrt() }
|
||||||
|
|
@ -673,8 +673,8 @@ mod fns {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rect_y() {
|
fn test_tube_y() {
|
||||||
let testee = RectY { internal: 100.0, external: 150.0 };
|
let testee = TubeY { internal: 100.0, external: 150.0 };
|
||||||
let ε = 1.0e-4f32;
|
let ε = 1.0e-4f32;
|
||||||
let δ = 1.0 / 8.0; // Mathematically, you want this to be small. Computationally, you don’t.
|
let δ = 1.0 / 8.0; // Mathematically, you want this to be small. Computationally, you don’t.
|
||||||
let margin = 1.0 / 16.0;
|
let margin = 1.0 / 16.0;
|
||||||
|
|
@ -700,39 +700,39 @@ mod fns {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rect() {
|
fn test_tube() {
|
||||||
let r = Rect {
|
let t = Tube {
|
||||||
outer_radius: 50.0,
|
outer_radius: 50.0,
|
||||||
inner_radius: 20.0,
|
inner_radius: 20.0,
|
||||||
external_halflength: 100.0,
|
external_halflength: 100.0,
|
||||||
internal_halflength: 10.0,
|
internal_halflength: 10.0,
|
||||||
};
|
};
|
||||||
assert_abs_diff_eq!(r.x(r.internal_halflength), r.external_halflength, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.x(t.internal_halflength), t.external_halflength, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.x(-r.internal_halflength), -r.external_halflength, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.x(-t.internal_halflength), -t.external_halflength, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.u(r.external_halflength), r.internal_halflength, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.u(t.external_halflength), t.internal_halflength, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.u(-r.external_halflength), -r.internal_halflength, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.u(-t.external_halflength), -t.internal_halflength, epsilon = 1.0e-5);
|
||||||
|
|
||||||
assert_abs_diff_eq!(r.dx(r.internal_halflength), 1.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.dx(t.internal_halflength), 1.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.dx(-r.internal_halflength), 1.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.dx(-t.internal_halflength), 1.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.du(r.external_halflength), 1.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.du(t.external_halflength), 1.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.du(-r.external_halflength), 1.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.du(-t.external_halflength), 1.0, epsilon = 1.0e-5);
|
||||||
|
|
||||||
assert_abs_diff_eq!(r.u(r.x(1.0)), 1.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.u(t.x(1.0)), 1.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.u(r.x(5.0)), 5.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.u(t.x(5.0)), 5.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.u(r.x(-5.0)), -5.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.u(t.x(-5.0)), -5.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.u(r.x(10.0)), 10.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.u(t.x(10.0)), 10.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.x(r.u(10.0)), 10.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.x(t.u(10.0)), 10.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.x(r.u(50.0)), 50.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.x(t.u(50.0)), 50.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.x(r.u(-50.0)), -50.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.x(t.u(-50.0)), -50.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.x(r.u(100.0)), 100.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.x(t.u(100.0)), 100.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.du(10.0) * r.dx(r.u(10.0)), 1.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.du(10.0) * t.dx(t.u(10.0)), 1.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.du(50.0) * r.dx(r.u(50.0)), 1.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.du(50.0) * t.dx(t.u(50.0)), 1.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.du(-50.0) * r.dx(r.u(-50.0)), 1.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.du(-50.0) * t.dx(t.u(-50.0)), 1.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.du(100.0) * r.dx(r.u(100.0)), 1.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.du(100.0) * t.dx(t.u(100.0)), 1.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.dx(1.0) * r.du(r.x(1.0)), 1.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.dx(1.0) * t.du(t.x(1.0)), 1.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.dx(5.0) * r.du(r.x(5.0)), 1.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.dx(5.0) * t.du(t.x(5.0)), 1.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.dx(-5.0) * r.du(r.x(-5.0)), 1.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.dx(-5.0) * t.du(t.x(-5.0)), 1.0, epsilon = 1.0e-5);
|
||||||
assert_abs_diff_eq!(r.dx(10.0) * r.du(r.x(10.0)), 1.0, epsilon = 1.0e-5);
|
assert_abs_diff_eq!(t.dx(10.0) * t.du(t.x(10.0)), 1.0, epsilon = 1.0e-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
trait FloatExt2 {
|
trait FloatExt2 {
|
||||||
|
|
@ -745,7 +745,7 @@ impl FloatExt2 for (f32, f32) {
|
||||||
fn inverse_lerp(&self, y: f32) -> f32 { f32::inverse_lerp(self.0, self.1, y) }
|
fn inverse_lerp(&self, y: f32) -> f32 { f32::inverse_lerp(self.0, self.1, y) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Metric for Rect {
|
impl Metric for Tube {
|
||||||
fn sqrt_at(&self, pos: Vec2) -> Decomp2 {
|
fn sqrt_at(&self, pos: Vec2) -> Decomp2 {
|
||||||
let sx = self.fx().value(pos.x);
|
let sx = self.fx().value(pos.x);
|
||||||
let sy = self.fy().du(pos.y);
|
let sy = self.fy().du(pos.y);
|
||||||
|
|
@ -775,12 +775,12 @@ impl Metric for Rect {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rect_metric_derivs() {
|
fn test_tube_metric_derivs() {
|
||||||
struct Approx(Rect);
|
struct Approx(Tube);
|
||||||
impl Metric for Approx {
|
impl Metric for Approx {
|
||||||
fn sqrt_at(&self, pos: Vec2) -> Decomp2 { self.0.sqrt_at(pos) }
|
fn sqrt_at(&self, pos: Vec2) -> Decomp2 { self.0.sqrt_at(pos) }
|
||||||
}
|
}
|
||||||
let testee = Rect {
|
let testee = Tube {
|
||||||
inner_radius: 30.0,
|
inner_radius: 30.0,
|
||||||
outer_radius: 50.0,
|
outer_radius: 50.0,
|
||||||
internal_halflength: 100.0,
|
internal_halflength: 100.0,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user