feat: Point coordinate regulators #118
1 changed files with 40 additions and 23 deletions
|
@ -308,10 +308,11 @@ impl Element for Point {
|
||||||
|
|
||||||
fn default_regulators(self: Rc<Self>) -> Vec<Rc<dyn Regulator>> {
|
fn default_regulators(self: Rc<Self>) -> Vec<Rc<dyn Regulator>> {
|
||||||
all::<Axis>()
|
all::<Axis>()
|
||||||
.map(|axis| {
|
.map(
|
||||||
Rc::new(PointCoordinateRegulator::new(self.clone(), axis))
|
|axis| Rc::new(
|
||||||
as Rc::<dyn Regulator>
|
PointCoordinateRegulator::new(self.clone(), axis)
|
||||||
})
|
) as Rc::<dyn Regulator>
|
||||||
|
)
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,19 +539,32 @@ impl PointCoordinateRegulator {
|
||||||
let measurement = subject.representation().map(
|
let measurement = subject.representation().map(
|
||||||
move |rep| rep[axis as usize]
|
move |rep| rep[axis as usize]
|
||||||
);
|
);
|
||||||
|
|
||||||
let set_point = create_signal(SpecifiedValue::from_empty_spec());
|
let set_point = create_signal(SpecifiedValue::from_empty_spec());
|
||||||
Self { subject, axis, measurement, set_point, serial: Self::next_serial() }
|
let serial = Self::next_serial();
|
||||||
|
|
||||||
|
Self { subject, axis, measurement, set_point, serial }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serial for PointCoordinateRegulator {
|
impl Serial for PointCoordinateRegulator {
|
||||||
fn serial(&self) -> u64 { self.serial }
|
fn serial(&self) -> u64 {
|
||||||
|
self.serial
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Regulator for PointCoordinateRegulator {
|
impl Regulator for PointCoordinateRegulator {
|
||||||
fn subjects(&self) -> Vec<Rc<dyn Element>> { vec![self.subject.clone()] }
|
fn subjects(&self) -> Vec<Rc<dyn Element>> {
|
||||||
fn measurement(&self) -> ReadSignal<f64> { self.measurement }
|
vec![self.subject.clone()]
|
||||||
fn set_point(&self) -> Signal<SpecifiedValue> { self.set_point }
|
}
|
||||||
|
|
||||||
|
fn measurement(&self) -> ReadSignal<f64> {
|
||||||
|
self.measurement
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_point(&self) -> Signal<SpecifiedValue> {
|
||||||
|
self.set_point
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProblemPoser for PointCoordinateRegulator {
|
impl ProblemPoser for PointCoordinateRegulator {
|
||||||
|
@ -558,22 +572,25 @@ impl ProblemPoser for PointCoordinateRegulator {
|
||||||
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 = self.subject.column_index().expect(
|
let col = self.subject.column_index().expect(
|
||||||
Vectornaut marked this conversation as resolved
|
|||||||
"Subject must be indexed before point-coordinate regulator poses.");
|
"Subject should be indexed before point coordinate regulator writes problem data"
|
||||||
|
);
|
||||||
problem.frozen.push(self.axis as usize, col, val);
|
problem.frozen.push(self.axis as usize, col, val);
|
||||||
// Check if all three spatial coordinates have been frozen, and if so,
|
|
||||||
// freeze the norm component as well
|
// if all three of the subject's spatial coordinates have been
|
||||||
let mut coords = [0.0; Axis::CARDINALITY];
|
// frozen, then freeze its norm component too
|
||||||
let mut nset: usize = 0;
|
let mut coords_frozen = [0.0; Axis::CARDINALITY];
|
||||||
|
let mut n_set: usize = 0;
|
||||||
for &MatrixEntry { index, value } in &(problem.frozen) {
|
for &MatrixEntry { index, value } in &(problem.frozen) {
|
||||||
if index.1 == col && index.0 < Axis::CARDINALITY {
|
let (row_frozen, col_frozen) = index;
|
||||||
nset += 1;
|
if col_frozen == col && row_frozen < Axis::CARDINALITY {
|
||||||
coords[index.0] = value
|
n_set += 1;
|
||||||
|
coords_frozen[row_frozen] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if nset == Axis::CARDINALITY {
|
if n_set == Axis::CARDINALITY {
|
||||||
let [x, y, z] = coords;
|
let [x, y, z] = coords_frozen;
|
||||||
problem.frozen.push(
|
let norm = point(x, y, z)[Point::NORM_COMPONENT];
|
||||||
Point::NORM_COMPONENT, col, point(x,y,z)[Point::NORM_COMPONENT]);
|
problem.frozen.push(Point::NORM_COMPONENT, col, norm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue
Flagging the inconsistent bracket formatting for later. Right now, this would be formatted as
{ index, value }
elsewhere, but during review we discussed potentially changing this convention in the future.It might shock you to know that I don't actually particularly care whether the braces-on-one-line spacing is uniform. If we both agree not to change them unless we touch a line, we could each just write this one the way we're comfortable writing. It's not like either way is particularly hard to read... Or we could decide to be uniform. It's all cool.