From f4e5c34fde35e5fe2eaa71d0f9d6fb5a7abb1d3d Mon Sep 17 00:00:00 2001 From: Aaron Fenyes Date: Mon, 19 May 2025 18:54:45 -0700 Subject: [PATCH] Add a trait method to normalize representations This corrects the dispatching of the normalization routine for spheres, and it adds a (perhaps redundant) normalization routine for points. --- app-proto/src/assembly.rs | 30 ++++++++++++++++-------------- app-proto/src/engine.rs | 15 +++++++++++++++ 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/app-proto/src/assembly.rs b/app-proto/src/assembly.rs index e48b802..0aa6dab 100644 --- a/app-proto/src/assembly.rs +++ b/app-proto/src/assembly.rs @@ -1,6 +1,5 @@ use nalgebra::{DMatrix, DVector, DVectorView}; use std::{ - any::{Any, TypeId}, cell::Cell, collections::{BTreeMap, BTreeSet}, cmp::Ordering, @@ -19,6 +18,8 @@ use crate::{ Q, change_half_curvature, local_unif_to_std, + normalize_mut_point, + normalize_mut_sphere, point, realize_gram, sphere, @@ -107,6 +108,9 @@ pub trait Element: Serial + ProblemPoser + DisplayItem { // element is responsible for keeping this set up to date fn regulators(&self) -> Signal>>; + // normalize a representation vector for this kind of element + fn normalize_mut_rep(&self, rep: &mut DVector); + // the configuration matrix column index that was assigned to the element // last time the assembly was realized, or `None` if the element has never // been through a realization @@ -221,6 +225,10 @@ impl Element for Sphere { self.regulators } + fn normalize_mut_rep(&self, rep: &mut DVector) { + normalize_mut_sphere(rep); + } + fn column_index(&self) -> Option { self.column_index.get() } @@ -313,6 +321,10 @@ impl Element for Point { self.regulators } + fn normalize_mut_rep(&self, rep: &mut DVector) { + normalize_mut_point(rep); + } + fn column_index(&self) -> Option { self.column_index.get() } @@ -782,24 +794,14 @@ impl Assembly { // step the assembly along the deformation. this changes the elements' // normalizations, so we restore those afterward - /* KLUDGE */ - // for now, we only restore the normalizations of spheres for elt in self.elements.get_clone_untracked() { elt.representation().update_silent(|rep| { match elt.column_index() { Some(column_index) => { - // step the assembly along the deformation + // step the element along the deformation and then + // restore its normalization *rep += motion_proj.column(column_index); - - if elt.type_id() == TypeId::of::() { - // restore normalization by contracting toward the - // last coordinate axis - let q_sp = rep.fixed_rows::<3>(0).norm_squared(); - let half_q_lt = -2.0 * rep[3] * rep[4]; - let half_q_lt_sq = half_q_lt * half_q_lt; - let scaling = half_q_lt + (q_sp + half_q_lt_sq).sqrt(); - rep.fixed_rows_mut::<4>(0).scale_mut(1.0 / scaling); - } + elt.normalize_mut_rep(rep); }, None => { console::log_1(&JsValue::from( diff --git a/app-proto/src/engine.rs b/app-proto/src/engine.rs index b0fa23d..7bc2bdc 100644 --- a/app-proto/src/engine.rs +++ b/app-proto/src/engine.rs @@ -34,6 +34,21 @@ pub fn sphere_with_offset(dir_x: f64, dir_y: f64, dir_z: f64, off: f64, curv: f6 ]) } +// normalize a sphere's representation vector by contracting toward the last +// coordinate axis +pub fn normalize_mut_sphere(rep: &mut DVector) { + let q_sp = rep.fixed_rows::<3>(0).norm_squared(); + let half_q_lt = -2.0 * rep[3] * rep[4]; + let half_q_lt_sq = half_q_lt * half_q_lt; + let scaling = half_q_lt + (q_sp + half_q_lt_sq).sqrt(); + rep.fixed_rows_mut::<4>(0).scale_mut(1.0 / scaling); +} + +// normalize a point's representation vector by scaling +pub fn normalize_mut_point(rep: &mut DVector) { + rep.scale_mut(0.5 / rep[3]); +} + // given a sphere's representation vector, change the sphere's half-curvature to // `half-curv` and then restore normalization by contracting the representation // vector toward the curvature axis