Unify coordinate mapping

This commit is contained in:
numzero 2024-06-25 19:55:45 +03:00
parent 2515c0a0da
commit a31a950eca

View File

@ -3,6 +3,7 @@ use crate::riemann;
use crate::riemann::Metric; use crate::riemann::Metric;
use Subspace::{Boundary, Inner, Outer}; use Subspace::{Boundary, Inner, Outer};
use metric::Tube; use metric::Tube;
use coords::Mapper;
use crate::types::{FlatTraceResult, Hit, Location, Object, Ray}; use crate::types::{FlatTraceResult, Hit, Location, Object, Ray};
pub mod metric; pub mod metric;
@ -63,13 +64,14 @@ impl Space {
pub fn trace_inner(&self, ray: Ray) -> FlatTraceResult { pub 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 = TubeInside { tube: self.tube }; let size = vec2(self.tube.inner_radius, self.tube.internal_halflength);
let ray = cell.ray_to_local(ray); let ray = self.tube.outer_to_inner(ray);
assert!(ray.pos.abs().cmple(size).all());
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 = Rect { size }.trace_out_of(ray).expect("Can't get outta here!");
FlatTraceResult { FlatTraceResult {
end: Some(cell.ray_to_global(ray.forward(dist))), end: Some(self.tube.inner_to_outer(ray.forward(dist))),
objects: Self::hit_objects(objs.as_slice(), ray, dist, |pos| cell.pos_to_global(pos)), objects: Self::hit_objects(objs.as_slice(), ray, dist, |pos| self.tube.inner_to_outer(pos)),
} }
} }
@ -151,11 +153,10 @@ impl Space {
match self.which_subspace(a) { match self.which_subspace(a) {
Outer => vec![b], Outer => vec![b],
Inner => { Inner => {
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 = self.tube.outer_to_inner(a);
let b = cell.pos_to_local(b); let b = self.tube.outer_to_inner(b);
(1..=n).map(|k| cell.pos_to_global(a.lerp(b, k as f32 / n as f32))).collect() (1..=n).map(|k| self.tube.inner_to_outer(a.lerp(b, k as f32 / n as f32))).collect()
} }
Boundary => panic!("Can't draw a line here!"), Boundary => panic!("Can't draw a line here!"),
} }
@ -223,44 +224,39 @@ fn test_rect() {
assert_eq!(r.trace_out_of(Ray { pos: vec2(2.0, 3.0), dir: vec2(1.0, 1.0) }), Some(0.0)); assert_eq!(r.trace_out_of(Ray { pos: vec2(2.0, 3.0), dir: vec2(1.0, 1.0) }), Some(0.0));
} }
#[derive(Debug)] mod coords {
struct TubeInside { use glam::{Vec2, vec2};
tube: Tube, use crate::types::Ray;
use super::Tube;
pub trait Mapper<T> {
fn inner_to_outer(self, v: T) -> T;
fn outer_to_inner(self, v: T) -> T;
} }
impl TubeInside { impl Mapper<Vec2> for Tube {
fn is_inside(&self, pos: Vec2) -> bool { fn inner_to_outer(self, pos: Vec2) -> Vec2 {
pos.abs().cmple(self.size()).all() vec2(pos.x, self.y(pos.y))
} }
fn to_boundary(&self, ray: Ray) -> Option<f32> { fn outer_to_inner(self, pos: Vec2) -> Vec2 {
assert!(self.is_inside(ray.pos)); vec2(pos.x, self.v(pos.y))
Rect { size: self.size() }.trace_out_of(ray) }
} }
fn pos_to_global(&self, pos: Vec2) -> Vec2 { impl Mapper<Ray> for Tube {
vec2(pos.x, self.tube.y(pos.y)) fn inner_to_outer(self, ray: Ray) -> Ray {
}
fn pos_to_local(&self, pos: Vec2) -> Vec2 {
vec2(pos.x, self.tube.v(pos.y))
}
fn ray_to_global(&self, ray: Ray) -> Ray {
Ray { Ray {
pos: self.pos_to_global(ray.pos), pos: self.inner_to_outer(ray.pos),
dir: vec2(ray.dir.x, self.tube.dy(ray.pos.y) * ray.dir.y), dir: vec2(ray.dir.x, self.dy(ray.pos.y) * ray.dir.y),
} }
} }
fn ray_to_local(&self, ray: Ray) -> Ray { fn outer_to_inner(self, ray: Ray) -> Ray {
Ray { Ray {
pos: self.pos_to_local(ray.pos), pos: self.outer_to_inner(ray.pos),
dir: vec2(ray.dir.x, self.tube.dv(ray.pos.y) * ray.dir.y), dir: vec2(ray.dir.x, self.dv(ray.pos.y) * ray.dir.y),
} }
} }
fn size(&self) -> Vec2 {
vec2(self.tube.inner_radius, self.tube.internal_halflength)
} }
} }