Awful... temp comit

This commit is contained in:
numzero 2024-05-07 14:08:15 +03:00
parent 544ccd75d1
commit 0ba6d597f7

View File

@ -13,9 +13,10 @@ pub fn main() {
m: 10.0, m: 10.0,
}; };
let space = Rect { let space = Rect {
scale: 3.0, inner_radius: 30.0,
r: vec2(30.0, 300.0), outer_radius: 50.0,
m: vec2(20.0, 50.0), internal_halflength: 100.0,
external_halflength: 300.0,
}; };
with_2d_graphics(move || { with_2d_graphics(move || {
let canvas = create_drawing_window("Refraction"); let canvas = create_drawing_window("Refraction");
@ -30,7 +31,9 @@ pub fn main() {
Box::new(Inside { space: space.clone() }), Box::new(Inside { space: space.clone() }),
]; ];
parts.draw_fan(gc, vec2(-500.0, 0.0), vec2(1.0, 0.0), 1.0); //parts.draw_fan(gc, vec2(-500.0, 0.0), vec2(1.0, 0.0), 1.0);
// parts.draw_fan(gc, vec2(-20.0, -500.0), vec2(0.1, 0.9), 1.0);
//parts.draw_ray(gc, vec2(-20.0, -500.0), vec2(0.1, 0.9));
}); });
}); });
} }
@ -70,7 +73,15 @@ impl SpaceVisual for Inside {
} }
fn globalize_loc(&self, pos: Vec2) -> Vec2 { fn globalize_loc(&self, pos: Vec2) -> Vec2 {
vec2(pos.x, pos.y * self.space.scale) todo!()
// let off = self.space.r.y + self.space.m - self.space.r.y / self.space.scale - self.space.m / (self.space.scale + 1.0) * 2.0;
// if pos.y.abs() * self.space.scale <= self.space.r.y {
// vec2(pos.x, pos.y * self.space.scale)
// } else {
// let t = pos.y.abs() - self.space.r.y / self.space.scale;
// let f = t + (self.space.scale - 1.0) * t * t * t + 0.5 * (1.0 - self.space.scale) * t * t * t * t;
// vec2(0.0, 0.0)
// }
} }
} }
@ -162,8 +173,8 @@ impl Renderable for Coil {
impl Renderable for Rect { impl Renderable for Rect {
fn render(&self, gc: &mut Vec<Draw>) { fn render(&self, gc: &mut Vec<Draw>) {
gc.new_path(); gc.new_path();
gc.rect(-self.r.x - self.m.x, -self.r.y - self.m.y, self.r.x + self.m.x, self.r.y + self.m.y); gc.rect(-self.outer_radius, -self.external_halflength, self.outer_radius, self.external_halflength);
gc.rect(-self.r.x, -self.r.y, self.r.x, self.r.y); gc.rect(-self.inner_radius, -self.external_halflength, self.inner_radius, self.external_halflength);
gc.winding_rule(WindingRule::EvenOdd); gc.winding_rule(WindingRule::EvenOdd);
gc.fill_color(Color::Rgba(0.8, 0.8, 0.8, 1.0)); gc.fill_color(Color::Rgba(0.8, 0.8, 0.8, 1.0));
gc.fill(); gc.fill();
@ -171,7 +182,9 @@ impl Renderable for Rect {
gc.stroke_color(Color::Rgba(1.0, 0.5, 0.0, 1.0)); gc.stroke_color(Color::Rgba(1.0, 0.5, 0.0, 1.0));
self.draw_fan(gc, vec2(-500.0, 0.0), vec2(1.0, 0.0), 1.0); self.draw_fan(gc, vec2(-500.0, 0.0), vec2(1.0, 0.0), 1.0);
gc.stroke_color(Color::Rgba(0.0, 0.5, 1.0, 1.0)); gc.stroke_color(Color::Rgba(0.0, 0.5, 1.0, 1.0));
self.draw_fan(gc, vec2(0.0, -0.5 * self.r.y), vec2(1.0, 1.0), 1.0); self.draw_fan(gc, vec2(0.0, -0.5 * self.external_halflength), vec2(1.0, 1.0), 1.0);
gc.stroke_color(Color::Rgba(0.2, 0.7, 0.0, 1.0));
self.draw_fan(gc, vec2(-0.5 * self.inner_radius, -1.2 * self.external_halflength), vec2(0.0, 1.0), 1.0);
} }
} }
@ -201,17 +214,42 @@ impl Metric for Coil {
} }
struct Rect { struct Rect {
scale: f32, outer_radius: f32,
r: Vec2, inner_radius: f32,
m: Vec2, external_halflength: f32,
internal_halflength: f32,
}
impl Rect {
fn γ(&self) -> f32 { self.external_halflength / self.internal_halflength }
fn ri(&self) -> f32 { self.internal_halflength }
fn re(&self) -> f32 { self.external_halflength }
fn a(&self) -> f32 { (1.0 - self.γ()) / self.ri() }
fn b(&self) -> f32 { 2.0 * self.γ() - 1.0 }
fn root(&self, x: f32) -> f32 { ((2.0 * self.γ() - 1.0).powi(2) + 4.0 * (1.0 - self.γ()) * x / self.ri()).sqrt() }
fn x(&self, u: f32) -> f32 { (self.a() * u.abs() + self.b()) * u }
fn u(&self, x: f32) -> f32 { 0.5 * self.ri() * (1.0 - 2.0 * self.γ() + self.root(x.abs())) / (1.0 - self.γ()) * x.signum() }
} }
impl Metric for Rect { impl Metric for Rect {
fn halfmetric(&self, pos: Vec2) -> Decomp2 { fn halfmetric(&self, pos: Vec2) -> Decomp2 {
let s = smoothbox(pos.x, vec2(-self.r.x, self.r.x), self.m.x) * smoothbox(pos.y, vec2(-self.r.y, self.r.y), self.m.y); let γ = self.γ();
let re = self.re();
let ri = self.ri();
let a = self.a();
let b = self.b();
let x = pos.y.abs();
let u = 0.5 * ri * (1.0 - 2.0 * γ + self.root(x)) / (1.0 - γ);
let sx = ((pos.x.abs() - self.inner_radius) / (self.outer_radius - self.inner_radius)).clamp(0.0, 1.0);
let sy = if x <= re { 1.0 / (2.0 * a * u + b) } else { 1.0 };
let sy = if x <= re { 1.0 / self.root(x) } else { 1.0 };
assert!(sx.is_finite());
assert!(sy.is_finite());
assert!(sy > 0.0);
Decomp2 { Decomp2 {
ortho: Mat2::IDENTITY, ortho: Mat2::IDENTITY,
diag: vec2(1.0, 1.0.lerp(1.0 / self.scale, s)), diag: vec2(1.0, sy.lerp(1.0, sx)),
} }
} }
} }
@ -241,13 +279,25 @@ struct Inside {
impl boundary::Boundary for Outside { impl boundary::Boundary for Outside {
fn next(&self, base: Vec2, dir: Vec2, limit: f32) -> Option<(boundary::Id, Vec2, Vec2)> { fn next(&self, base: Vec2, dir: Vec2, limit: f32) -> Option<(boundary::Id, Vec2, Vec2)> {
let size = self.space.r + self.space.m; todo!()
let bnd = Loop(vec![vec2(-size.x, -size.y), vec2(size.x, -size.y), vec2(size.x, size.y), vec2(-size.x, size.y)]); // let osize = self.space.r + self.space.m;
let (_, dist) = bnd.hit(base, dir)?; // let isize = self.space.r;
if dist <= limit { // let bnd = Loop(vec![
return Some((boundary::Id(1), base + dist * dir, dir)); // vec2(-osize.x, -osize.y), vec2(-isize.x, -osize.y), vec2(isize.x, -osize.y), vec2(osize.x, -osize.y),
} // vec2(osize.x, osize.y), vec2(isize.x, osize.y), vec2(-isize.x, osize.y), vec2(-osize.x, osize.y),
None // ]);
// let (side, dist) = bnd.hit(base, dir)?;
// if dist <= limit {
// let bnds = [0, 1, 0, 0, 0, 2, 0, 0];
// let off = self.space.r.y + self.space.m - self.space.r.y / self.space.scale - self.space.m / (self.space.scale + 1.0) * 2.0;
// return match bnds[side] {
// 0 => Some((boundary::Id(1), base + dist * dir, dir)),
// 1 => Some((boundary::Id(2), base + dist * dir + vec2(0.0, off), dir)),
// 2 => Some((boundary::Id(2), base + dist * dir - vec2(0.0, off), dir)),
// _ => panic!(),
// };
// }
// None
} }
} }
@ -259,25 +309,26 @@ impl Metric for Outside {
impl boundary::Boundary for Wall { impl boundary::Boundary for Wall {
fn next(&self, base: Vec2, dir: Vec2, limit: f32) -> Option<(boundary::Id, Vec2, Vec2)> { fn next(&self, base: Vec2, dir: Vec2, limit: f32) -> Option<(boundary::Id, Vec2, Vec2)> {
let osize = self.space.r + self.space.m; todo!()
let isize = self.space.r; // let osize = self.space.r + self.space.m;
let obnd = Loop(vec![vec2(-osize.x, -osize.y), vec2(-osize.x, osize.y), vec2(osize.x, osize.y), vec2(osize.x, -osize.y)]); // let isize = self.space.r;
let ibnd = Loop(vec![vec2(-isize.x, -isize.y), vec2(isize.x, -isize.y), vec2(isize.x, isize.y), vec2(-isize.x, isize.y)]); // let obnd = Loop(vec![vec2(-osize.x, -osize.y), vec2(-osize.x, osize.y), vec2(osize.x, osize.y), vec2(osize.x, -osize.y)]);
if let Some((_, dist)) = ibnd.hit(base, dir) { // let ibnd = Loop(vec![vec2(-isize.x, -isize.y), vec2(isize.x, -isize.y), vec2(isize.x, isize.y), vec2(-isize.x, isize.y)]);
if dist <= limit { // if let Some((_, dist)) = ibnd.hit(base, dir) {
let p = base + dist * dir; // if dist <= limit {
let v = dir; // let p = base + dist * dir;
let p = vec2(p.x, p.y / self.space.scale); // let v = dir;
let v = vec2(v.x, v.y / self.space.scale); // let p = vec2(p.x, p.y / self.space.scale);
return Some((boundary::Id(2), p, v)); // let v = vec2(v.x, v.y / self.space.scale);
} // return Some((boundary::Id(2), p, v));
} // }
if let Some((_, dist)) = obnd.hit(base, dir) { // }
if dist <= limit { // if let Some((_, dist)) = obnd.hit(base, dir) {
return Some((boundary::Id(0), base + dist * dir, dir)); // if dist <= limit {
} // return Some((boundary::Id(0), base + dist * dir, dir));
} // }
None // }
// None
} }
} }
@ -289,18 +340,19 @@ impl Metric for Wall {
impl boundary::Boundary for Inside { impl boundary::Boundary for Inside {
fn next(&self, base: Vec2, dir: Vec2, limit: f32) -> Option<(boundary::Id, Vec2, Vec2)> { fn next(&self, base: Vec2, dir: Vec2, limit: f32) -> Option<(boundary::Id, Vec2, Vec2)> {
let size = self.space.r; todo!()
let size = vec2(size.x, size.y / self.space.scale); // let size = self.space.r;
let bnd = Loop(vec![vec2(-size.x, -size.y), vec2(-size.x, size.y), vec2(size.x, size.y), vec2(size.x, -size.y)]); // let size = vec2(size.x, size.y / self.space.scale);
let (_, dist) = bnd.hit(base, dir)?; // let bnd = Loop(vec![vec2(-size.x, -size.y), vec2(-size.x, size.y), vec2(size.x, size.y), vec2(size.x, -size.y)]);
if dist <= limit { // let (_, dist) = bnd.hit(base, dir)?;
let p = base + dist * dir; // if dist <= limit {
let v = dir; // let p = base + dist * dir;
let p = vec2(p.x, p.y * self.space.scale); // let v = dir;
let v = vec2(v.x, v.y * self.space.scale); // let p = vec2(p.x, p.y * self.space.scale);
return Some((boundary::Id(1), p, v)); // let v = vec2(v.x, v.y * self.space.scale);
} // return Some((boundary::Id(1), p, v));
None // }
// None
} }
} }
@ -502,10 +554,15 @@ fn smoothstep(x: f32) -> f32 {
3.0 * x * x - 2.0 * x * x * x 3.0 * x * x - 2.0 * x * x * x
} }
/// 1.0 for val∈[range.x, range.y], 0.0 for val∉[range.xpad, range.y+pad], smoothstep in-between. /// 1.0 for val∈[range.x, range.y], 0.0 for val∉[range.xpad, range.y+pad], linear in-between.
fn smoothbox(val: f32, range: Vec2, pad: f32) -> f32 { fn trapezoid(val: f32, range: Vec2, pad: f32) -> f32 {
let slope1 = 1.0 + (val - range.x) / pad; let slope1 = 1.0 + (val - range.x) / pad;
let slope2 = 1.0 - (val - range.y) / pad; let slope2 = 1.0 - (val - range.y) / pad;
let lin = slope1.min(slope2); let lin = slope1.min(slope2);
smoothstep(lin.clamp(0.0, 1.0)) lin.clamp(0.0, 1.0)
}
/// 1.0 for val∈[range.x, range.y], 0.0 for val∉[range.xpad, range.y+pad], smoothstep in-between.
fn smoothbox(val: f32, range: Vec2, pad: f32) -> f32 {
smoothstep(trapezoid(val, range, pad))
} }