Rename the Element
structure to Sphere
This makes way for an `Element` trait. Some `Sphere` variables, like the arguments of the sphere insertion methods, have been renamed to show that they refer specifically to spheres. Others, like the argument of `ElementOutlineItem`, have kept their general names, because I expect them to become `Element` trait objects.
This commit is contained in:
parent
68abc2ad44
commit
a1e23543cb
4 changed files with 41 additions and 41 deletions
|
@ -4,7 +4,7 @@ use web_sys::{console, wasm_bindgen::JsValue};
|
||||||
use crate::{
|
use crate::{
|
||||||
engine,
|
engine,
|
||||||
AppState,
|
AppState,
|
||||||
assembly::{Assembly, Element, InversiveDistanceRegulator}
|
assembly::{Assembly, InversiveDistanceRegulator, Sphere}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* DEBUG */
|
/* DEBUG */
|
||||||
|
@ -12,7 +12,7 @@ use crate::{
|
||||||
// built a more formal test assembly system
|
// built a more formal test assembly system
|
||||||
fn load_gen_assemb(assembly: &Assembly) {
|
fn load_gen_assemb(assembly: &Assembly) {
|
||||||
let _ = assembly.try_insert_sphere(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Sphere::new(
|
||||||
String::from("gemini_a"),
|
String::from("gemini_a"),
|
||||||
String::from("Castor"),
|
String::from("Castor"),
|
||||||
[1.00_f32, 0.25_f32, 0.00_f32],
|
[1.00_f32, 0.25_f32, 0.00_f32],
|
||||||
|
@ -20,7 +20,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_sphere(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Sphere::new(
|
||||||
String::from("gemini_b"),
|
String::from("gemini_b"),
|
||||||
String::from("Pollux"),
|
String::from("Pollux"),
|
||||||
[0.00_f32, 0.25_f32, 1.00_f32],
|
[0.00_f32, 0.25_f32, 1.00_f32],
|
||||||
|
@ -28,7 +28,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_sphere(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Sphere::new(
|
||||||
String::from("ursa_major"),
|
String::from("ursa_major"),
|
||||||
String::from("Ursa major"),
|
String::from("Ursa major"),
|
||||||
[0.25_f32, 0.00_f32, 1.00_f32],
|
[0.25_f32, 0.00_f32, 1.00_f32],
|
||||||
|
@ -36,7 +36,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_sphere(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Sphere::new(
|
||||||
String::from("ursa_minor"),
|
String::from("ursa_minor"),
|
||||||
String::from("Ursa minor"),
|
String::from("Ursa minor"),
|
||||||
[0.25_f32, 1.00_f32, 0.00_f32],
|
[0.25_f32, 1.00_f32, 0.00_f32],
|
||||||
|
@ -44,7 +44,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_sphere(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Sphere::new(
|
||||||
String::from("moon_deimos"),
|
String::from("moon_deimos"),
|
||||||
String::from("Deimos"),
|
String::from("Deimos"),
|
||||||
[0.75_f32, 0.75_f32, 0.00_f32],
|
[0.75_f32, 0.75_f32, 0.00_f32],
|
||||||
|
@ -52,7 +52,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_sphere(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Sphere::new(
|
||||||
String::from("moon_phobos"),
|
String::from("moon_phobos"),
|
||||||
String::from("Phobos"),
|
String::from("Phobos"),
|
||||||
[0.00_f32, 0.75_f32, 0.50_f32],
|
[0.00_f32, 0.75_f32, 0.50_f32],
|
||||||
|
@ -67,7 +67,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
||||||
fn load_low_curv_assemb(assembly: &Assembly) {
|
fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
let a = 0.75_f64.sqrt();
|
let a = 0.75_f64.sqrt();
|
||||||
let _ = assembly.try_insert_sphere(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Sphere::new(
|
||||||
"central".to_string(),
|
"central".to_string(),
|
||||||
"Central".to_string(),
|
"Central".to_string(),
|
||||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||||
|
@ -75,7 +75,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_sphere(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Sphere::new(
|
||||||
"assemb_plane".to_string(),
|
"assemb_plane".to_string(),
|
||||||
"Assembly plane".to_string(),
|
"Assembly plane".to_string(),
|
||||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||||
|
@ -83,7 +83,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_sphere(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Sphere::new(
|
||||||
"side1".to_string(),
|
"side1".to_string(),
|
||||||
"Side 1".to_string(),
|
"Side 1".to_string(),
|
||||||
[1.00_f32, 0.00_f32, 0.25_f32],
|
[1.00_f32, 0.00_f32, 0.25_f32],
|
||||||
|
@ -91,7 +91,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_sphere(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Sphere::new(
|
||||||
"side2".to_string(),
|
"side2".to_string(),
|
||||||
"Side 2".to_string(),
|
"Side 2".to_string(),
|
||||||
[0.25_f32, 1.00_f32, 0.00_f32],
|
[0.25_f32, 1.00_f32, 0.00_f32],
|
||||||
|
@ -99,7 +99,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_sphere(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Sphere::new(
|
||||||
"side3".to_string(),
|
"side3".to_string(),
|
||||||
"Side 3".to_string(),
|
"Side 3".to_string(),
|
||||||
[0.00_f32, 0.25_f32, 1.00_f32],
|
[0.00_f32, 0.25_f32, 1.00_f32],
|
||||||
|
@ -107,7 +107,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_sphere(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Sphere::new(
|
||||||
"corner1".to_string(),
|
"corner1".to_string(),
|
||||||
"Corner 1".to_string(),
|
"Corner 1".to_string(),
|
||||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||||
|
@ -115,7 +115,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_sphere(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Sphere::new(
|
||||||
"corner2".to_string(),
|
"corner2".to_string(),
|
||||||
"Corner 2".to_string(),
|
"Corner 2".to_string(),
|
||||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||||
|
@ -123,7 +123,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let _ = assembly.try_insert_sphere(
|
let _ = assembly.try_insert_sphere(
|
||||||
Element::new(
|
Sphere::new(
|
||||||
String::from("corner3"),
|
String::from("corner3"),
|
||||||
String::from("Corner 3"),
|
String::from("Corner 3"),
|
||||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||||
|
|
|
@ -33,11 +33,11 @@ pub type ElementColor = [f32; 3];
|
||||||
static NEXT_ELEMENT_SERIAL: AtomicU64 = AtomicU64::new(0);
|
static NEXT_ELEMENT_SERIAL: AtomicU64 = AtomicU64::new(0);
|
||||||
|
|
||||||
pub trait ProblemPoser {
|
pub trait ProblemPoser {
|
||||||
fn pose(&self, problem: &mut ConstraintProblem, elts: &Slab<Element>);
|
fn pose(&self, problem: &mut ConstraintProblem, elts: &Slab<Sphere>);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub struct Element {
|
pub struct Sphere {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub label: String,
|
pub label: String,
|
||||||
pub color: ElementColor,
|
pub color: ElementColor,
|
||||||
|
@ -57,7 +57,7 @@ pub struct Element {
|
||||||
column_index: Option<usize>
|
column_index: Option<usize>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Element {
|
impl Sphere {
|
||||||
const CURVATURE_COMPONENT: usize = 3;
|
const CURVATURE_COMPONENT: usize = 3;
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
@ -65,7 +65,7 @@ impl Element {
|
||||||
label: String,
|
label: String,
|
||||||
color: ElementColor,
|
color: ElementColor,
|
||||||
representation: DVector<f64>
|
representation: DVector<f64>
|
||||||
) -> Element {
|
) -> Sphere {
|
||||||
// take the next serial number, panicking if that was the last number we
|
// take the next serial number, panicking if that was the last number we
|
||||||
// had left. the technique we use to panic on overflow is taken from
|
// had left. the technique we use to panic on overflow is taken from
|
||||||
// _Rust Atomics and Locks_, by Mara Bos
|
// _Rust Atomics and Locks_, by Mara Bos
|
||||||
|
@ -77,7 +77,7 @@ impl Element {
|
||||||
|serial| serial.checked_add(1)
|
|serial| serial.checked_add(1)
|
||||||
).expect("Out of serial numbers for elements");
|
).expect("Out of serial numbers for elements");
|
||||||
|
|
||||||
Element {
|
Sphere {
|
||||||
id: id,
|
id: id,
|
||||||
label: label,
|
label: label,
|
||||||
color: color,
|
color: color,
|
||||||
|
@ -132,10 +132,10 @@ impl Element {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProblemPoser for Element {
|
impl ProblemPoser for Sphere {
|
||||||
fn pose(&self, problem: &mut ConstraintProblem, _elts: &Slab<Element>) {
|
fn pose(&self, problem: &mut ConstraintProblem, _elts: &Slab<Sphere>) {
|
||||||
let index = self.column_index.expect(
|
let index = self.column_index.expect(
|
||||||
format!("Element \"{}\" should be indexed before writing problem data", self.id).as_str()
|
format!("Sphere \"{}\" should be indexed before writing problem data", self.id).as_str()
|
||||||
);
|
);
|
||||||
problem.gram.push_sym(index, index, 1.0);
|
problem.gram.push_sym(index, index, 1.0);
|
||||||
problem.guess.set_column(index, &self.representation.get_clone_untracked());
|
problem.guess.set_column(index, &self.representation.get_clone_untracked());
|
||||||
|
@ -198,7 +198,7 @@ impl Regulator for InversiveDistanceRegulator {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProblemPoser for InversiveDistanceRegulator {
|
impl ProblemPoser for InversiveDistanceRegulator {
|
||||||
fn pose(&self, problem: &mut ConstraintProblem, elts: &Slab<Element>) {
|
fn pose(&self, problem: &mut ConstraintProblem, elts: &Slab<Sphere>) {
|
||||||
self.set_point.with_untracked(|set_pt| {
|
self.set_point.with_untracked(|set_pt| {
|
||||||
if let Some(val) = set_pt.value {
|
if let Some(val) = set_pt.value {
|
||||||
let [row, col] = self.subjects.map(
|
let [row, col] = self.subjects.map(
|
||||||
|
@ -222,7 +222,7 @@ impl HalfCurvatureRegulator {
|
||||||
pub fn new(subject: ElementKey, assembly: &Assembly) -> HalfCurvatureRegulator {
|
pub fn new(subject: ElementKey, assembly: &Assembly) -> HalfCurvatureRegulator {
|
||||||
let measurement = assembly.elements.map(
|
let measurement = assembly.elements.map(
|
||||||
move |elts| elts[subject].representation.with(
|
move |elts| elts[subject].representation.with(
|
||||||
|rep| rep[Element::CURVATURE_COMPONENT]
|
|rep| rep[Sphere::CURVATURE_COMPONENT]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -262,13 +262,13 @@ impl Regulator for HalfCurvatureRegulator {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProblemPoser for HalfCurvatureRegulator {
|
impl ProblemPoser for HalfCurvatureRegulator {
|
||||||
fn pose(&self, problem: &mut ConstraintProblem, elts: &Slab<Element>) {
|
fn pose(&self, problem: &mut ConstraintProblem, elts: &Slab<Sphere>) {
|
||||||
self.set_point.with_untracked(|set_pt| {
|
self.set_point.with_untracked(|set_pt| {
|
||||||
if let Some(val) = set_pt.value {
|
if let Some(val) = set_pt.value {
|
||||||
let col = elts[self.subject].column_index.expect(
|
let col = elts[self.subject].column_index.expect(
|
||||||
"Subject should be indexed before half-curvature regulator writes problem data"
|
"Subject should be indexed before half-curvature regulator writes problem data"
|
||||||
);
|
);
|
||||||
problem.frozen.push(Element::CURVATURE_COMPONENT, col, val);
|
problem.frozen.push(Sphere::CURVATURE_COMPONENT, col, val);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -286,7 +286,7 @@ type AssemblyMotion<'a> = Vec<ElementMotion<'a>>;
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Assembly {
|
pub struct Assembly {
|
||||||
// elements and regulators
|
// elements and regulators
|
||||||
pub elements: Signal<Slab<Element>>,
|
pub elements: Signal<Slab<Sphere>>,
|
||||||
pub regulators: Signal<Slab<Rc<dyn Regulator>>>,
|
pub regulators: Signal<Slab<Rc<dyn Regulator>>>,
|
||||||
|
|
||||||
// solution variety tangent space. the basis vectors are stored in
|
// solution variety tangent space. the basis vectors are stored in
|
||||||
|
@ -320,10 +320,10 @@ impl Assembly {
|
||||||
// insert a sphere into the assembly without checking whether we already
|
// insert a sphere into the assembly without checking whether we already
|
||||||
// have an element with the same identifier. any element that does have the
|
// have an element with the same identifier. any element that does have the
|
||||||
// same identifier will get kicked out of the `elements_by_id` index
|
// same identifier will get kicked out of the `elements_by_id` index
|
||||||
fn insert_sphere_unchecked(&self, elt: Element) -> ElementKey {
|
fn insert_sphere_unchecked(&self, sphere: Sphere) -> ElementKey {
|
||||||
// insert the sphere
|
// insert the sphere
|
||||||
let id = elt.id.clone();
|
let id = sphere.id.clone();
|
||||||
let key = self.elements.update(|elts| elts.insert(elt));
|
let key = self.elements.update(|elts| elts.insert(sphere));
|
||||||
self.elements_by_id.update(|elts_by_id| elts_by_id.insert(id, key));
|
self.elements_by_id.update(|elts_by_id| elts_by_id.insert(id, key));
|
||||||
|
|
||||||
// regulate the sphere's curvature
|
// regulate the sphere's curvature
|
||||||
|
@ -332,12 +332,12 @@ impl Assembly {
|
||||||
key
|
key
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_insert_sphere(&self, elt: Element) -> Option<ElementKey> {
|
pub fn try_insert_sphere(&self, sphere: Sphere) -> Option<ElementKey> {
|
||||||
let can_insert = self.elements_by_id.with_untracked(
|
let can_insert = self.elements_by_id.with_untracked(
|
||||||
|elts_by_id| !elts_by_id.contains_key(&elt.id)
|
|elts_by_id| !elts_by_id.contains_key(&sphere.id)
|
||||||
);
|
);
|
||||||
if can_insert {
|
if can_insert {
|
||||||
Some(self.insert_sphere_unchecked(elt))
|
Some(self.insert_sphere_unchecked(sphere))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -356,7 +356,7 @@ impl Assembly {
|
||||||
|
|
||||||
// create and insert a sphere
|
// create and insert a sphere
|
||||||
let _ = self.insert_sphere_unchecked(
|
let _ = self.insert_sphere_unchecked(
|
||||||
Element::new(
|
Sphere::new(
|
||||||
id,
|
id,
|
||||||
format!("Sphere {}", id_num),
|
format!("Sphere {}", id_num),
|
||||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||||
|
@ -607,10 +607,10 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "Element \"sphere\" should be indexed before writing problem data")]
|
#[should_panic(expected = "Sphere \"sphere\" should be indexed before writing problem data")]
|
||||||
fn unindexed_element_test() {
|
fn unindexed_element_test() {
|
||||||
let _ = create_root(|| {
|
let _ = create_root(|| {
|
||||||
Element::new(
|
Sphere::new(
|
||||||
"sphere".to_string(),
|
"sphere".to_string(),
|
||||||
"Sphere".to_string(),
|
"Sphere".to_string(),
|
||||||
[1.0_f32, 1.0_f32, 1.0_f32],
|
[1.0_f32, 1.0_f32, 1.0_f32],
|
||||||
|
@ -626,7 +626,7 @@ mod tests {
|
||||||
let mut elts = Slab::new();
|
let mut elts = Slab::new();
|
||||||
let subjects = [0, 1].map(|k| {
|
let subjects = [0, 1].map(|k| {
|
||||||
elts.insert(
|
elts.insert(
|
||||||
Element::new(
|
Sphere::new(
|
||||||
format!("sphere{k}"),
|
format!("sphere{k}"),
|
||||||
format!("Sphere {k}"),
|
format!("Sphere {k}"),
|
||||||
[1.0_f32, 1.0_f32, 1.0_f32],
|
[1.0_f32, 1.0_f32, 1.0_f32],
|
||||||
|
|
|
@ -14,7 +14,7 @@ use web_sys::{
|
||||||
wasm_bindgen::{JsCast, JsValue}
|
wasm_bindgen::{JsCast, JsValue}
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{AppState, assembly::{Element, ElementKey, ElementColor, ElementMotion}};
|
use crate::{AppState, assembly::{ElementKey, ElementColor, ElementMotion, Sphere}};
|
||||||
|
|
||||||
// --- scene data ---
|
// --- scene data ---
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ trait DisplayItem {
|
||||||
fn show(&self, scene: &mut Scene, selected: bool);
|
fn show(&self, scene: &mut Scene, selected: bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DisplayItem for Element {
|
impl DisplayItem for Sphere {
|
||||||
fn show(&self, scene: &mut Scene, selected: bool) {
|
fn show(&self, scene: &mut Scene, selected: bool) {
|
||||||
const HIGHLIGHT: f32 = 0.2; /* SCAFFOLDING */
|
const HIGHLIGHT: f32 = 0.2; /* SCAFFOLDING */
|
||||||
let representation = self.representation.get_clone_untracked();
|
let representation = self.representation.get_clone_untracked();
|
||||||
|
|
|
@ -141,7 +141,7 @@ fn RegulatorOutlineItem(regulator_key: RegulatorKey, element_key: ElementKey) ->
|
||||||
|
|
||||||
// a list item that shows an element in an outline view of an assembly
|
// a list item that shows an element in an outline view of an assembly
|
||||||
#[component(inline_props)]
|
#[component(inline_props)]
|
||||||
fn ElementOutlineItem(key: ElementKey, element: assembly::Element) -> View {
|
fn ElementOutlineItem(key: ElementKey, element: assembly::Sphere) -> View {
|
||||||
let state = use_context::<AppState>();
|
let state = use_context::<AppState>();
|
||||||
let class = state.selection.map(
|
let class = state.selection.map(
|
||||||
move |sel| if sel.contains(&key) { "selected" } else { "" }
|
move |sel| if sel.contains(&key) { "selected" } else { "" }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue