forked from StudioInfinity/dyna3
feat: planar octagon with correct dimensions for 554aug2
This commit is contained in:
parent
aeace1a562
commit
c3c3e14a43
2 changed files with 232 additions and 212 deletions
|
@ -1,6 +1,7 @@
|
|||
use enum_iterator::{all, Sequence};
|
||||
use nalgebra::{DMatrix, DVector, DVectorView};
|
||||
use std::{
|
||||
any::Any,
|
||||
cell::Cell,
|
||||
cmp::Ordering,
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
|
@ -95,7 +96,7 @@ pub trait Element: Serial + ProblemPoser + DisplayItem {
|
|||
fn default_id() -> String where Self: Sized;
|
||||
|
||||
// the default example of an element of this type
|
||||
fn default(id: String, id_num: u64) -> Self where Self: Sized;
|
||||
fn default(id: &str, id_num: u64) -> Self where Self: Sized;
|
||||
|
||||
// the default regulators that come with this element
|
||||
fn default_regulators(self: Rc<Self>) -> Vec<Rc<dyn Regulator>> {
|
||||
|
@ -173,14 +174,14 @@ impl Sphere {
|
|||
const CURVATURE_COMPONENT: usize = 3;
|
||||
|
||||
pub fn new(
|
||||
id: String,
|
||||
label: String,
|
||||
id: &str,
|
||||
label: &str,
|
||||
color: ElementColor,
|
||||
representation: DVector<f64>,
|
||||
) -> Self {
|
||||
Self {
|
||||
id,
|
||||
label,
|
||||
id: id.to_string(),
|
||||
label: label.to_string(),
|
||||
color,
|
||||
representation: create_signal(representation),
|
||||
ghost: create_signal(false),
|
||||
|
@ -196,11 +197,11 @@ impl Element for Sphere {
|
|||
"sphere".to_string()
|
||||
}
|
||||
|
||||
fn default(id: String, id_num: u64) -> Self {
|
||||
fn default(id: &str, id_num: u64) -> Self {
|
||||
Self::new(
|
||||
id,
|
||||
format!("Sphere {id_num}"),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
&format!("Sphere {id_num}"),
|
||||
[0.75, 0.75, 0.75],
|
||||
sphere(0.0, 0.0, 0.0, 1.0),
|
||||
)
|
||||
}
|
||||
|
@ -297,9 +298,9 @@ impl Element for Point {
|
|||
"point".to_string()
|
||||
}
|
||||
|
||||
fn default(id: String, id_num: u64) -> Self {
|
||||
fn default(id: &str, id_num: u64) -> Self {
|
||||
Self::new(
|
||||
&id,
|
||||
id,
|
||||
&format!("Point {id_num}"),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
point(0.0, 0.0, 0.0),
|
||||
|
@ -365,10 +366,22 @@ impl ProblemPoser for Point {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait Regulator: Serial + ProblemPoser + OutlineItem {
|
||||
pub trait Regulator: Any + Serial + ProblemPoser + OutlineItem {
|
||||
fn subjects(&self) -> Vec<Rc<dyn Element>>;
|
||||
fn measurement(&self) -> ReadSignal<f64>;
|
||||
fn set_point(&self) -> Signal<SpecifiedValue>;
|
||||
fn set_to(&self, val: f64) {
|
||||
self.set_point().set(SpecifiedValue::from(Some(val)))
|
||||
}
|
||||
// QUESTION: Why doesn't the following work? When I used it to
|
||||
// set the coordinate regulators on pinned points, dyna3 would panic
|
||||
// when trying to nudge unpinned points :-(
|
||||
// fn set_to_current(&self) {
|
||||
// self.set_point().set(
|
||||
// SpecifiedValue::from(Some(self.measurement().get())),
|
||||
// )
|
||||
// }
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
}
|
||||
|
||||
impl Hash for dyn Regulator {
|
||||
|
@ -434,6 +447,8 @@ impl Regulator for InversiveDistanceRegulator {
|
|||
fn set_point(&self) -> Signal<SpecifiedValue> {
|
||||
self.set_point
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {self}
|
||||
}
|
||||
|
||||
impl Serial for InversiveDistanceRegulator {
|
||||
|
@ -489,6 +504,8 @@ impl Regulator for HalfCurvatureRegulator {
|
|||
fn set_point(&self) -> Signal<SpecifiedValue> {
|
||||
self.set_point
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {self}
|
||||
}
|
||||
|
||||
impl Serial for HalfCurvatureRegulator {
|
||||
|
@ -544,6 +561,7 @@ impl Regulator for PointCoordinateRegulator {
|
|||
fn subjects(&self) -> Vec<Rc<dyn Element>> { vec![self.subject.clone()] }
|
||||
fn measurement(&self) -> ReadSignal<f64> { self.measurement }
|
||||
fn set_point(&self) -> Signal<SpecifiedValue> { self.set_point }
|
||||
fn as_any(&self) -> &dyn Any {self}
|
||||
}
|
||||
|
||||
impl ProblemPoser for PointCoordinateRegulator {
|
||||
|
@ -696,9 +714,12 @@ impl Assembly {
|
|||
}
|
||||
|
||||
// create and insert the default example of `T`
|
||||
let _ = self.insert_element_unchecked(T::default(id, id_num));
|
||||
let _ = self.insert_element_unchecked(T::default(&id, id_num));
|
||||
}
|
||||
|
||||
|
||||
// FIXME: insert_element and insert_regulator are not parallel;
|
||||
// the former takes an element and calls Rc::new, inserting clones of
|
||||
// the result, whereas the latter takes an Rc and inserts clones of that
|
||||
pub fn insert_regulator(&self, regulator: Rc<dyn Regulator>) {
|
||||
// add the regulator to the assembly's regulator list
|
||||
self.regulators.update(
|
||||
|
@ -735,6 +756,11 @@ impl Assembly {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
// --- finding entities ---
|
||||
pub fn find_element(&self, id: &str) -> Rc<dyn Element> {
|
||||
self.elements_by_id.with_untracked( |elts| elts[id].clone() )
|
||||
}
|
||||
|
||||
// --- updating the configuration ---
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use itertools::izip;
|
||||
use std::{f64::consts::{FRAC_1_SQRT_2, PI}, rc::Rc};
|
||||
use std::{f64::consts::{FRAC_1_SQRT_2, PI, SQRT_2}, rc::Rc};
|
||||
use nalgebra::Vector3;
|
||||
use sycamore::prelude::*;
|
||||
use web_sys::{console, wasm_bindgen::JsValue};
|
||||
|
@ -12,6 +12,8 @@ use crate::{
|
|||
ElementColor,
|
||||
InversiveDistanceRegulator,
|
||||
Point,
|
||||
PointCoordinateRegulator,
|
||||
Regulator,
|
||||
Sphere,
|
||||
},
|
||||
engine,
|
||||
|
@ -78,6 +80,12 @@ const fn sqrt<T: const ConstSqrt>(x: T) -> f64 {x.sqr()}
|
|||
// FIXME: replace with std::f64::consts::PHI when that gets stabilized
|
||||
const PHI: f64 = (1. + sqrt(5)) / 2.;
|
||||
|
||||
const fn gray(level: f32) -> ElementColor { [level, level, level] }
|
||||
const GRAY: ElementColor = gray(0.75);
|
||||
const RED: ElementColor = [1., 0., 0.25];
|
||||
const GREEN: ElementColor = [0.25, 1., 0.];
|
||||
const BLUE: ElementColor = [0., 0.25, 1.];
|
||||
|
||||
// --- loaders ---
|
||||
|
||||
/* DEBUG */
|
||||
|
@ -88,49 +96,37 @@ const PHI: f64 = (1. + sqrt(5)) / 2.;
|
|||
fn load_general(assembly: &Assembly) {
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
String::from("gemini_a"),
|
||||
String::from("Castor"),
|
||||
[1.00_f32, 0.25_f32, 0.00_f32],
|
||||
"gemini_a", "Castor", [1.00, 0.25, 0.00],
|
||||
engine::sphere(0.5, 0.5, 0.0, 1.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
String::from("gemini_b"),
|
||||
String::from("Pollux"),
|
||||
[0.00_f32, 0.25_f32, 1.00_f32],
|
||||
"gemini_b", "Pollux", BLUE,
|
||||
engine::sphere(-0.5, -0.5, 0.0, 1.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
String::from("ursa_major"),
|
||||
String::from("Ursa major"),
|
||||
[0.25_f32, 0.00_f32, 1.00_f32],
|
||||
"ursa_major", "Ursa major", [0.25, 0.00, 1.00],
|
||||
engine::sphere(-0.5, 0.5, 0.0, 0.75),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
String::from("ursa_minor"),
|
||||
String::from("Ursa minor"),
|
||||
[0.25_f32, 1.00_f32, 0.00_f32],
|
||||
"ursa_minor", "Ursa minor", GREEN,
|
||||
engine::sphere(0.5, -0.5, 0.0, 0.5),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
String::from("moon_deimos"),
|
||||
String::from("Deimos"),
|
||||
[0.75_f32, 0.75_f32, 0.00_f32],
|
||||
"moon_deimos", "Deimos", [0.75, 0.75, 0.00],
|
||||
engine::sphere(0.0, 0.15, 1.0, 0.25),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
String::from("moon_phobos"),
|
||||
String::from("Phobos"),
|
||||
[0.00_f32, 0.75_f32, 0.50_f32],
|
||||
"moon_phobos", "Phobos", [0.00, 0.75, 0.50],
|
||||
engine::sphere(0.0, -0.15, -1.0, 0.25),
|
||||
)
|
||||
);
|
||||
|
@ -141,65 +137,49 @@ fn load_low_curvature(assembly: &Assembly) {
|
|||
const A: f64 = sqrt(0.75);
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
"central".to_string(),
|
||||
"Central".to_string(),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
"central", "Central", GRAY,
|
||||
engine::sphere(0.0, 0.0, 0.0, 1.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
"assemb_plane".to_string(),
|
||||
"Assembly plane".to_string(),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
"assemb_plane", "Assembly plane", GRAY,
|
||||
engine::sphere_with_offset(0.0, 0.0, 1.0, 0.0, 0.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
"side1".to_string(),
|
||||
"Side 1".to_string(),
|
||||
[1.00_f32, 0.00_f32, 0.25_f32],
|
||||
"side1", "Side 1", RED,
|
||||
engine::sphere_with_offset(1.0, 0.0, 0.0, 1.0, 0.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
"side2".to_string(),
|
||||
"Side 2".to_string(),
|
||||
[0.25_f32, 1.00_f32, 0.00_f32],
|
||||
"side2", "Side 2", GREEN,
|
||||
engine::sphere_with_offset(-0.5, A, 0.0, 1.0, 0.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
"side3".to_string(),
|
||||
"Side 3".to_string(),
|
||||
[0.00_f32, 0.25_f32, 1.00_f32],
|
||||
"side3", "Side 3", BLUE,
|
||||
engine::sphere_with_offset(-0.5, -A, 0.0, 1.0, 0.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
"corner1".to_string(),
|
||||
"Corner 1".to_string(),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
"corner1", "Corner 1", GRAY,
|
||||
engine::sphere(-4.0/3.0, 0.0, 0.0, 1.0/3.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
"corner2".to_string(),
|
||||
"Corner 2".to_string(),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
"corner2", "Corner 2", GRAY,
|
||||
engine::sphere(2.0/3.0, -4.0/3.0 * A, 0.0, 1.0/3.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
String::from("corner3"),
|
||||
String::from("Corner 3"),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
"corner3", "Corner 3", GRAY,
|
||||
engine::sphere(2.0/3.0, 4.0/3.0 * A, 0.0, 1.0/3.0),
|
||||
)
|
||||
);
|
||||
|
@ -207,19 +187,13 @@ fn load_low_curvature(assembly: &Assembly) {
|
|||
// impose the desired tangencies and make the sides planar
|
||||
let index_range = 1..=3;
|
||||
let [central, assemb_plane] = ["central", "assemb_plane"].map(
|
||||
|id| assembly.elements_by_id.with_untracked(
|
||||
|elts_by_id| elts_by_id[id].clone()
|
||||
)
|
||||
|id| assembly.find_element(id)
|
||||
);
|
||||
let sides = index_range.clone().map(
|
||||
|k| assembly.elements_by_id.with_untracked(
|
||||
|elts_by_id| elts_by_id[&format!("side{k}")].clone()
|
||||
)
|
||||
|k| assembly.find_element(&format!("side{k}"))
|
||||
);
|
||||
let corners = index_range.map(
|
||||
|k| assembly.elements_by_id.with_untracked(
|
||||
|elts_by_id| elts_by_id[&format!("corner{k}")].clone()
|
||||
)
|
||||
|k| assembly.find_element(&format!("corner{k}"))
|
||||
);
|
||||
for plane in [assemb_plane.clone()].into_iter().chain(sides.clone()) {
|
||||
// fix the curvature of each plane
|
||||
|
@ -279,8 +253,8 @@ fn load_pointed(assembly: &Assembly) {
|
|||
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
format!("sphere{index_x}{index_y}"),
|
||||
format!("Sphere {index_x}{index_y}"),
|
||||
&format!("sphere{index_x}{index_y}"),
|
||||
&format!("Sphere {index_x}{index_y}"),
|
||||
[0.5*(1.0 + x) as f32, 0.5*(1.0 + y) as f32, 0.5*(1.0 - x*y) as f32],
|
||||
engine::sphere(x, y, 0.0, 1.0),
|
||||
)
|
||||
|
@ -326,27 +300,23 @@ fn load_tridiminished_icosahedron(assembly: &Assembly) {
|
|||
}
|
||||
|
||||
// create the faces
|
||||
const COLOR_FACE: ElementColor = [0.75, 0.75, 0.75];
|
||||
const SQRT_1_6: f64 = invsqrt(6.);
|
||||
const SQRT_2_3: f64 = 2. * SQRT_1_6;
|
||||
let faces = [
|
||||
Sphere::new(
|
||||
"face1".to_string(),
|
||||
"Face 1".to_string(),
|
||||
COLOR_FACE,
|
||||
engine::sphere_with_offset(SQRT_2_3, -SQRT_1_6, -SQRT_1_6, -SQRT_1_6, 0.0),
|
||||
"face1", "Face 1", GRAY,
|
||||
engine::sphere_with_offset(
|
||||
SQRT_2_3, -SQRT_1_6, -SQRT_1_6, -SQRT_1_6, 0.0),
|
||||
),
|
||||
Sphere::new(
|
||||
"face2".to_string(),
|
||||
"Face 2".to_string(),
|
||||
COLOR_FACE,
|
||||
engine::sphere_with_offset(-SQRT_1_6, SQRT_2_3, -SQRT_1_6, -SQRT_1_6, 0.0),
|
||||
"face2", "Face 2", GRAY,
|
||||
engine::sphere_with_offset(
|
||||
-SQRT_1_6, SQRT_2_3, -SQRT_1_6, -SQRT_1_6, 0.0),
|
||||
),
|
||||
Sphere::new(
|
||||
"face3".to_string(),
|
||||
"Face 3".to_string(),
|
||||
COLOR_FACE,
|
||||
engine::sphere_with_offset(-SQRT_1_6, -SQRT_1_6, SQRT_2_3, -SQRT_1_6, 0.0),
|
||||
"face3", "Face 3", GRAY,
|
||||
engine::sphere_with_offset(
|
||||
-SQRT_1_6, -SQRT_1_6, SQRT_2_3, -SQRT_1_6, 0.0),
|
||||
),
|
||||
];
|
||||
for face in faces {
|
||||
|
@ -427,9 +397,7 @@ fn load_dodecahedral_packing(assembly: &Assembly) {
|
|||
// add the substrate
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
"substrate".to_string(),
|
||||
"Substrate".to_string(),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
"substrate", "Substrate", GRAY,
|
||||
engine::sphere(0.0, 0.0, 0.0, 1.0),
|
||||
)
|
||||
);
|
||||
|
@ -466,8 +434,8 @@ fn load_dodecahedral_packing(assembly: &Assembly) {
|
|||
let id_a = format!("a{id_num}");
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
id_a.clone(),
|
||||
format!("A{label_sub}"),
|
||||
&id_a,
|
||||
&format!("A{label_sub}"),
|
||||
COLOR_A,
|
||||
engine::sphere(0.0, small_coord, big_coord, FACE_RADII[k]),
|
||||
)
|
||||
|
@ -482,8 +450,8 @@ fn load_dodecahedral_packing(assembly: &Assembly) {
|
|||
let id_b = format!("b{id_num}");
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
id_b.clone(),
|
||||
format!("B{label_sub}"),
|
||||
&id_b,
|
||||
&format!("B{label_sub}"),
|
||||
COLOR_B,
|
||||
engine::sphere(small_coord, big_coord, 0.0, FACE_RADII[k]),
|
||||
)
|
||||
|
@ -498,8 +466,8 @@ fn load_dodecahedral_packing(assembly: &Assembly) {
|
|||
let id_c = format!("c{id_num}");
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
id_c.clone(),
|
||||
format!("C{label_sub}"),
|
||||
&id_c,
|
||||
&format!("C{label_sub}"),
|
||||
COLOR_C,
|
||||
engine::sphere(big_coord, 0.0, small_coord, FACE_RADII[k]),
|
||||
)
|
||||
|
@ -569,23 +537,9 @@ fn load_balanced(assembly: &Assembly) {
|
|||
const R_INNER: f64 = 4.0;
|
||||
let spheres = [
|
||||
Sphere::new(
|
||||
"outer".to_string(),
|
||||
"Outer".to_string(),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
engine::sphere(0.0, 0.0, 0.0, R_OUTER),
|
||||
),
|
||||
Sphere::new(
|
||||
"a".to_string(),
|
||||
"A".to_string(),
|
||||
[1.00_f32, 0.00_f32, 0.25_f32],
|
||||
engine::sphere(0.0, 4.0, 0.0, R_INNER),
|
||||
),
|
||||
Sphere::new(
|
||||
"b".to_string(),
|
||||
"B".to_string(),
|
||||
[0.00_f32, 0.25_f32, 1.00_f32],
|
||||
engine::sphere(0.0, -4.0, 0.0, R_INNER),
|
||||
),
|
||||
"outer","Outer", GRAY, engine::sphere(0.0, 0.0, 0.0, R_OUTER)),
|
||||
Sphere::new("a", "A", RED, engine::sphere(0.0, 4.0, 0.0, R_INNER)),
|
||||
Sphere::new("b", "B", BLUE, engine::sphere(0.0, -4.0, 0.0, R_INNER)),
|
||||
];
|
||||
for sphere in spheres {
|
||||
let _ = assembly.try_insert_element(sphere);
|
||||
|
@ -593,9 +547,7 @@ fn load_balanced(assembly: &Assembly) {
|
|||
|
||||
// get references to the spheres
|
||||
let [outer, a, b] = ["outer", "a", "b"].map(
|
||||
|id| assembly.elements_by_id.with_untracked(
|
||||
|elts_by_id| elts_by_id[id].clone()
|
||||
)
|
||||
|id| assembly.find_element(id)
|
||||
);
|
||||
|
||||
// fix the diameters of the outer, sun, and moon spheres
|
||||
|
@ -627,27 +579,22 @@ fn load_balanced(assembly: &Assembly) {
|
|||
fn load_off_center(assembly: &Assembly) {
|
||||
// create a point almost at the origin and a sphere centered on the origin
|
||||
let _ = assembly.try_insert_element(
|
||||
Point::new("point", "Point", [0.75, 0.75, 0.75], point(1e-9, 0.0, 0.0)),
|
||||
Point::new("point", "Point", GRAY, point(1e-9, 0.0, 0.0)),
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
Sphere::new(
|
||||
"sphere".to_string(),
|
||||
"Sphere".to_string(),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
engine::sphere(0.0, 0.0, 0.0, 1.0),
|
||||
),
|
||||
"sphere", "Sphere", GRAY, engine::sphere(0.0, 0.0, 0.0, 1.0)),
|
||||
);
|
||||
|
||||
|
||||
// get references to the elements
|
||||
let point_and_sphere = ["point", "sphere"].map(
|
||||
|id| assembly.elements_by_id.with_untracked(
|
||||
|elts_by_id| elts_by_id[id].clone()
|
||||
)
|
||||
|id| assembly.find_element(id)
|
||||
);
|
||||
|
||||
// put the point on the sphere
|
||||
let incidence = InversiveDistanceRegulator::new(point_and_sphere);
|
||||
incidence.set_point.set(SpecifiedValue::try_from("0".to_string()).unwrap());
|
||||
incidence.set_to(0.);
|
||||
assembly.insert_regulator(Rc::new(incidence));
|
||||
}
|
||||
|
||||
|
@ -660,18 +607,13 @@ fn load_radius_ratio(assembly: &Assembly) {
|
|||
let index_range = 1..=4;
|
||||
|
||||
// create the spheres
|
||||
const GRAY: ElementColor = [0.75, 0.75, 0.75];
|
||||
let spheres = [
|
||||
Sphere::new(
|
||||
"sphere_faces".to_string(),
|
||||
"Insphere".to_string(),
|
||||
GRAY,
|
||||
"sphere_faces", "Insphere", GRAY,
|
||||
engine::sphere(0.0, 0.0, 0.0, 0.5),
|
||||
),
|
||||
Sphere::new(
|
||||
"sphere_vertices".to_string(),
|
||||
"Circumsphere".to_string(),
|
||||
GRAY,
|
||||
"sphere_vertices", "Circumsphere", GRAY,
|
||||
engine::sphere(0.0, 0.0, 0.0, 0.25),
|
||||
),
|
||||
];
|
||||
|
@ -728,8 +670,8 @@ fn load_radius_ratio(assembly: &Assembly) {
|
|||
).map(
|
||||
|(k, color, representation)| {
|
||||
Sphere::new(
|
||||
format!("f{k}"),
|
||||
format!("Face {k}"),
|
||||
&format!("f{k}"),
|
||||
&format!("Face {k}"),
|
||||
color,
|
||||
representation,
|
||||
)
|
||||
|
@ -742,27 +684,18 @@ fn load_radius_ratio(assembly: &Assembly) {
|
|||
|
||||
// impose the constraints
|
||||
for j in index_range.clone() {
|
||||
let [face_j, vertex_j] = [
|
||||
format!("f{j}"),
|
||||
format!("v{j}"),
|
||||
].map(
|
||||
|id| assembly.elements_by_id.with_untracked(
|
||||
|elts_by_id| elts_by_id[&id].clone()
|
||||
)
|
||||
);
|
||||
let [face_j, vertex_j] = [format!("f{j}"),format!("v{j}")]
|
||||
.map(|id| assembly.find_element(&id));
|
||||
|
||||
|
||||
// make the faces planar
|
||||
let curvature_regulator = face_j.regulators().with_untracked(
|
||||
|regs| regs.first().unwrap().clone()
|
||||
);
|
||||
curvature_regulator.set_point().set(
|
||||
SpecifiedValue::try_from("0".to_string()).unwrap()
|
||||
);
|
||||
curvature_regulator.set_to(0.);
|
||||
|
||||
for k in index_range.clone().filter(|&index| index != j) {
|
||||
let vertex_k = assembly.elements_by_id.with_untracked(
|
||||
|elts_by_id| elts_by_id[&format!("v{k}")].clone()
|
||||
);
|
||||
let vertex_k = assembly.find_element(&format!("v{k}"));
|
||||
|
||||
// fix the distances between the vertices
|
||||
if j < k {
|
||||
|
@ -774,7 +707,7 @@ fn load_radius_ratio(assembly: &Assembly) {
|
|||
|
||||
// put the vertices on the faces
|
||||
let incidence_regulator = InversiveDistanceRegulator::new([face_j.clone(), vertex_k.clone()]);
|
||||
incidence_regulator.set_point.set(SpecifiedValue::try_from("0".to_string()).unwrap());
|
||||
incidence_regulator.set_to(0.);
|
||||
assembly.insert_regulator(Rc::new(incidence_regulator));
|
||||
}
|
||||
}
|
||||
|
@ -800,32 +733,26 @@ fn load_radius_ratio(assembly: &Assembly) {
|
|||
fn load_irisawa_hexlet(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],
|
||||
[1.00, 0.00, 0.25],
|
||||
[1.00, 0.25, 0.00],
|
||||
[0.75, 0.75, 0.00],
|
||||
[0.25, 1.00, 0.00],
|
||||
[0.00, 0.25, 1.00],
|
||||
[0.25, 0.00, 1.00],
|
||||
].into_iter();
|
||||
|
||||
// create the spheres
|
||||
let spheres = [
|
||||
Sphere::new(
|
||||
"outer".to_string(),
|
||||
"Outer".to_string(),
|
||||
[0.5_f32, 0.5_f32, 0.5_f32],
|
||||
"outer", "Outer", gray(0.5),
|
||||
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],
|
||||
"sun", "Sun", GRAY,
|
||||
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],
|
||||
"moon", "Moon", gray(0.25),
|
||||
engine::sphere(0.0, 0.75, 0.0, 0.75),
|
||||
),
|
||||
].into_iter().chain(
|
||||
|
@ -833,8 +760,8 @@ fn load_irisawa_hexlet(assembly: &Assembly) {
|
|||
|(k, color)| {
|
||||
let ang = (k as f64) * PI/3.0;
|
||||
Sphere::new(
|
||||
format!("chain{k}"),
|
||||
format!("Chain {k}"),
|
||||
&format!("chain{k}"),
|
||||
&format!("Chain {k}"),
|
||||
color,
|
||||
engine::sphere(1.0 * ang.sin(), 0.0, 1.0 * ang.cos(), 0.5),
|
||||
)
|
||||
|
@ -846,9 +773,7 @@ fn load_irisawa_hexlet(assembly: &Assembly) {
|
|||
}
|
||||
|
||||
// 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()
|
||||
);
|
||||
let outer = assembly.find_element("outer");
|
||||
outer.ghost().set(true);
|
||||
let outer_curvature_regulator = outer.regulators().with_untracked(
|
||||
|regs| regs.first().unwrap().clone()
|
||||
|
@ -858,15 +783,9 @@ fn load_irisawa_hexlet(assembly: &Assembly) {
|
|||
);
|
||||
|
||||
// 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 [sun, moon] = ["sun", "moon"].map(|id| assembly.find_element(id));
|
||||
let chain = index_range.map(
|
||||
|k| assembly.elements_by_id.with_untracked(
|
||||
|elts_by_id| elts_by_id[&format!("chain{k}")].clone()
|
||||
)
|
||||
|k| assembly.find_element(&format!("chain{k}"))
|
||||
);
|
||||
for (chain_sphere, chain_sphere_next) in chain.clone().zip(chain.cycle().skip(1)) {
|
||||
for (other_sphere, inversive_distance) in [
|
||||
|
@ -899,46 +818,47 @@ const F: bool = false; // Free
|
|||
// Initial data for the vertices commmon to 554aug2 and 554domed.
|
||||
// Used the Vectornaut near_miss branch final positions for 554aug2,
|
||||
// to the 3 decimal places currently shown.
|
||||
const_array!(ACRON554_COMMON: (&str, (f64, f64, f64), bool, usize, &str) = [
|
||||
const_array!(ACRON554_COMMON: (&str, [f64; 3], bool, usize, &str) = [
|
||||
// id, coordinates, Pin/Free, level, earlier neighbor IDs.
|
||||
("A_NE", ( 0.5, 0.5, 0.), P, 0, ""),
|
||||
("A_NW", (-0.5, 0.5, 0.), P, 0, ""),
|
||||
("A_SE", ( 0.5, -0.5, 0.), P, 0, ""),
|
||||
("A_SW", (-0.5, -0.5, 0.), P, 0, ""),
|
||||
("Z_E", ( 0.229, -0.002, 0.821), F, 1, "A_NE,A_SE"),
|
||||
("Z_S", ( 0.002, -0.229, 0.821), F, 1, "A_SE,A_SW"),
|
||||
("B_NE", ( HPHI, HPHI, RTHPHI), P, 2, "Z_E"),
|
||||
("B_NW", (-HPHI, HPHI, RTHPHI), P, 2, ""),
|
||||
("B_SW", (-HPHI, -HPHI, RTHPHI), P, 2, "Z_S"),
|
||||
("B_SE", ( 0.812, -0.812, 0.89), F, 2, "Z_E,Z_S"),
|
||||
("Y_NE", ( 0.11, 0.103, 1.019), F, 3, "B_NE"),
|
||||
("Y_NW", (-0.103, 0.103, 1.02), F, 3, "B_NW"),
|
||||
("Y_SE", ( 0.11, -0.11, 1.017), F, 3, "B_SE"),
|
||||
("Y_SW", (-0.103, -0.11, 1.019), F, 3, "B_SW"),
|
||||
("C_N", ( 0., 1., RTPHIPH), P, 4, "Y_NE,Y_NW"),
|
||||
("C_W", (-1., 0., RTPHIPH), P, 4, "Y_NW,Y_SW"),
|
||||
("C_E", ( 1.006, -0.006, 1.45), F, 4, "Y_NE,Y_SE"),
|
||||
("C_S", ( 0.006, -1.006, 1.45), F, 4, "Y_SE,Y_SW"),
|
||||
("D_NE", ( 0.2, 0.181, 2.011), F, 5, "Y_NE,C_N,C_E"),
|
||||
("D_NW", (-0.181, 0.181, 2.014), F, 5, "Y_NW,C_N,C_W"),
|
||||
("D_SE", ( 0.2, -0.2, 2.009), F, 5, "Y_SE,C_E,C_S"),
|
||||
("D_SW", (-0.181, -0.2, 2.011), F, 5, "Y_SW,C_W,C_S"),
|
||||
("E_N", ( 0.012, 1.055, 2.46), F, 6, "C_N,D_NE,D_NW"),
|
||||
("E_W", (-1.055, -0.012, 2.46), F, 6, "C_W,D_NW,D_SW"),
|
||||
("E_E", ( 1.079, -0.012, 2.447), F, 6, "C_E,D_NE,D_SE"),
|
||||
("E_S", ( 0.012, -1.079, 2.447), F, 6, "C_S,D_SE,D_SW"),
|
||||
("F_NE", ( 0.296, 0.265, 3.003), F, 7, "D_NE,E_N,E_E"),
|
||||
("F_NW", (-0.265, 0.265, 3.007), F, 7, "D_NW,E_N,E_W"),
|
||||
("F_SE", ( 0.296, -0.296, 3.0), F, 7, "D_SE,E_E,E_S"),
|
||||
("F_SW", (-0.265, -0.296, 3.003), F, 7, "D_SW,E_W,E_S"),
|
||||
("G_1", ( 0.517, 1.19, 3.312), F, 8, "E_N,F_NE"),
|
||||
("G_2", ( 1.224, 0.483, 3.304), F, 8, "E_E,F_NE,G_1"),
|
||||
("G_4", ( 1.224, -0.517, 3.298), F, 8, "E_E,F_SE,G_2"),
|
||||
("G_5", ( 0.517, -1.224, 3.298), F, 8, "E_S,F_SE,G_4"),
|
||||
("G_7", (-0.483, -1.224, 3.304), F, 8, "E_S,F_SW,G_5"),
|
||||
("G_8", (-1.19, -0.517, 3.312), F, 8, "E_W,F_SW,G_7"),
|
||||
("G_10", (-1.19, 0.483, 3.318), F, 8, "E_W,F_NW,G_8"),
|
||||
("G_11", (-0.483, 1.19, 3.318), F, 8, "E_N,F_NW,G_1,G_10"),
|
||||
("A_NE", [ 0.5, 0.5, 0.], P, 0, ""),
|
||||
("A_NW", [-0.5, 0.5, 0.], P, 0, ""),
|
||||
("A_SE", [ 0.5, -0.5, 0.], P, 0, ""),
|
||||
("A_SW", [-0.5, -0.5, 0.], P, 0, ""),
|
||||
("Z_E", [ 0.229, -0.002, 0.821], F, 1, "A_NE,A_SE"),
|
||||
("Z_S", [ 0.002, -0.229, 0.821], F, 1, "A_SE,A_SW"),
|
||||
("B_NE", [ HPHI, HPHI, RTHPHI], P, 2, "Z_E"),
|
||||
("B_NW", [-HPHI, HPHI, RTHPHI], P, 2, ""),
|
||||
("B_SW", [-HPHI, -HPHI, RTHPHI], P, 2, "Z_S"),
|
||||
("B_SE", [ 0.812, -0.812, 0.89], F, 2, "Z_E,Z_S"),
|
||||
("Y_NE", [ 0.11, 0.103, 1.019], F, 3, "B_NE"),
|
||||
("Y_NW", [-0.103, 0.103, 1.02], F, 3, "B_NW"),
|
||||
("Y_SE", [ 0.11, -0.11, 1.017], F, 3, "B_SE"),
|
||||
("Y_SW", [-0.103, -0.11, 1.019], F, 3, "B_SW"),
|
||||
("C_N", [ 0., 1., RTPHIPH], P, 4, "Y_NE,Y_NW"),
|
||||
("C_W", [-1., 0., RTPHIPH], P, 4, "Y_NW,Y_SW"),
|
||||
("C_E", [ 1.006, -0.006, 1.45], F, 4, "Y_NE,Y_SE"),
|
||||
("C_S", [ 0.006, -1.006, 1.45], F, 4, "Y_SE,Y_SW"),
|
||||
("D_NE", [ 0.2, 0.181, 2.011], F, 5, "Y_NE,C_N,C_E"),
|
||||
("D_NW", [-0.181, 0.181, 2.014], F, 5, "Y_NW,C_N,C_W"),
|
||||
("D_SE", [ 0.2, -0.2, 2.009], F, 5, "Y_SE,C_E,C_S"),
|
||||
("D_SW", [-0.181, -0.2, 2.011], F, 5, "Y_SW,C_W,C_S"),
|
||||
("E_N", [ 0.012, 1.055, 2.46], F, 6, "C_N,D_NE,D_NW"),
|
||||
("E_W", [-1.055, -0.012, 2.46], F, 6, "C_W,D_NW,D_SW"),
|
||||
("E_E", [ 1.079, -0.012, 2.447], F, 6, "C_E,D_NE,D_SE"),
|
||||
("E_S", [ 0.012, -1.079, 2.447], F, 6, "C_S,D_SE,D_SW"),
|
||||
("F_NE", [ 0.296, 0.265, 3.003], F, 7, "D_NE,E_N,E_E"),
|
||||
("F_NW", [-0.265, 0.265, 3.007], F, 7, "D_NW,E_N,E_W"),
|
||||
("F_SE", [ 0.296, -0.296, 3.0], F, 7, "D_SE,E_E,E_S"),
|
||||
("F_SW", [-0.265, -0.296, 3.003], F, 7, "D_SW,E_W,E_S"),
|
||||
// The following must be in order around the octagon (in some orientation)
|
||||
("G_1", [ 0.517, 1.19, 3.312], F, 8, "E_N,F_NE"),
|
||||
("G_2", [ 1.224, 0.483, 3.304], F, 8, "E_E,F_NE"),
|
||||
("G_4", [ 1.224, -0.517, 3.298], F, 8, "E_E,F_SE"),
|
||||
("G_5", [ 0.517, -1.224, 3.298], F, 8, "E_S,F_SE"),
|
||||
("G_7", [-0.483, -1.224, 3.304], F, 8, "E_S,F_SW"),
|
||||
("G_8", [-1.19, -0.517, 3.312], F, 8, "E_W,F_SW"),
|
||||
("G_10", [-1.19, 0.483, 3.318], F, 8, "E_W,F_NW"),
|
||||
("G_11", [-0.483, 1.19, 3.318], F, 8, "E_N,F_NW"),
|
||||
]);
|
||||
|
||||
const_array!(LEVEL_COLORS: ElementColor = [
|
||||
|
@ -954,9 +874,83 @@ const_array!(LEVEL_COLORS: ElementColor = [
|
|||
]);
|
||||
|
||||
fn load_554aug2(assembly: &Assembly) {
|
||||
for (id, v, _pinned, level, _neighbors) in ACRON554_COMMON {
|
||||
let pt = Point::new(id, id, LEVEL_COLORS[level], point(v.0, v.1, v.2));
|
||||
// first a plane for the octagon
|
||||
let oct_id = "f_g";
|
||||
let engsph = engine::sphere_with_offset(
|
||||
0., 0., 1., ACRON554_COMMON[37].1[2], 0.);
|
||||
let octaface = Sphere::new(oct_id, "Octagon", [0.7, 0.7, 0.7], engsph);
|
||||
octaface.ghost().set(true);
|
||||
assembly.try_insert_element(octaface);
|
||||
let face_rc = assembly.find_element(oct_id);
|
||||
let face_curvature = face_rc.regulators().with_untracked(
|
||||
|regs| regs.first().unwrap().clone()
|
||||
);
|
||||
face_curvature.set_to(0.);
|
||||
// Octagon vertices and side/diagonal lengths
|
||||
let mut oct_verts = Vec::<Rc<dyn Element>>::new();
|
||||
const OCT_LONG: usize = 4;
|
||||
const OCT_N_DIAG: usize = 5;
|
||||
const OCT_N: usize = 8;
|
||||
const OCT_DIST: [f64; OCT_N_DIAG] = [0., // dummy at start
|
||||
-0.5,
|
||||
-0.5*(2. + SQRT_2),
|
||||
-0.5*(3. + 2.*SQRT_2),
|
||||
-0.5*(4. + 2.*SQRT_2)
|
||||
];
|
||||
// Now process the acron data
|
||||
for (id, v, pinned, l, _neighbors) in ACRON554_COMMON {
|
||||
let pt = Point::new(id, id, LEVEL_COLORS[l], point(v[0], v[1], v[2]));
|
||||
assembly.try_insert_element(pt);
|
||||
if pinned { // regulate each coordinate to its given value
|
||||
let mut freeze = Vec::<Rc<dyn Regulator>>::new();
|
||||
// QUESTION: Would there be a way to insert an Rc<Element> into
|
||||
// an assembly to avoid the need to re-lookup pt in the assembly
|
||||
// after just inserting it?
|
||||
let pt_rc = assembly.elements_by_id.with_untracked(
|
||||
|elts| elts[id].clone()
|
||||
);
|
||||
// filter the three coordinate regulators into freeze
|
||||
pt_rc.regulators().with_untracked( |regs| {
|
||||
for reg in regs {
|
||||
if let Some(_pcr) = reg
|
||||
.as_any().downcast_ref::<PointCoordinateRegulator>() {
|
||||
freeze.push(reg.clone())
|
||||
}
|
||||
}
|
||||
});
|
||||
// now set them to their originally specified values.
|
||||
let mut coord: usize = 0;
|
||||
for reg in freeze {
|
||||
reg.set_to(v[coord]);
|
||||
coord += 1;
|
||||
}
|
||||
}
|
||||
// If part of the octagon, make incident to the plane:
|
||||
if l == 8 {
|
||||
let pt_rc = assembly.find_element(id);
|
||||
let oct_index = oct_verts.len();
|
||||
oct_verts.push(pt_rc.clone());
|
||||
let incidence = InversiveDistanceRegulator::new(
|
||||
[face_rc.clone(), pt_rc.clone()]);
|
||||
incidence.set_to(0.0);
|
||||
assembly.insert_regulator(Rc::new(incidence));
|
||||
// And regulate the length to the other vertices of the octagon
|
||||
for offset in 1..OCT_N_DIAG {
|
||||
if offset <= oct_index {
|
||||
let dist = InversiveDistanceRegulator::new(
|
||||
[oct_verts[oct_index - offset].clone(), pt_rc.clone()]);
|
||||
dist.set_to(OCT_DIST[offset]);
|
||||
assembly.insert_regulator(Rc::new(dist));
|
||||
}
|
||||
if offset < OCT_LONG && oct_index + offset >= OCT_N {
|
||||
let forward = oct_index + offset - OCT_N;
|
||||
let dist = InversiveDistanceRegulator::new(
|
||||
[oct_verts[forward].clone(), pt_rc.clone()]);
|
||||
dist.set_to(OCT_DIST[offset]);
|
||||
assembly.insert_regulator(Rc::new(dist));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue