Split into modules

This commit is contained in:
numzero 2024-04-28 23:11:34 +03:00
parent 4c29c8de0b
commit 10563d8d56

View File

@ -2,6 +2,7 @@ use flo_draw::*;
use flo_canvas::*; use flo_canvas::*;
use glm::*; use glm::*;
use num_traits::identities::Zero; use num_traits::identities::Zero;
use riemann::{Decomp2, Metric, trace_iter};
pub fn main() { pub fn main() {
let space = Coil { let space = Coil {
@ -75,14 +76,18 @@ impl Metric for Coil {
} }
} }
struct Decomp2 { mod riemann {
ortho: Mat2, use glm::*;
diag: Vec2, use num_traits::identities::Zero;
}
type Tens2 = [Mat2; 2]; pub struct Decomp2 {
pub ortho: Mat2,
pub diag: Vec2,
}
trait Metric { type Tens2 = [Mat2; 2];
pub trait Metric {
fn halfmetric(&self, pos: Vec2) -> Decomp2; fn halfmetric(&self, pos: Vec2) -> Decomp2;
fn metric(&self, pos: Vec2) -> Mat2 { fn metric(&self, pos: Vec2) -> Mat2 {
@ -103,18 +108,18 @@ trait Metric {
} }
fn globalize(&self, at: Vec2, v: Vec2) -> Vec2 { fn globalize(&self, at: Vec2, v: Vec2) -> Vec2 {
let h = self.halfmetric(at); let h = self.halfmetric(at);
transpose(&h.ortho) * diagonal( Vec2::from_s(1.0) / h.diag) * h.ortho * v transpose(&h.ortho) * diagonal(Vec2::from_s(1.0) / h.diag) * h.ortho * v
}
} }
}
struct TraceIter<'a, M: Metric> { pub struct TraceIter<'a, M: Metric> {
space: &'a M, space: &'a M,
p: Vec2, p: Vec2,
v: Vec2, v: Vec2,
dt: f32, dt: f32,
} }
impl<'a, M: Metric> Iterator for TraceIter<'a, M> { impl<'a, M: Metric> Iterator for TraceIter<'a, M> {
type Item = Vec2; type Item = Vec2;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
@ -123,23 +128,29 @@ impl<'a, M: Metric> Iterator for TraceIter<'a, M> {
self.p = self.p + self.v * self.dt; self.p = self.p + self.v * self.dt;
Some(self.p) Some(self.p)
} }
} }
fn trace(space: &impl Metric, base: Vec2, dir: Vec2, distance: f32, dt: f32) -> Vec<Vec2> { fn trace(space: &impl Metric, base: Vec2, dir: Vec2, distance: f32, dt: f32) -> Vec<Vec2> {
trace_iter(space, base, dir, dt).take((distance / dt) as usize).collect() trace_iter(space, base, dir, dt).take((distance / dt) as usize).collect()
} }
fn trace_iter<M: Metric>(space: &M, base: Vec2, dir: Vec2, dt: f32) -> TraceIter<M> { pub fn trace_iter<M: Metric>(space: &M, base: Vec2, dir: Vec2, dt: f32) -> TraceIter<M> {
TraceIter{ TraceIter {
space: space, space: space,
p: base, p: base,
v: space.normalize(base, dir), v: space.normalize(base, dir),
dt: dt, dt: dt,
} }
} }
#[test] #[cfg(test)]
fn t_iter() { mod test {
use glm::*;
use crate::riemann::{trace, trace_iter};
use crate::Coil;
#[test]
fn t_iter() {
let space = Coil { let space = Coil {
coil_scale: 2.0, coil_scale: 2.0,
coil_r: 300.0, coil_r: 300.0,
@ -153,9 +164,10 @@ fn t_iter() {
let a = trace(&space, base, dir, dt * (steps as f32), dt); let a = trace(&space, base, dir, dt * (steps as f32), dt);
let b: Vec<Vec2> = trace_iter(&space, base, dir, dt).take(steps).collect(); let b: Vec<Vec2> = trace_iter(&space, base, dir, dt).take(steps).collect();
assert_eq!(a, b); assert_eq!(a, b);
} }
}
fn krist(space: &impl Metric, pos: Vec2) -> Tens2 { fn krist(space: &impl Metric, pos: Vec2) -> Tens2 {
// Γ^i_k_l = .5 * g^i^m * (g_m_k,l + g_m_l,k - g_k_l,m) // Γ^i_k_l = .5 * g^i^m * (g_m_k,l + g_m_l,k - g_k_l,m)
let g = inverse(&space.metric(pos)); // с верхними индексами let g = inverse(&space.metric(pos)); // с верхними индексами
let d = space.dmetric(pos); let d = space.dmetric(pos);
@ -173,28 +185,29 @@ fn krist(space: &impl Metric, pos: Vec2) -> Tens2 {
} }
} }
ret ret
} }
fn dir_deriv(f: impl Fn(Vec2) -> Mat2, pos: Vec2, delta: Vec2) -> Mat2 { fn dir_deriv(f: impl Fn(Vec2) -> Mat2, pos: Vec2, delta: Vec2) -> Mat2 {
(f(pos + delta) - f(pos - delta)) / (2.0 * length(delta)) (f(pos + delta) - f(pos - delta)) / (2.0 * length(delta))
} }
fn part_deriv(f: impl Fn(Vec2) -> Mat2, pos: Vec2, eps: f32) -> Tens2 { fn part_deriv(f: impl Fn(Vec2) -> Mat2, pos: Vec2, eps: f32) -> Tens2 {
[ [
dir_deriv(&f, pos, vec2(eps, 0.0)), dir_deriv(&f, pos, vec2(eps, 0.0)),
dir_deriv(&f, pos, vec2(0.0, eps)), dir_deriv(&f, pos, vec2(0.0, eps)),
] ]
} }
fn convolute(G: Tens2, v: Vec2) -> Vec2 { fn convolute(G: Tens2, v: Vec2) -> Vec2 {
vec2( vec2(
dot(v, G[0] * v), dot(v, G[0] * v),
dot(v, G[1] * v) dot(v, G[1] * v)
) )
} }
fn diagonal(v: Vec2) -> Mat2 { fn diagonal(v: Vec2) -> Mat2 {
mat2(v.x, 0.0, 0.0, v.y) mat2(v.x, 0.0, 0.0, v.y)
}
} }
fn sqr(x: f32) -> f32 { fn sqr(x: f32) -> f32 {