Compare commits
1 commit
main
...
pointCoord
Author | SHA1 | Date | |
---|---|---|---|
ecbbe2068c |
5 changed files with 117 additions and 5 deletions
21
app-proto/Cargo.lock
generated
21
app-proto/Cargo.lock
generated
|
@ -255,6 +255,7 @@ dependencies = [
|
||||||
"charming",
|
"charming",
|
||||||
"console_error_panic_hook",
|
"console_error_panic_hook",
|
||||||
"dyna3",
|
"dyna3",
|
||||||
|
"enum-iterator",
|
||||||
"itertools",
|
"itertools",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
@ -271,6 +272,26 @@ version = "1.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enum-iterator"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4549325971814bda7a44061bf3fe7e487d447cba01e4220a4b454d630d7a016"
|
||||||
|
dependencies = [
|
||||||
|
"enum-iterator-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enum-iterator-derive"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
|
|
@ -10,6 +10,7 @@ default = ["console_error_panic_hook"]
|
||||||
dev = []
|
dev = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
enum-iterator = "2.3.0"
|
||||||
itertools = "0.13.0"
|
itertools = "0.13.0"
|
||||||
js-sys = "0.3.70"
|
js-sys = "0.3.70"
|
||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use enum_iterator::{all, Sequence};
|
||||||
use nalgebra::{DMatrix, DVector, DVectorView};
|
use nalgebra::{DMatrix, DVector, DVectorView};
|
||||||
use std::{
|
use std::{
|
||||||
cell::Cell,
|
cell::Cell,
|
||||||
|
@ -26,6 +27,7 @@ use crate::{
|
||||||
ConfigSubspace,
|
ConfigSubspace,
|
||||||
ConstraintProblem,
|
ConstraintProblem,
|
||||||
DescentHistory,
|
DescentHistory,
|
||||||
|
MatrixEntry,
|
||||||
Realization,
|
Realization,
|
||||||
},
|
},
|
||||||
specified::SpecifiedValue,
|
specified::SpecifiedValue,
|
||||||
|
@ -269,6 +271,7 @@ pub struct Point {
|
||||||
|
|
||||||
impl Point {
|
impl Point {
|
||||||
const WEIGHT_COMPONENT: usize = 3;
|
const WEIGHT_COMPONENT: usize = 3;
|
||||||
|
const NORM_COMPONENT: usize = 4;
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
id: String,
|
id: String,
|
||||||
|
@ -302,6 +305,15 @@ impl Element for Point {
|
||||||
point(0.0, 0.0, 0.0),
|
point(0.0, 0.0, 0.0),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_regulators(self: Rc<Self>) -> Vec<Rc<dyn Regulator>> {
|
||||||
|
all::<Axis>()
|
||||||
|
.map(|axis| {
|
||||||
|
Rc::new(PointCoordinateRegulator::new(self.clone(), axis))
|
||||||
|
as Rc::<dyn Regulator>
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
fn id(&self) -> &String {
|
fn id(&self) -> &String {
|
||||||
&self.id
|
&self.id
|
||||||
|
@ -446,14 +458,14 @@ impl ProblemPoser for InversiveDistanceRegulator {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct HalfCurvatureRegulator {
|
pub struct HalfCurvatureRegulator {
|
||||||
pub subject: Rc<dyn Element>,
|
pub subject: Rc<Sphere>,
|
||||||
pub measurement: ReadSignal<f64>,
|
pub measurement: ReadSignal<f64>,
|
||||||
pub set_point: Signal<SpecifiedValue>,
|
pub set_point: Signal<SpecifiedValue>,
|
||||||
serial: u64,
|
serial: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HalfCurvatureRegulator {
|
impl HalfCurvatureRegulator {
|
||||||
pub fn new(subject: Rc<dyn Element>) -> Self {
|
pub fn new(subject: Rc<Sphere>) -> Self {
|
||||||
let measurement = subject.representation().map(
|
let measurement = subject.representation().map(
|
||||||
|rep| rep[Sphere::CURVATURE_COMPONENT]
|
|rep| rep[Sphere::CURVATURE_COMPONENT]
|
||||||
);
|
);
|
||||||
|
@ -498,6 +510,69 @@ impl ProblemPoser for HalfCurvatureRegulator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Sequence)]
|
||||||
|
pub enum Axis {X = 0, Y = 1, Z = 2}
|
||||||
|
|
||||||
|
impl Axis {
|
||||||
|
pub const N_AXIS: usize = (Axis::Z as usize) + 1;
|
||||||
|
pub const NAME: [&str; Axis::N_AXIS] = ["X", "Y", "Z"];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PointCoordinateRegulator {
|
||||||
|
pub subject: Rc<Point>,
|
||||||
|
pub axis: Axis,
|
||||||
|
pub measurement: ReadSignal<f64>,
|
||||||
|
pub set_point: Signal<SpecifiedValue>,
|
||||||
|
serial: u64
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PointCoordinateRegulator {
|
||||||
|
pub fn new(subject: Rc<Point>, axis: Axis) -> Self {
|
||||||
|
let measurement = subject.representation().map(
|
||||||
|
move |rep| rep[axis as usize]
|
||||||
|
);
|
||||||
|
let set_point = create_signal(SpecifiedValue::from_empty_spec());
|
||||||
|
Self { subject, axis, measurement, set_point, serial: Self::next_serial() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serial for PointCoordinateRegulator {
|
||||||
|
fn serial(&self) -> u64 { self.serial }
|
||||||
|
}
|
||||||
|
|
||||||
|
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 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProblemPoser for PointCoordinateRegulator {
|
||||||
|
fn pose(&self, problem: &mut ConstraintProblem) {
|
||||||
|
self.set_point.with_untracked(|set_pt| {
|
||||||
|
if let Some(val) = set_pt.value {
|
||||||
|
let col = self.subject.column_index().expect(
|
||||||
|
"Subject must be indexed before point-coordinate regulator poses.");
|
||||||
|
problem.frozen.push(self.axis as usize, col, val);
|
||||||
|
// Check if all three coordinates have been frozen, and if so,
|
||||||
|
// freeze the coradius as well
|
||||||
|
let mut coords = [0.0; Axis::N_AXIS];
|
||||||
|
let mut nset: usize = 0;
|
||||||
|
for &MatrixEntry {index, value} in &(problem.frozen) {
|
||||||
|
if index.1 == col && index.0 < Axis::N_AXIS {
|
||||||
|
nset += 1;
|
||||||
|
coords[index.0] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if nset == Axis::N_AXIS {
|
||||||
|
let [x, y, z] = coords;
|
||||||
|
problem.frozen.push(
|
||||||
|
Point::NORM_COMPONENT, col, point(x,y,z)[Point::NORM_COMPONENT]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// the velocity is expressed in uniform coordinates
|
// the velocity is expressed in uniform coordinates
|
||||||
pub struct ElementMotion<'a> {
|
pub struct ElementMotion<'a> {
|
||||||
pub element: Rc<dyn Element>,
|
pub element: Rc<dyn Element>,
|
||||||
|
|
|
@ -6,9 +6,11 @@ use web_sys::{KeyboardEvent, MouseEvent, wasm_bindgen::JsCast};
|
||||||
use crate::{
|
use crate::{
|
||||||
AppState,
|
AppState,
|
||||||
assembly::{
|
assembly::{
|
||||||
|
Axis,
|
||||||
Element,
|
Element,
|
||||||
HalfCurvatureRegulator,
|
HalfCurvatureRegulator,
|
||||||
InversiveDistanceRegulator,
|
InversiveDistanceRegulator,
|
||||||
|
PointCoordinateRegulator,
|
||||||
Regulator,
|
Regulator,
|
||||||
},
|
},
|
||||||
specified::SpecifiedValue
|
specified::SpecifiedValue
|
||||||
|
@ -119,6 +121,19 @@ impl OutlineItem for HalfCurvatureRegulator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl OutlineItem for PointCoordinateRegulator {
|
||||||
|
fn outline_item(self: Rc<Self>, _element: &Rc<dyn Element>) -> View {
|
||||||
|
view! {
|
||||||
|
li(class = "regulator") {
|
||||||
|
div(class = "regulator-label") { (Axis::NAME[self.axis as usize]) }
|
||||||
|
div(class = "regulator-type") { "Coordinate" }
|
||||||
|
RegulatorInput(regulator = self)
|
||||||
|
div(class = "status")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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(element: Rc<dyn Element>) -> View {
|
fn ElementOutlineItem(element: Rc<dyn Element>) -> View {
|
||||||
|
|
|
@ -46,14 +46,14 @@ pub fn project_sphere_to_normalized(rep: &mut DVector<f64>) {
|
||||||
|
|
||||||
// normalize a point's representation vector by scaling
|
// normalize a point's representation vector by scaling
|
||||||
pub fn project_point_to_normalized(rep: &mut DVector<f64>) {
|
pub fn project_point_to_normalized(rep: &mut DVector<f64>) {
|
||||||
rep.scale_mut(0.5 / rep[3]);
|
rep.scale_mut(0.5 / rep[3]); //FIXME: This 3 should be Point::WEIGHT_COMPONENT
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- partial matrices ---
|
// --- partial matrices ---
|
||||||
|
|
||||||
pub struct MatrixEntry {
|
pub struct MatrixEntry {
|
||||||
index: (usize, usize),
|
pub index: (usize, usize),
|
||||||
value: f64,
|
pub value: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PartialMatrix(Vec<MatrixEntry>);
|
pub struct PartialMatrix(Vec<MatrixEntry>);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue