Unify tracing in different CSes

This commit is contained in:
numzero 2024-06-28 15:32:35 +03:00
parent 08dba8e1dd
commit e8551f5d02

View File

@ -4,6 +4,7 @@ use crate::riemann::Metric;
use Subspace::{Boundary, Inner, Outer};
use metric::Tube;
use coords::{FlatCoordinateSystem, InnerCS, OuterCS};
use crate::tube::coords::FlatRegion;
use crate::types::{FlatTraceResult, Hit, Location, Object, Ray};
pub mod metric;
@ -56,23 +57,17 @@ impl Space {
pub fn trace_inner(&self, ray: Ray) -> FlatTraceResult {
assert_eq!(self.which_subspace(ray.pos), Inner);
let cs = InnerCS(self.tube);
let inner = Rect { size: vec2(self.tube.inner_radius, self.tube.internal_halflength) };
let ray = cs.global_to_flat(ray);
assert!(inner.is_inside(ray.pos));
let dist = inner.trace_out_of(ray);
self.trace_flat(cs, ray, dist)
self.trace_flat(InnerCS(self.tube), ray)
}
pub fn trace_outer(&self, ray: Ray) -> FlatTraceResult {
assert_eq!(self.which_subspace(ray.pos), Outer);
let cs = OuterCS(self.tube);
let outer = Rect { size: vec2(self.tube.outer_radius, self.tube.external_halflength) };
let dist = outer.trace_into(ray);
self.trace_flat(cs, ray, dist)
self.trace_flat(OuterCS(self.tube), ray)
}
fn trace_flat(&self, cs: impl FlatCoordinateSystem<Vec2> + FlatCoordinateSystem<Ray> + FlatCoordinateSystem<Location>, ray: Ray, dist: Option<f32>) -> FlatTraceResult {
fn trace_flat(&self, cs: impl FlatRegion, ray: Ray) -> FlatTraceResult {
let ray = cs.global_to_flat(ray);
let dist = cs.distance_to_boundary(ray);
let objs = self.list_objects(|loc| cs.global_to_flat(loc));
FlatTraceResult {
end: dist.map(|dist| cs.flat_to_global(ray.forward(dist))),
@ -200,6 +195,11 @@ mod coords {
fn global_to_flat(&self, v: T) -> T { v }
}
pub trait FlatRegion: FlatCoordinateSystem<Vec2> + FlatCoordinateSystem<Ray> + FlatCoordinateSystem<Location> {
// Измеряет расстояние до выхода за пределы области вдоль луча ray. Луч задаётся в плоской СК.
fn distance_to_boundary(&self, _ray: Ray) -> Option<f32> { None }
}
pub struct InnerCS(pub Tube);
impl FlatCoordinateSystem<Vec2> for InnerCS {
@ -241,6 +241,12 @@ mod coords {
}
}
impl FlatRegion for InnerCS {
fn distance_to_boundary(&self, ray: Ray) -> Option<f32> {
Rect { size: vec2(self.0.inner_radius, self.0.internal_halflength) }.trace_out_of(ray)
}
}
pub struct OuterCS(pub Tube);
impl FlatCoordinateSystem<Vec2> for OuterCS {}
@ -268,6 +274,12 @@ mod coords {
}
}
impl FlatRegion for OuterCS {
fn distance_to_boundary(&self, ray: Ray) -> Option<f32> {
Rect { size: vec2(self.0.outer_radius, self.0.external_halflength) }.trace_into(ray)
}
}
#[cfg(test)]
mod test {
use super::{Location, Tube, OuterCS, FlatCoordinateSystem};