Extract flat coordinate system handling
This commit is contained in:
parent
7f560a2b49
commit
b5c57babb4
|
|
@ -3,7 +3,7 @@ use crate::riemann;
|
|||
use crate::riemann::Metric;
|
||||
use Subspace::{Boundary, Inner, Outer};
|
||||
use metric::Tube;
|
||||
use coords::Mapper;
|
||||
use coords::{MapperInner, MapperOuter};
|
||||
use crate::types::{FlatTraceResult, Hit, Location, Object, Ray};
|
||||
|
||||
pub mod metric;
|
||||
|
|
@ -64,11 +64,11 @@ impl Space {
|
|||
|
||||
pub fn trace_inner(&self, ray: Ray) -> FlatTraceResult {
|
||||
assert_eq!(self.which_subspace(ray.pos), Inner);
|
||||
let size = vec2(self.tube.inner_radius, self.tube.internal_halflength);
|
||||
let ray = self.tube.outer_to_inner(ray);
|
||||
assert!(ray.pos.abs().cmple(size).all());
|
||||
let inner = Rect { size: vec2(self.tube.inner_radius, self.tube.internal_halflength) };
|
||||
let ray = self.tube.global_to_inner(ray);
|
||||
assert!(inner.is_inside(ray.pos));
|
||||
let objs = self.list_objects_inner();
|
||||
let dist = Rect { size }.trace_out_of(ray).expect("Can't get outta here!");
|
||||
let dist = inner.trace_out_of(ray).expect("Can't get outta here!");
|
||||
FlatTraceResult {
|
||||
end: Some(self.tube.inner_to_global(ray.forward(dist))),
|
||||
objects: Self::hit_objects(objs.as_slice(), ray, dist, |pos| self.tube.inner_to_global(pos)),
|
||||
|
|
@ -101,30 +101,16 @@ impl Space {
|
|||
fn list_objects_outer(&self) -> Vec<Object> {
|
||||
self.list_objects(|loc|
|
||||
match self.which_subspace(loc.pos) {
|
||||
Outer => loc,
|
||||
Inner => {
|
||||
let Vec2 { x: u, y } = loc.pos; // в основной СК
|
||||
let v = self.tube.v(y) + y.signum() * (self.tube.external_halflength - self.tube.internal_halflength);
|
||||
Location {
|
||||
pos: vec2(u, v), // в плоском продолжении СК Outer на область Inner
|
||||
rot: self.global_to_flat(loc.pos) * loc.rot,
|
||||
}
|
||||
}
|
||||
Inner | Outer => self.tube.global_to_outer(loc),
|
||||
Boundary => panic!("Object at {} was destroyed by the space curvature", loc.pos),
|
||||
})
|
||||
}
|
||||
|
||||
fn list_objects_inner(&self) -> Vec<Object> {
|
||||
self.list_objects(|Location { pos, rot }|
|
||||
match self.which_subspace(pos) {
|
||||
Inner | Outer => {
|
||||
// NB: не работает для частей Outer с |y| < external_halflength. Но они и не нужны.
|
||||
Location {
|
||||
pos: vec2(pos.x, self.tube.v(pos.y)), // в плоской СК для Inner или её продолжении на Outer
|
||||
rot: self.global_to_flat(pos) * rot,
|
||||
}
|
||||
}
|
||||
Boundary => panic!("Object at {pos} was destroyed by the space curvature"),
|
||||
self.list_objects(|loc|
|
||||
match self.which_subspace(loc.pos) {
|
||||
Inner | Outer => self.tube.global_to_inner(loc),
|
||||
Boundary => panic!("Object at {} was destroyed by the space curvature", loc.pos),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -225,16 +211,22 @@ fn test_rect() {
|
|||
}
|
||||
|
||||
mod coords {
|
||||
use glam::{Vec2, vec2};
|
||||
use crate::types::Ray;
|
||||
use super::Tube;
|
||||
use glam::{Mat2, Vec2, vec2};
|
||||
use crate::riemann::Metric;
|
||||
use crate::types::{Location, Ray};
|
||||
use super::{Rect, Tube};
|
||||
|
||||
pub trait Mapper<T> {
|
||||
pub trait MapperInner<T> {
|
||||
fn inner_to_global(self, v: T) -> T;
|
||||
fn global_to_inner(self, v: T) -> T;
|
||||
}
|
||||
|
||||
impl Mapper<Vec2> for Tube {
|
||||
pub trait MapperOuter<T> {
|
||||
fn outer_to_global(self, v: T) -> T;
|
||||
fn global_to_outer(self, v: T) -> T;
|
||||
}
|
||||
|
||||
impl MapperInner<Vec2> for Tube {
|
||||
fn inner_to_global(self, pos: Vec2) -> Vec2 {
|
||||
vec2(pos.x, self.y(pos.y))
|
||||
}
|
||||
|
|
@ -244,7 +236,7 @@ mod coords {
|
|||
}
|
||||
}
|
||||
|
||||
impl Mapper<Ray> for Tube {
|
||||
impl MapperInner<Ray> for Tube {
|
||||
fn inner_to_global(self, ray: Ray) -> Ray {
|
||||
Ray {
|
||||
pos: self.inner_to_global(ray.pos),
|
||||
|
|
@ -259,4 +251,49 @@ mod coords {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Tube {
|
||||
fn flat_to_global(&self, at: Vec2) -> Mat2 {
|
||||
Mat2::from(self.sqrt_at(at).inverse())
|
||||
}
|
||||
|
||||
fn global_to_flat(&self, at: Vec2) -> Mat2 {
|
||||
Mat2::from(self.sqrt_at(at))
|
||||
}
|
||||
}
|
||||
|
||||
impl MapperInner<Location> for Tube {
|
||||
fn inner_to_global(self, loc: Location) -> Location {
|
||||
todo!()
|
||||
}
|
||||
|
||||
// NB: не работает для частей Outer с |y| < external_halflength. Но они и не нужны.
|
||||
fn global_to_inner(self, loc: Location) -> Location {
|
||||
Location {
|
||||
pos: vec2(loc.pos.x, self.v(loc.pos.y)), // в плоской СК для Inner или её продолжении на Outer
|
||||
rot: self.global_to_flat(loc.pos) * loc.rot,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MapperOuter<Location> for Tube {
|
||||
fn outer_to_global(self, loc: Location) -> Location {
|
||||
todo!()
|
||||
}
|
||||
|
||||
// NB: имеет разрыв в области Inner на y = 0.
|
||||
fn global_to_outer(self, loc: Location) -> Location {
|
||||
let inner = Rect { size: vec2(self.inner_radius, self.internal_halflength) };
|
||||
if inner.is_inside(loc.pos) {
|
||||
let Vec2 { x: u, y } = loc.pos; // в основной СК
|
||||
let v = self.v(y) + y.signum() * (self.external_halflength - self.internal_halflength);
|
||||
Location {
|
||||
pos: vec2(u, v), // в плоском продолжении СК Outer на область Inner
|
||||
rot: self.global_to_flat(loc.pos) * loc.rot,
|
||||
}
|
||||
} else {
|
||||
loc
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user