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 crate::riemann::Metric;
|
||||||
use Subspace::{Boundary, Inner, Outer};
|
use Subspace::{Boundary, Inner, Outer};
|
||||||
use metric::Tube;
|
use metric::Tube;
|
||||||
use coords::Mapper;
|
use coords::{MapperInner, MapperOuter};
|
||||||
use crate::types::{FlatTraceResult, Hit, Location, Object, Ray};
|
use crate::types::{FlatTraceResult, Hit, Location, Object, Ray};
|
||||||
|
|
||||||
pub mod metric;
|
pub mod metric;
|
||||||
|
|
@ -64,11 +64,11 @@ 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 size = vec2(self.tube.inner_radius, self.tube.internal_halflength);
|
let inner = Rect { size: vec2(self.tube.inner_radius, self.tube.internal_halflength) };
|
||||||
let ray = self.tube.outer_to_inner(ray);
|
let ray = self.tube.global_to_inner(ray);
|
||||||
assert!(ray.pos.abs().cmple(size).all());
|
assert!(inner.is_inside(ray.pos));
|
||||||
let objs = self.list_objects_inner();
|
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 {
|
FlatTraceResult {
|
||||||
end: Some(self.tube.inner_to_global(ray.forward(dist))),
|
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)),
|
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> {
|
fn list_objects_outer(&self) -> Vec<Object> {
|
||||||
self.list_objects(|loc|
|
self.list_objects(|loc|
|
||||||
match self.which_subspace(loc.pos) {
|
match self.which_subspace(loc.pos) {
|
||||||
Outer => loc,
|
Inner | Outer => self.tube.global_to_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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Boundary => panic!("Object at {} was destroyed by the space curvature", loc.pos),
|
Boundary => panic!("Object at {} was destroyed by the space curvature", loc.pos),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_objects_inner(&self) -> Vec<Object> {
|
fn list_objects_inner(&self) -> Vec<Object> {
|
||||||
self.list_objects(|Location { pos, rot }|
|
self.list_objects(|loc|
|
||||||
match self.which_subspace(pos) {
|
match self.which_subspace(loc.pos) {
|
||||||
Inner | Outer => {
|
Inner | Outer => self.tube.global_to_inner(loc),
|
||||||
// NB: не работает для частей Outer с |y| < external_halflength. Но они и не нужны.
|
Boundary => panic!("Object at {} was destroyed by the space curvature", loc.pos),
|
||||||
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"),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -225,16 +211,22 @@ fn test_rect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
mod coords {
|
mod coords {
|
||||||
use glam::{Vec2, vec2};
|
use glam::{Mat2, Vec2, vec2};
|
||||||
use crate::types::Ray;
|
use crate::riemann::Metric;
|
||||||
use super::Tube;
|
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 inner_to_global(self, v: T) -> T;
|
||||||
fn global_to_inner(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 {
|
fn inner_to_global(self, pos: Vec2) -> Vec2 {
|
||||||
vec2(pos.x, self.y(pos.y))
|
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 {
|
fn inner_to_global(self, ray: Ray) -> Ray {
|
||||||
Ray {
|
Ray {
|
||||||
pos: self.inner_to_global(ray.pos),
|
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