forked from StudioInfinity/dyna3
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.
This commit is contained in:
parent
a671a8273a
commit
f4e5c34fde
2 changed files with 31 additions and 14 deletions
|
@ -1,6 +1,5 @@
|
||||||
use nalgebra::{DMatrix, DVector, DVectorView};
|
use nalgebra::{DMatrix, DVector, DVectorView};
|
||||||
use std::{
|
use std::{
|
||||||
any::{Any, TypeId},
|
|
||||||
cell::Cell,
|
cell::Cell,
|
||||||
collections::{BTreeMap, BTreeSet},
|
collections::{BTreeMap, BTreeSet},
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
|
@ -19,6 +18,8 @@ use crate::{
|
||||||
Q,
|
Q,
|
||||||
change_half_curvature,
|
change_half_curvature,
|
||||||
local_unif_to_std,
|
local_unif_to_std,
|
||||||
|
normalize_mut_point,
|
||||||
|
normalize_mut_sphere,
|
||||||
point,
|
point,
|
||||||
realize_gram,
|
realize_gram,
|
||||||
sphere,
|
sphere,
|
||||||
|
@ -107,6 +108,9 @@ pub trait Element: Serial + ProblemPoser + DisplayItem {
|
||||||
// element is responsible for keeping this set up to date
|
// element is responsible for keeping this set up to date
|
||||||
fn regulators(&self) -> Signal<BTreeSet<Rc<dyn Regulator>>>;
|
fn regulators(&self) -> Signal<BTreeSet<Rc<dyn Regulator>>>;
|
||||||
|
|
||||||
|
// normalize a representation vector for this kind of element
|
||||||
|
fn normalize_mut_rep(&self, rep: &mut DVector<f64>);
|
||||||
|
|
||||||
// the configuration matrix column index that was assigned to the element
|
// the configuration matrix column index that was assigned to the element
|
||||||
// last time the assembly was realized, or `None` if the element has never
|
// last time the assembly was realized, or `None` if the element has never
|
||||||
// been through a realization
|
// been through a realization
|
||||||
|
@ -221,6 +225,10 @@ impl Element for Sphere {
|
||||||
self.regulators
|
self.regulators
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn normalize_mut_rep(&self, rep: &mut DVector<f64>) {
|
||||||
|
normalize_mut_sphere(rep);
|
||||||
|
}
|
||||||
|
|
||||||
fn column_index(&self) -> Option<usize> {
|
fn column_index(&self) -> Option<usize> {
|
||||||
self.column_index.get()
|
self.column_index.get()
|
||||||
}
|
}
|
||||||
|
@ -313,6 +321,10 @@ impl Element for Point {
|
||||||
self.regulators
|
self.regulators
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn normalize_mut_rep(&self, rep: &mut DVector<f64>) {
|
||||||
|
normalize_mut_point(rep);
|
||||||
|
}
|
||||||
|
|
||||||
fn column_index(&self) -> Option<usize> {
|
fn column_index(&self) -> Option<usize> {
|
||||||
self.column_index.get()
|
self.column_index.get()
|
||||||
}
|
}
|
||||||
|
@ -782,24 +794,14 @@ impl Assembly {
|
||||||
|
|
||||||
// step the assembly along the deformation. this changes the elements'
|
// step the assembly along the deformation. this changes the elements'
|
||||||
// normalizations, so we restore those afterward
|
// normalizations, so we restore those afterward
|
||||||
/* KLUDGE */
|
|
||||||
// for now, we only restore the normalizations of spheres
|
|
||||||
for elt in self.elements.get_clone_untracked() {
|
for elt in self.elements.get_clone_untracked() {
|
||||||
elt.representation().update_silent(|rep| {
|
elt.representation().update_silent(|rep| {
|
||||||
match elt.column_index() {
|
match elt.column_index() {
|
||||||
Some(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);
|
*rep += motion_proj.column(column_index);
|
||||||
|
elt.normalize_mut_rep(rep);
|
||||||
if elt.type_id() == TypeId::of::<Sphere>() {
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
console::log_1(&JsValue::from(
|
console::log_1(&JsValue::from(
|
||||||
|
|
|
@ -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<f64>) {
|
||||||
|
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<f64>) {
|
||||||
|
rep.scale_mut(0.5 / rep[3]);
|
||||||
|
}
|
||||||
|
|
||||||
// given a sphere's representation vector, change the sphere's half-curvature to
|
// given a sphere's representation vector, change the sphere's half-curvature to
|
||||||
// `half-curv` and then restore normalization by contracting the representation
|
// `half-curv` and then restore normalization by contracting the representation
|
||||||
// vector toward the curvature axis
|
// vector toward the curvature axis
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue