forked from StudioInfinity/dyna3
Add an Irisawa hexlet test assembly
This partial setup of the Irisawa hexlet problem is from the summer 2025 tech demo.
This commit is contained in:
parent
543bc4020f
commit
fae3f4531e
1 changed files with 113 additions and 1 deletions
|
@ -1,5 +1,5 @@
|
||||||
use itertools::izip;
|
use itertools::izip;
|
||||||
use std::{f64::consts::FRAC_1_SQRT_2, rc::Rc};
|
use std::{f64::consts::{FRAC_1_SQRT_2, PI}, rc::Rc};
|
||||||
use nalgebra::Vector3;
|
use nalgebra::Vector3;
|
||||||
use sycamore::prelude::*;
|
use sycamore::prelude::*;
|
||||||
use web_sys::{console, wasm_bindgen::JsValue};
|
use web_sys::{console, wasm_bindgen::JsValue};
|
||||||
|
@ -367,6 +367,116 @@ fn load_radius_ratio_assemb(assembly: &Assembly) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// to finish setting up the problem, fix the following curvatures:
|
||||||
|
// sun 1
|
||||||
|
// moon 5/3 = 1.666666666666666...
|
||||||
|
// chain1 2
|
||||||
|
// a tiny `x` or `z` nudge of the outer sphere reliably prevents realization
|
||||||
|
// failures before they happen, or resolves them after they happen. the result
|
||||||
|
// depends sensitively on the translation direction, suggesting that realization
|
||||||
|
// is failing because the engine is having trouble breaking a symmetry
|
||||||
|
// /* TO DO */
|
||||||
|
// the engine's performance on this problem is scale-dependent! with the current
|
||||||
|
// initial conditions, realization fails for any order of imposing the remaining
|
||||||
|
// curvature constraints. scaling everything up by a factor of ten, as done in
|
||||||
|
// the original problem, makes realization succeed reliably. one potentially
|
||||||
|
// relevant difference is that a lot of the numbers in the current initial
|
||||||
|
// conditions are exactly representable as floats, unlike the analogous numbers
|
||||||
|
// in the scaled-up problem. the inexact representations might break the
|
||||||
|
// symmetry that's getting the engine stuck
|
||||||
|
fn load_irisawa_hexlet_assemb(assembly: &Assembly) {
|
||||||
|
let index_range = 1..=6;
|
||||||
|
let colors = [
|
||||||
|
[1.00_f32, 0.00_f32, 0.25_f32],
|
||||||
|
[1.00_f32, 0.25_f32, 0.00_f32],
|
||||||
|
[0.75_f32, 0.75_f32, 0.00_f32],
|
||||||
|
[0.25_f32, 1.00_f32, 0.00_f32],
|
||||||
|
[0.00_f32, 0.25_f32, 1.00_f32],
|
||||||
|
[0.25_f32, 0.00_f32, 1.00_f32]
|
||||||
|
].into_iter();
|
||||||
|
|
||||||
|
// create the spheres
|
||||||
|
let spheres = [
|
||||||
|
Sphere::new(
|
||||||
|
"outer".to_string(),
|
||||||
|
"Outer".to_string(),
|
||||||
|
[0.5_f32, 0.5_f32, 0.5_f32],
|
||||||
|
engine::sphere(0.0, 0.0, 0.0, 1.5)
|
||||||
|
),
|
||||||
|
Sphere::new(
|
||||||
|
"sun".to_string(),
|
||||||
|
"Sun".to_string(),
|
||||||
|
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||||
|
engine::sphere(0.0, -0.75, 0.0, 0.75)
|
||||||
|
),
|
||||||
|
Sphere::new(
|
||||||
|
"moon".to_string(),
|
||||||
|
"Moon".to_string(),
|
||||||
|
[0.25_f32, 0.25_f32, 0.25_f32],
|
||||||
|
engine::sphere(0.0, 0.75, 0.0, 0.75)
|
||||||
|
),
|
||||||
|
].into_iter().chain(
|
||||||
|
index_range.clone().zip(colors).map(
|
||||||
|
|(k, color)| {
|
||||||
|
let ang = (k as f64) * PI/3.0;
|
||||||
|
Sphere::new(
|
||||||
|
format!("chain{k}"),
|
||||||
|
format!("Chain {k}"),
|
||||||
|
color,
|
||||||
|
engine::sphere(1.0 * ang.sin(), 0.0, 1.0 * ang.cos(), 0.5)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
for sphere in spheres {
|
||||||
|
let _ = assembly.try_insert_element(sphere);
|
||||||
|
}
|
||||||
|
|
||||||
|
// put the outer sphere in ghost mode and fix its curvature
|
||||||
|
let outer = assembly.elements_by_id.with_untracked(
|
||||||
|
|elts_by_id| elts_by_id["outer"].clone()
|
||||||
|
);
|
||||||
|
outer.ghost().set(true);
|
||||||
|
let outer_curvature_regulator = outer.regulators().with_untracked(
|
||||||
|
|regs| regs.first().unwrap().clone()
|
||||||
|
);
|
||||||
|
outer_curvature_regulator.set_point().set(
|
||||||
|
SpecifiedValue::try_from((1.0 / 3.0).to_string()).unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
// impose the desired tangencies
|
||||||
|
let [outer, sun, moon] = ["outer", "sun", "moon"].map(
|
||||||
|
|id| assembly.elements_by_id.with_untracked(
|
||||||
|
|elts_by_id| elts_by_id[id].clone()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
let chain = index_range.map(
|
||||||
|
|k| assembly.elements_by_id.with_untracked(
|
||||||
|
|elts_by_id| elts_by_id[&format!("chain{k}")].clone()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
for (chain_sphere, chain_sphere_next) in chain.clone().zip(chain.cycle().skip(1)) {
|
||||||
|
for (other_sphere, inversive_distance) in [
|
||||||
|
(outer.clone(), "1"),
|
||||||
|
(sun.clone(), "-1"),
|
||||||
|
(moon.clone(), "-1"),
|
||||||
|
(chain_sphere_next.clone(), "-1")
|
||||||
|
] {
|
||||||
|
let tangency = InversiveDistanceRegulator::new([chain_sphere.clone(), other_sphere]);
|
||||||
|
tangency.set_point.set(SpecifiedValue::try_from(inversive_distance.to_string()).unwrap());
|
||||||
|
assembly.insert_regulator(Rc::new(tangency));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let outer_sun_tangency = InversiveDistanceRegulator::new([outer.clone(), sun]);
|
||||||
|
outer_sun_tangency.set_point.set(SpecifiedValue::try_from("1".to_string()).unwrap());
|
||||||
|
assembly.insert_regulator(Rc::new(outer_sun_tangency));
|
||||||
|
|
||||||
|
let outer_moon_tangency = InversiveDistanceRegulator::new([outer.clone(), moon]);
|
||||||
|
outer_moon_tangency.set_point.set(SpecifiedValue::try_from("1".to_string()).unwrap());
|
||||||
|
assembly.insert_regulator(Rc::new(outer_moon_tangency));
|
||||||
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn AddRemove() -> View {
|
pub fn AddRemove() -> View {
|
||||||
/* DEBUG */
|
/* DEBUG */
|
||||||
|
@ -398,6 +508,7 @@ pub fn AddRemove() -> View {
|
||||||
"low-curv" => load_low_curv_assemb(assembly),
|
"low-curv" => load_low_curv_assemb(assembly),
|
||||||
"pointed" => load_pointed_assemb(assembly),
|
"pointed" => load_pointed_assemb(assembly),
|
||||||
"radius-ratio" => load_radius_ratio_assemb(assembly),
|
"radius-ratio" => load_radius_ratio_assemb(assembly),
|
||||||
|
"irisawa-hexlet" => load_irisawa_hexlet_assemb(assembly),
|
||||||
_ => ()
|
_ => ()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -450,6 +561,7 @@ pub fn AddRemove() -> View {
|
||||||
option(value="low-curv") { "Low-curvature" }
|
option(value="low-curv") { "Low-curvature" }
|
||||||
option(value="pointed") { "Pointed" }
|
option(value="pointed") { "Pointed" }
|
||||||
option(value="radius-ratio") { "Radius ratio" }
|
option(value="radius-ratio") { "Radius ratio" }
|
||||||
|
option(value="irisawa-hexlet") { "Irisawa hexlet" }
|
||||||
option(value="empty") { "Empty" }
|
option(value="empty") { "Empty" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue