Add trailing commas; clean up formatting
All checks were successful
/ test (pull_request) Successful in 3m55s
All checks were successful
/ test (pull_request) Successful in 3m55s
This commit is contained in:
parent
2eba80fb69
commit
af59166906
12 changed files with 235 additions and 213 deletions
|
@ -23,7 +23,7 @@ fn main() {
|
|||
let twist_motion: DMatrix<_> = (0..N_POINTS).step_by(4).flat_map(
|
||||
|n| [
|
||||
tangent.proj(&up.as_view(), n),
|
||||
tangent.proj(&down.as_view(), n+1)
|
||||
tangent.proj(&down.as_view(), n+1),
|
||||
]
|
||||
).sum();
|
||||
let normalization = 5.0 / twist_motion[(2, 0)];
|
||||
|
|
|
@ -6,7 +6,7 @@ use dyna3::engine::{
|
|||
realize_gram,
|
||||
sphere,
|
||||
ConfigNeighborhood,
|
||||
ConstraintProblem
|
||||
ConstraintProblem,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
|
@ -25,7 +25,7 @@ fn main() {
|
|||
);
|
||||
print::title("Point on a sphere");
|
||||
print::realization_diagnostics(&realization);
|
||||
if let Ok(ConfigNeighborhood{ config, .. }) = realization.result {
|
||||
if let Ok(ConfigNeighborhood { config, .. }) = realization.result {
|
||||
print::gram_matrix(&config);
|
||||
print::config(&config);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ use dyna3::engine::{
|
|||
realize_gram,
|
||||
sphere,
|
||||
ConfigNeighborhood,
|
||||
ConstraintProblem
|
||||
ConstraintProblem,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
|
@ -14,7 +14,7 @@ fn main() {
|
|||
&[
|
||||
sphere(1.0, 0.0, 0.0, 1.0),
|
||||
sphere(-0.5, a, 0.0, 1.0),
|
||||
sphere(-0.5, -a, 0.0, 1.0)
|
||||
sphere(-0.5, -a, 0.0, 1.0),
|
||||
]
|
||||
});
|
||||
for j in 0..3 {
|
||||
|
@ -27,7 +27,7 @@ fn main() {
|
|||
);
|
||||
print::title("Three spheres");
|
||||
print::realization_diagnostics(&realization);
|
||||
if let Ok(ConfigNeighborhood{ config, .. }) = realization.result {
|
||||
if let Ok(ConfigNeighborhood { config, .. }) = realization.result {
|
||||
print::gram_matrix(&config);
|
||||
}
|
||||
print::loss_history(&realization.history);
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use nalgebra::{DMatrix, DVector, DVectorView};
|
||||
use std::{
|
||||
cell::Cell,
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
cmp::Ordering,
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
fmt,
|
||||
fmt::{Debug, Formatter},
|
||||
hash::{Hash, Hasher},
|
||||
rc::Rc,
|
||||
sync::{atomic, atomic::AtomicU64}
|
||||
sync::{atomic, atomic::AtomicU64},
|
||||
};
|
||||
use sycamore::prelude::*;
|
||||
use web_sys::{console, wasm_bindgen::JsValue}; /* DEBUG */
|
||||
|
@ -26,9 +26,9 @@ use crate::{
|
|||
ConfigSubspace,
|
||||
ConstraintProblem,
|
||||
DescentHistory,
|
||||
Realization
|
||||
Realization,
|
||||
},
|
||||
specified::SpecifiedValue
|
||||
specified::SpecifiedValue,
|
||||
};
|
||||
|
||||
pub type ElementColor = [f32; 3];
|
||||
|
@ -164,7 +164,7 @@ pub struct Sphere {
|
|||
pub ghost: Signal<bool>,
|
||||
pub regulators: Signal<BTreeSet<Rc<dyn Regulator>>>,
|
||||
serial: u64,
|
||||
column_index: Cell<Option<usize>>
|
||||
column_index: Cell<Option<usize>>,
|
||||
}
|
||||
|
||||
impl Sphere {
|
||||
|
@ -174,17 +174,17 @@ impl Sphere {
|
|||
id: String,
|
||||
label: String,
|
||||
color: ElementColor,
|
||||
representation: DVector<f64>
|
||||
representation: DVector<f64>,
|
||||
) -> Sphere {
|
||||
Sphere {
|
||||
id: id,
|
||||
label: label,
|
||||
color: color,
|
||||
id,
|
||||
label,
|
||||
color,
|
||||
representation: create_signal(representation),
|
||||
ghost: create_signal(false),
|
||||
regulators: create_signal(BTreeSet::new()),
|
||||
serial: Self::next_serial(),
|
||||
column_index: None.into()
|
||||
column_index: None.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ impl Element for Sphere {
|
|||
id,
|
||||
format!("Sphere {id_num}"),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
sphere(0.0, 0.0, 0.0, 1.0)
|
||||
sphere(0.0, 0.0, 0.0, 1.0),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -264,7 +264,7 @@ pub struct Point {
|
|||
pub ghost: Signal<bool>,
|
||||
pub regulators: Signal<BTreeSet<Rc<dyn Regulator>>>,
|
||||
serial: u64,
|
||||
column_index: Cell<Option<usize>>
|
||||
column_index: Cell<Option<usize>>,
|
||||
}
|
||||
|
||||
impl Point {
|
||||
|
@ -274,7 +274,7 @@ impl Point {
|
|||
id: String,
|
||||
label: String,
|
||||
color: ElementColor,
|
||||
representation: DVector<f64>
|
||||
representation: DVector<f64>,
|
||||
) -> Point {
|
||||
Point {
|
||||
id,
|
||||
|
@ -284,7 +284,7 @@ impl Point {
|
|||
ghost: create_signal(false),
|
||||
regulators: create_signal(BTreeSet::new()),
|
||||
serial: Self::next_serial(),
|
||||
column_index: None.into()
|
||||
column_index: None.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ impl Element for Point {
|
|||
id,
|
||||
format!("Point {id_num}"),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
point(0.0, 0.0, 0.0)
|
||||
point(0.0, 0.0, 0.0),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -389,7 +389,7 @@ pub struct InversiveDistanceRegulator {
|
|||
pub subjects: [Rc<dyn Element>; 2],
|
||||
pub measurement: ReadSignal<f64>,
|
||||
pub set_point: Signal<SpecifiedValue>,
|
||||
serial: u64
|
||||
serial: u64,
|
||||
}
|
||||
|
||||
impl InversiveDistanceRegulator {
|
||||
|
@ -449,7 +449,7 @@ pub struct HalfCurvatureRegulator {
|
|||
pub subject: Rc<dyn Element>,
|
||||
pub measurement: ReadSignal<f64>,
|
||||
pub set_point: Signal<SpecifiedValue>,
|
||||
serial: u64
|
||||
serial: u64,
|
||||
}
|
||||
|
||||
impl HalfCurvatureRegulator {
|
||||
|
@ -501,7 +501,7 @@ impl ProblemPoser for HalfCurvatureRegulator {
|
|||
// the velocity is expressed in uniform coordinates
|
||||
pub struct ElementMotion<'a> {
|
||||
pub element: Rc<dyn Element>,
|
||||
pub velocity: DVectorView<'a, f64>
|
||||
pub velocity: DVectorView<'a, f64>,
|
||||
}
|
||||
|
||||
type AssemblyMotion<'a> = Vec<ElementMotion<'a>>;
|
||||
|
@ -533,7 +533,7 @@ pub struct Assembly {
|
|||
|
||||
// realization diagnostics
|
||||
pub realization_status: Signal<Result<(), String>>,
|
||||
pub descent_history: Signal<DescentHistory>
|
||||
pub descent_history: Signal<DescentHistory>,
|
||||
}
|
||||
|
||||
impl Assembly {
|
||||
|
@ -546,7 +546,7 @@ impl Assembly {
|
|||
elements_by_id: create_signal(BTreeMap::default()),
|
||||
realization_trigger: create_signal(()),
|
||||
realization_status: create_signal(Ok(())),
|
||||
descent_history: create_signal(DescentHistory::new())
|
||||
descent_history: create_signal(DescentHistory::new()),
|
||||
};
|
||||
|
||||
// realize the assembly whenever the element list, the regulator list,
|
||||
|
@ -717,7 +717,7 @@ impl Assembly {
|
|||
|
||||
// save the tangent space
|
||||
self.tangent.set_silent(tangent);
|
||||
},
|
||||
}
|
||||
Err(message) => {
|
||||
// report the realization status. the `Err(message)` we're
|
||||
// setting the status to has a different type than the
|
||||
|
@ -804,7 +804,7 @@ impl Assembly {
|
|||
// restore its normalization
|
||||
*rep += motion_proj.column(column_index);
|
||||
elt.project_to_normalized(rep);
|
||||
},
|
||||
}
|
||||
None => {
|
||||
console_log!("No velocity to unpack for fresh element \"{}\"", elt.id())
|
||||
}
|
||||
|
@ -867,7 +867,7 @@ mod tests {
|
|||
String::from(sphere_id),
|
||||
String::from("Sphere 0"),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
engine::sphere(0.0, 0.0, 0.0, INITIAL_RADIUS)
|
||||
engine::sphere(0.0, 0.0, 0.0, INITIAL_RADIUS),
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -881,7 +881,7 @@ mod tests {
|
|||
vec![
|
||||
ElementMotion {
|
||||
element: sphere.clone(),
|
||||
velocity: velocity.as_view()
|
||||
velocity: velocity.as_view(),
|
||||
}
|
||||
]
|
||||
);
|
||||
|
|
|
@ -4,7 +4,7 @@ use sycamore::prelude::*;
|
|||
use super::test_assembly_chooser::TestAssemblyChooser;
|
||||
use crate::{
|
||||
AppState,
|
||||
assembly::{InversiveDistanceRegulator, Point, Sphere}
|
||||
assembly::{InversiveDistanceRegulator, Point, Sphere},
|
||||
};
|
||||
|
||||
#[component]
|
||||
|
|
|
@ -11,13 +11,13 @@ use crate::AppState;
|
|||
|
||||
#[derive(Clone)]
|
||||
struct DiagnosticsState {
|
||||
active_tab: Signal<String>
|
||||
active_tab: Signal<String>,
|
||||
}
|
||||
|
||||
impl DiagnosticsState {
|
||||
fn new(initial_tab: String) -> DiagnosticsState {
|
||||
DiagnosticsState {
|
||||
active_tab: create_signal(initial_tab)
|
||||
active_tab: create_signal(initial_tab),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ fn RealizationStatus() -> View {
|
|||
class=realization_status.with(
|
||||
|status| match status {
|
||||
Ok(_) => "",
|
||||
Err(_) => "invalid"
|
||||
Err(_) => "invalid",
|
||||
}
|
||||
)
|
||||
) {
|
||||
|
@ -42,7 +42,7 @@ fn RealizationStatus() -> View {
|
|||
(realization_status.with(
|
||||
|status| match status {
|
||||
Ok(_) => "Target accuracy achieved".to_string(),
|
||||
Err(message) => message.clone()
|
||||
Err(message) => message.clone(),
|
||||
}
|
||||
))
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ fn RealizationStatus() -> View {
|
|||
fn into_log10_time_point((step, value): (usize, f64)) -> Vec<Option<f64>> {
|
||||
vec![
|
||||
Some(step as f64),
|
||||
if value == 0.0 { None } else { Some(value.abs().log10()) }
|
||||
if value == 0.0 { None } else { Some(value.abs().log10()) },
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ fn SpectrumHistory() -> View {
|
|||
// positive, negative, and strictly-zero parts
|
||||
let (
|
||||
hess_eigvals_zero,
|
||||
hess_eigvals_nonzero
|
||||
hess_eigvals_nonzero,
|
||||
): (Vec<_>, Vec<_>) = state.assembly.descent_history.with(
|
||||
|history| history.hess_eigvals
|
||||
.iter()
|
||||
|
@ -143,7 +143,7 @@ fn SpectrumHistory() -> View {
|
|||
.unwrap_or(1.0);
|
||||
let (
|
||||
hess_eigvals_pos,
|
||||
hess_eigvals_neg
|
||||
hess_eigvals_neg,
|
||||
): (Vec<_>, Vec<_>) = hess_eigvals_nonzero
|
||||
.into_iter()
|
||||
.partition(|&(_, val)| val > 0.0);
|
||||
|
|
|
@ -12,12 +12,12 @@ use web_sys::{
|
|||
WebGlProgram,
|
||||
WebGlShader,
|
||||
WebGlUniformLocation,
|
||||
wasm_bindgen::{JsCast, JsValue}
|
||||
wasm_bindgen::{JsCast, JsValue},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
AppState,
|
||||
assembly::{Element, ElementColor, ElementMotion, Point, Sphere}
|
||||
assembly::{Element, ElementColor, ElementMotion, Point, Sphere},
|
||||
};
|
||||
|
||||
// --- color ---
|
||||
|
@ -37,15 +37,15 @@ fn combine_channels(color: ElementColor, opacity: f32) -> ColorWithOpacity {
|
|||
struct SceneSpheres {
|
||||
representations: Vec<DVector<f64>>,
|
||||
colors_with_opacity: Vec<ColorWithOpacity>,
|
||||
highlights: Vec<f32>
|
||||
highlights: Vec<f32>,
|
||||
}
|
||||
|
||||
impl SceneSpheres {
|
||||
fn new() -> SceneSpheres{
|
||||
fn new() -> SceneSpheres {
|
||||
SceneSpheres {
|
||||
representations: Vec::new(),
|
||||
colors_with_opacity: Vec::new(),
|
||||
highlights: Vec::new()
|
||||
highlights: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,13 @@ impl SceneSpheres {
|
|||
self.representations.len().try_into().expect("Number of spheres must fit in a 32-bit integer")
|
||||
}
|
||||
|
||||
fn push(&mut self, representation: DVector<f64>, color: ElementColor, opacity: f32, highlight: f32) {
|
||||
fn push(
|
||||
&mut self,
|
||||
representation: DVector<f64>,
|
||||
color: ElementColor,
|
||||
opacity: f32,
|
||||
highlight: f32,
|
||||
) {
|
||||
self.representations.push(representation);
|
||||
self.colors_with_opacity.push(combine_channels(color, opacity));
|
||||
self.highlights.push(highlight);
|
||||
|
@ -64,7 +70,7 @@ struct ScenePoints {
|
|||
representations: Vec<DVector<f64>>,
|
||||
colors_with_opacity: Vec<ColorWithOpacity>,
|
||||
highlights: Vec<f32>,
|
||||
selections: Vec<f32>
|
||||
selections: Vec<f32>,
|
||||
}
|
||||
|
||||
impl ScenePoints {
|
||||
|
@ -73,11 +79,18 @@ impl ScenePoints {
|
|||
representations: Vec::new(),
|
||||
colors_with_opacity: Vec::new(),
|
||||
highlights: Vec::new(),
|
||||
selections: Vec::new()
|
||||
selections: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn push(&mut self, representation: DVector<f64>, color: ElementColor, opacity: f32, highlight: f32, selected: bool) {
|
||||
fn push(
|
||||
&mut self,
|
||||
representation: DVector<f64>,
|
||||
color: ElementColor,
|
||||
opacity: f32,
|
||||
highlight: f32,
|
||||
selected: bool,
|
||||
) {
|
||||
self.representations.push(representation);
|
||||
self.colors_with_opacity.push(combine_channels(color, opacity));
|
||||
self.highlights.push(highlight);
|
||||
|
@ -87,14 +100,14 @@ impl ScenePoints {
|
|||
|
||||
pub struct Scene {
|
||||
spheres: SceneSpheres,
|
||||
points: ScenePoints
|
||||
points: ScenePoints,
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
fn new() -> Scene {
|
||||
Scene {
|
||||
spheres: SceneSpheres::new(),
|
||||
points: ScenePoints::new()
|
||||
points: ScenePoints::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,7 +118,12 @@ pub trait DisplayItem {
|
|||
// the smallest positive depth, represented as a multiple of `dir`, where
|
||||
// the line generated by `dir` hits the element. returns `None` if the line
|
||||
// misses the element
|
||||
fn cast(&self, dir: Vector3<f64>, assembly_to_world: &DMatrix<f64>, pixel_size: f64) -> Option<f64>;
|
||||
fn cast(
|
||||
&self,
|
||||
dir: Vector3<f64>,
|
||||
assembly_to_world: &DMatrix<f64>,
|
||||
pixel_size: f64,
|
||||
) -> Option<f64>;
|
||||
}
|
||||
|
||||
impl DisplayItem for Sphere {
|
||||
|
@ -124,7 +142,12 @@ impl DisplayItem for Sphere {
|
|||
|
||||
// this method should be kept synchronized with `sphere_cast` in
|
||||
// `spheres.frag`, which does essentially the same thing on the GPU side
|
||||
fn cast(&self, dir: Vector3<f64>, assembly_to_world: &DMatrix<f64>, _pixel_size: f64) -> Option<f64> {
|
||||
fn cast(
|
||||
&self,
|
||||
dir: Vector3<f64>,
|
||||
assembly_to_world: &DMatrix<f64>,
|
||||
_pixel_size: f64,
|
||||
) -> Option<f64> {
|
||||
// if `a/b` is less than this threshold, we approximate
|
||||
// `a*u^2 + b*u + c` by the linear function `b*u + c`
|
||||
const DEG_THRESHOLD: f64 = 1e-9;
|
||||
|
@ -177,7 +200,12 @@ impl DisplayItem for Point {
|
|||
}
|
||||
|
||||
/* SCAFFOLDING */
|
||||
fn cast(&self, dir: Vector3<f64>, assembly_to_world: &DMatrix<f64>, pixel_size: f64) -> Option<f64> {
|
||||
fn cast(
|
||||
&self,
|
||||
dir: Vector3<f64>,
|
||||
assembly_to_world: &DMatrix<f64>,
|
||||
pixel_size: f64,
|
||||
) -> Option<f64> {
|
||||
let rep = self.representation.with_untracked(|rep| assembly_to_world * rep);
|
||||
if rep[2] < 0.0 {
|
||||
// this constant should be kept synchronized with `point.frag`
|
||||
|
@ -220,7 +248,7 @@ fn compile_shader(
|
|||
fn set_up_program(
|
||||
context: &WebGl2RenderingContext,
|
||||
vertex_shader_source: &str,
|
||||
fragment_shader_source: &str
|
||||
fragment_shader_source: &str,
|
||||
) -> WebGlProgram {
|
||||
// compile the shaders
|
||||
let vertex_shader = compile_shader(
|
||||
|
@ -260,12 +288,12 @@ fn get_uniform_array_locations<const N: usize>(
|
|||
context: &WebGl2RenderingContext,
|
||||
program: &WebGlProgram,
|
||||
var_name: &str,
|
||||
member_name_opt: Option<&str>
|
||||
member_name_opt: Option<&str>,
|
||||
) -> [Option<WebGlUniformLocation>; N] {
|
||||
array::from_fn(|n| {
|
||||
let name = match member_name_opt {
|
||||
Some(member_name) => format!("{var_name}[{n}].{member_name}"),
|
||||
None => format!("{var_name}[{n}]")
|
||||
None => format!("{var_name}[{n}]"),
|
||||
};
|
||||
context.get_uniform_location(&program, name.as_str())
|
||||
})
|
||||
|
@ -276,7 +304,7 @@ fn bind_to_attribute(
|
|||
context: &WebGl2RenderingContext,
|
||||
attr_index: u32,
|
||||
attr_size: i32,
|
||||
buffer: &Option<WebGlBuffer>
|
||||
buffer: &Option<WebGlBuffer>,
|
||||
) {
|
||||
context.bind_buffer(WebGl2RenderingContext::ARRAY_BUFFER, buffer.as_ref());
|
||||
context.vertex_attrib_pointer_with_i32(
|
||||
|
@ -292,7 +320,7 @@ fn bind_to_attribute(
|
|||
// load the given data into a new vertex buffer object
|
||||
fn load_new_buffer(
|
||||
context: &WebGl2RenderingContext,
|
||||
data: &[f32]
|
||||
data: &[f32],
|
||||
) -> Option<WebGlBuffer> {
|
||||
// create a buffer and bind it to ARRAY_BUFFER
|
||||
let buffer = context.create_buffer();
|
||||
|
@ -319,7 +347,7 @@ fn bind_new_buffer_to_attribute(
|
|||
context: &WebGl2RenderingContext,
|
||||
attr_index: u32,
|
||||
attr_size: i32,
|
||||
data: &[f32]
|
||||
data: &[f32],
|
||||
) {
|
||||
let buffer = load_new_buffer(context, data);
|
||||
bind_to_attribute(context, attr_index, attr_size, &buffer);
|
||||
|
@ -341,9 +369,9 @@ fn event_dir(event: &MouseEvent) -> (Vector3<f64>, f64) {
|
|||
Vector3::new(
|
||||
FOCAL_SLOPE * (2.0*(f64::from(event.client_x()) - rect.left()) - width) / shortdim,
|
||||
FOCAL_SLOPE * (2.0*(rect.bottom() - f64::from(event.client_y())) - height) / shortdim,
|
||||
-1.0
|
||||
-1.0,
|
||||
),
|
||||
FOCAL_SLOPE * 2.0 / shortdim
|
||||
FOCAL_SLOPE * 2.0 / shortdim,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -443,14 +471,14 @@ pub fn Display() -> View {
|
|||
let sphere_program = set_up_program(
|
||||
&ctx,
|
||||
include_str!("identity.vert"),
|
||||
include_str!("spheres.frag")
|
||||
include_str!("spheres.frag"),
|
||||
);
|
||||
|
||||
// set up the point rendering program
|
||||
let point_program = set_up_program(
|
||||
&ctx,
|
||||
include_str!("point.vert"),
|
||||
include_str!("point.frag")
|
||||
include_str!("point.frag"),
|
||||
);
|
||||
|
||||
/* DEBUG */
|
||||
|
@ -467,7 +495,7 @@ pub fn Display() -> View {
|
|||
// capped at 1024 elements
|
||||
console::log_2(
|
||||
&ctx.get_parameter(WebGl2RenderingContext::MAX_FRAGMENT_UNIFORM_VECTORS).unwrap(),
|
||||
&JsValue::from("uniform vectors available")
|
||||
&JsValue::from("uniform vectors available"),
|
||||
);
|
||||
|
||||
// find the sphere program's vertex attribute
|
||||
|
@ -503,7 +531,7 @@ pub fn Display() -> View {
|
|||
// southeast triangle
|
||||
-1.0, -1.0, 0.0,
|
||||
1.0, 1.0, 0.0,
|
||||
1.0, -1.0, 0.0
|
||||
1.0, -1.0, 0.0,
|
||||
];
|
||||
let viewport_position_buffer = load_new_buffer(&ctx, &viewport_positions);
|
||||
|
||||
|
@ -596,7 +624,7 @@ pub fn Display() -> View {
|
|||
vec![
|
||||
ElementMotion {
|
||||
element: sel,
|
||||
velocity: elt_motion.as_view()
|
||||
velocity: elt_motion.as_view(),
|
||||
}
|
||||
]
|
||||
);
|
||||
|
@ -629,7 +657,7 @@ pub fn Display() -> View {
|
|||
0.0, 1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0, u,
|
||||
0.0, 0.0, 2.0*u, 1.0, u*u,
|
||||
0.0, 0.0, 0.0, 0.0, 1.0
|
||||
0.0, 0.0, 0.0, 0.0, 1.0,
|
||||
])
|
||||
};
|
||||
let asm_to_world = &location * &orientation;
|
||||
|
@ -668,19 +696,19 @@ pub fn Display() -> View {
|
|||
let v = &sphere_reps_world[n];
|
||||
ctx.uniform3fv_with_f32_array(
|
||||
sphere_sp_locs[n].as_ref(),
|
||||
v.rows(0, 3).as_slice()
|
||||
v.rows(0, 3).as_slice(),
|
||||
);
|
||||
ctx.uniform2fv_with_f32_array(
|
||||
sphere_lt_locs[n].as_ref(),
|
||||
v.rows(3, 2).as_slice()
|
||||
v.rows(3, 2).as_slice(),
|
||||
);
|
||||
ctx.uniform4fv_with_f32_array(
|
||||
sphere_color_locs[n].as_ref(),
|
||||
&scene.spheres.colors_with_opacity[n]
|
||||
&scene.spheres.colors_with_opacity[n],
|
||||
);
|
||||
ctx.uniform1f(
|
||||
sphere_highlight_locs[n].as_ref(),
|
||||
scene.spheres.highlights[n]
|
||||
scene.spheres.highlights[n],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -773,7 +801,7 @@ pub fn Display() -> View {
|
|||
"ArrowLeft" if shift => roll_ccw.set(value),
|
||||
"ArrowRight" => yaw_right.set(value),
|
||||
"ArrowLeft" => yaw_left.set(value),
|
||||
_ => navigating = false
|
||||
_ => navigating = false,
|
||||
};
|
||||
if navigating {
|
||||
scene_changed.set(true);
|
||||
|
@ -793,7 +821,7 @@ pub fn Display() -> View {
|
|||
"s" | "S" => translate_neg_y.set(value),
|
||||
"]" | "}" => shrink_neg.set(value),
|
||||
"[" | "{" => shrink_pos.set(value),
|
||||
_ => manipulating = false
|
||||
_ => manipulating = false,
|
||||
};
|
||||
if manipulating {
|
||||
event.prevent_default();
|
||||
|
@ -882,8 +910,8 @@ pub fn Display() -> View {
|
|||
if depth < best_depth {
|
||||
clicked = Some((elt, depth))
|
||||
}
|
||||
},
|
||||
None => clicked = Some((elt, depth))
|
||||
}
|
||||
None => clicked = Some((elt, depth)),
|
||||
}
|
||||
None => ()
|
||||
};
|
||||
|
@ -894,7 +922,7 @@ pub fn Display() -> View {
|
|||
Some((elt, _)) => state.select(&elt, event.shift_key()),
|
||||
None => state.selection.update(|sel| sel.clear())
|
||||
};
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,11 +1,7 @@
|
|||
use itertools::Itertools;
|
||||
use std::rc::Rc;
|
||||
use sycamore::prelude::*;
|
||||
use web_sys::{
|
||||
KeyboardEvent,
|
||||
MouseEvent,
|
||||
wasm_bindgen::JsCast
|
||||
};
|
||||
use web_sys::{KeyboardEvent, MouseEvent, wasm_bindgen::JsCast};
|
||||
|
||||
use crate::{
|
||||
AppState,
|
||||
|
@ -13,7 +9,7 @@ use crate::{
|
|||
Element,
|
||||
HalfCurvatureRegulator,
|
||||
InversiveDistanceRegulator,
|
||||
Regulator
|
||||
Regulator,
|
||||
},
|
||||
specified::SpecifiedValue
|
||||
};
|
||||
|
@ -83,7 +79,7 @@ fn RegulatorInput(regulator: Rc<dyn Regulator>) -> View {
|
|||
_ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -166,20 +162,20 @@ fn ElementOutlineItem(element: Rc<dyn Element>) -> View {
|
|||
"Enter" => {
|
||||
state.select(&element_for_handler, event.shift_key());
|
||||
event.prevent_default();
|
||||
},
|
||||
}
|
||||
"ArrowRight" if regulated.get() => {
|
||||
let _ = details_node
|
||||
.get()
|
||||
.unchecked_into::<web_sys::Element>()
|
||||
.set_attribute("open", "");
|
||||
},
|
||||
}
|
||||
"ArrowLeft" => {
|
||||
let _ = details_node
|
||||
.get()
|
||||
.unchecked_into::<web_sys::Element>()
|
||||
.remove_attribute("open");
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,17 +6,17 @@ use web_sys::{console, wasm_bindgen::JsValue};
|
|||
|
||||
use crate::{
|
||||
AppState,
|
||||
engine,
|
||||
engine::DescentHistory,
|
||||
assembly::{
|
||||
Assembly,
|
||||
Element,
|
||||
ElementColor,
|
||||
InversiveDistanceRegulator,
|
||||
Point,
|
||||
Sphere
|
||||
Sphere,
|
||||
},
|
||||
specified::SpecifiedValue
|
||||
engine,
|
||||
engine::DescentHistory,
|
||||
specified::SpecifiedValue,
|
||||
};
|
||||
|
||||
// --- loaders ---
|
||||
|
@ -32,7 +32,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
|||
String::from("gemini_a"),
|
||||
String::from("Castor"),
|
||||
[1.00_f32, 0.25_f32, 0.00_f32],
|
||||
engine::sphere(0.5, 0.5, 0.0, 1.0)
|
||||
engine::sphere(0.5, 0.5, 0.0, 1.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
|
@ -40,7 +40,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
|||
String::from("gemini_b"),
|
||||
String::from("Pollux"),
|
||||
[0.00_f32, 0.25_f32, 1.00_f32],
|
||||
engine::sphere(-0.5, -0.5, 0.0, 1.0)
|
||||
engine::sphere(-0.5, -0.5, 0.0, 1.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
|
@ -48,7 +48,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
|||
String::from("ursa_major"),
|
||||
String::from("Ursa major"),
|
||||
[0.25_f32, 0.00_f32, 1.00_f32],
|
||||
engine::sphere(-0.5, 0.5, 0.0, 0.75)
|
||||
engine::sphere(-0.5, 0.5, 0.0, 0.75),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
|
@ -56,7 +56,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
|||
String::from("ursa_minor"),
|
||||
String::from("Ursa minor"),
|
||||
[0.25_f32, 1.00_f32, 0.00_f32],
|
||||
engine::sphere(0.5, -0.5, 0.0, 0.5)
|
||||
engine::sphere(0.5, -0.5, 0.0, 0.5),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
|
@ -64,7 +64,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
|||
String::from("moon_deimos"),
|
||||
String::from("Deimos"),
|
||||
[0.75_f32, 0.75_f32, 0.00_f32],
|
||||
engine::sphere(0.0, 0.15, 1.0, 0.25)
|
||||
engine::sphere(0.0, 0.15, 1.0, 0.25),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
|
@ -72,7 +72,7 @@ fn load_gen_assemb(assembly: &Assembly) {
|
|||
String::from("moon_phobos"),
|
||||
String::from("Phobos"),
|
||||
[0.00_f32, 0.75_f32, 0.50_f32],
|
||||
engine::sphere(0.0, -0.15, -1.0, 0.25)
|
||||
engine::sphere(0.0, -0.15, -1.0, 0.25),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
|||
"central".to_string(),
|
||||
"Central".to_string(),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
engine::sphere(0.0, 0.0, 0.0, 1.0)
|
||||
engine::sphere(0.0, 0.0, 0.0, 1.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
|
@ -93,7 +93,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
|||
"assemb_plane".to_string(),
|
||||
"Assembly plane".to_string(),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
engine::sphere_with_offset(0.0, 0.0, 1.0, 0.0, 0.0)
|
||||
engine::sphere_with_offset(0.0, 0.0, 1.0, 0.0, 0.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
|
@ -101,7 +101,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
|||
"side1".to_string(),
|
||||
"Side 1".to_string(),
|
||||
[1.00_f32, 0.00_f32, 0.25_f32],
|
||||
engine::sphere_with_offset(1.0, 0.0, 0.0, 1.0, 0.0)
|
||||
engine::sphere_with_offset(1.0, 0.0, 0.0, 1.0, 0.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
|
@ -109,7 +109,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
|||
"side2".to_string(),
|
||||
"Side 2".to_string(),
|
||||
[0.25_f32, 1.00_f32, 0.00_f32],
|
||||
engine::sphere_with_offset(-0.5, a, 0.0, 1.0, 0.0)
|
||||
engine::sphere_with_offset(-0.5, a, 0.0, 1.0, 0.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
|
@ -117,7 +117,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
|||
"side3".to_string(),
|
||||
"Side 3".to_string(),
|
||||
[0.00_f32, 0.25_f32, 1.00_f32],
|
||||
engine::sphere_with_offset(-0.5, -a, 0.0, 1.0, 0.0)
|
||||
engine::sphere_with_offset(-0.5, -a, 0.0, 1.0, 0.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
|
@ -125,7 +125,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
|||
"corner1".to_string(),
|
||||
"Corner 1".to_string(),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
engine::sphere(-4.0/3.0, 0.0, 0.0, 1.0/3.0)
|
||||
engine::sphere(-4.0/3.0, 0.0, 0.0, 1.0/3.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
|
@ -133,7 +133,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
|||
"corner2".to_string(),
|
||||
"Corner 2".to_string(),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
engine::sphere(2.0/3.0, -4.0/3.0 * a, 0.0, 1.0/3.0)
|
||||
engine::sphere(2.0/3.0, -4.0/3.0 * a, 0.0, 1.0/3.0),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
|
@ -141,7 +141,7 @@ fn load_low_curv_assemb(assembly: &Assembly) {
|
|||
String::from("corner3"),
|
||||
String::from("Corner 3"),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
engine::sphere(2.0/3.0, 4.0/3.0 * a, 0.0, 1.0/3.0)
|
||||
engine::sphere(2.0/3.0, 4.0/3.0 * a, 0.0, 1.0/3.0),
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -202,7 +202,7 @@ fn load_pointed_assemb(assembly: &Assembly) {
|
|||
format!("point_front"),
|
||||
format!("Front point"),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
engine::point(0.0, 0.0, FRAC_1_SQRT_2)
|
||||
engine::point(0.0, 0.0, FRAC_1_SQRT_2),
|
||||
)
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
|
@ -210,7 +210,7 @@ fn load_pointed_assemb(assembly: &Assembly) {
|
|||
format!("point_back"),
|
||||
format!("Back point"),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
engine::point(0.0, 0.0, -FRAC_1_SQRT_2)
|
||||
engine::point(0.0, 0.0, -FRAC_1_SQRT_2),
|
||||
)
|
||||
);
|
||||
for index_x in 0..=1 {
|
||||
|
@ -223,7 +223,7 @@ fn load_pointed_assemb(assembly: &Assembly) {
|
|||
format!("sphere{index_x}{index_y}"),
|
||||
format!("Sphere {index_x}{index_y}"),
|
||||
[0.5*(1.0 + x) as f32, 0.5*(1.0 + y) as f32, 0.5*(1.0 - x*y) as f32],
|
||||
engine::sphere(x, y, 0.0, 1.0)
|
||||
engine::sphere(x, y, 0.0, 1.0),
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -232,7 +232,7 @@ fn load_pointed_assemb(assembly: &Assembly) {
|
|||
format!("point{index_x}{index_y}"),
|
||||
format!("Point {index_x}{index_y}"),
|
||||
[0.5*(1.0 + x) as f32, 0.5*(1.0 + y) as f32, 0.5*(1.0 - x*y) as f32],
|
||||
engine::point(x, y, 0.0)
|
||||
engine::point(x, y, 0.0),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -256,56 +256,56 @@ fn load_tridim_icosahedron_assemb(assembly: &Assembly) {
|
|||
"a1".to_string(),
|
||||
"A₁".to_string(),
|
||||
COLOR_A,
|
||||
engine::point(0.25, 0.75, 0.75)
|
||||
engine::point(0.25, 0.75, 0.75),
|
||||
),
|
||||
Point::new(
|
||||
"a2".to_string(),
|
||||
"A₂".to_string(),
|
||||
COLOR_A,
|
||||
engine::point(0.75, 0.25, 0.75)
|
||||
engine::point(0.75, 0.25, 0.75),
|
||||
),
|
||||
Point::new(
|
||||
"a3".to_string(),
|
||||
"A₃".to_string(),
|
||||
COLOR_A,
|
||||
engine::point(0.75, 0.75, 0.25)
|
||||
engine::point(0.75, 0.75, 0.25),
|
||||
),
|
||||
Point::new(
|
||||
"b1".to_string(),
|
||||
"B₁".to_string(),
|
||||
COLOR_B,
|
||||
engine::point(0.75, -0.25, -0.25)
|
||||
engine::point(0.75, -0.25, -0.25),
|
||||
),
|
||||
Point::new(
|
||||
"b2".to_string(),
|
||||
"B₂".to_string(),
|
||||
COLOR_B,
|
||||
engine::point(-0.25, 0.75, -0.25)
|
||||
engine::point(-0.25, 0.75, -0.25),
|
||||
),
|
||||
Point::new(
|
||||
"b3".to_string(),
|
||||
"B₃".to_string(),
|
||||
COLOR_B,
|
||||
engine::point(-0.25, -0.25, 0.75)
|
||||
engine::point(-0.25, -0.25, 0.75),
|
||||
),
|
||||
Point::new(
|
||||
"c1".to_string(),
|
||||
"C₁".to_string(),
|
||||
COLOR_C,
|
||||
engine::point(0.0, -1.0, -1.0)
|
||||
engine::point(0.0, -1.0, -1.0),
|
||||
),
|
||||
Point::new(
|
||||
"c2".to_string(),
|
||||
"C₂".to_string(),
|
||||
COLOR_C,
|
||||
engine::point(-1.0, 0.0, -1.0)
|
||||
engine::point(-1.0, 0.0, -1.0),
|
||||
),
|
||||
Point::new(
|
||||
"c3".to_string(),
|
||||
"C₃".to_string(),
|
||||
COLOR_C,
|
||||
engine::point(-1.0, -1.0, 0.0)
|
||||
)
|
||||
engine::point(-1.0, -1.0, 0.0),
|
||||
),
|
||||
];
|
||||
for vertex in vertices {
|
||||
let _ = assembly.try_insert_element(vertex);
|
||||
|
@ -320,20 +320,20 @@ fn load_tridim_icosahedron_assemb(assembly: &Assembly) {
|
|||
"face1".to_string(),
|
||||
"Face 1".to_string(),
|
||||
COLOR_FACE,
|
||||
engine::sphere_with_offset(frac_2_sqrt_6, -frac_1_sqrt_6, -frac_1_sqrt_6, -frac_1_sqrt_6, 0.0)
|
||||
engine::sphere_with_offset(frac_2_sqrt_6, -frac_1_sqrt_6, -frac_1_sqrt_6, -frac_1_sqrt_6, 0.0),
|
||||
),
|
||||
Sphere::new(
|
||||
"face2".to_string(),
|
||||
"Face 2".to_string(),
|
||||
COLOR_FACE,
|
||||
engine::sphere_with_offset(-frac_1_sqrt_6, frac_2_sqrt_6, -frac_1_sqrt_6, -frac_1_sqrt_6, 0.0)
|
||||
engine::sphere_with_offset(-frac_1_sqrt_6, frac_2_sqrt_6, -frac_1_sqrt_6, -frac_1_sqrt_6, 0.0),
|
||||
),
|
||||
Sphere::new(
|
||||
"face3".to_string(),
|
||||
"Face 3".to_string(),
|
||||
COLOR_FACE,
|
||||
engine::sphere_with_offset(-frac_1_sqrt_6, -frac_1_sqrt_6, frac_2_sqrt_6, -frac_1_sqrt_6, 0.0)
|
||||
)
|
||||
engine::sphere_with_offset(-frac_1_sqrt_6, -frac_1_sqrt_6, frac_2_sqrt_6, -frac_1_sqrt_6, 0.0),
|
||||
),
|
||||
];
|
||||
for face in faces {
|
||||
face.ghost().set(true);
|
||||
|
@ -416,7 +416,7 @@ fn load_dodeca_packing_assemb(assembly: &Assembly) {
|
|||
"substrate".to_string(),
|
||||
"Substrate".to_string(),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
engine::sphere(0.0, 0.0, 0.0, 1.0)
|
||||
engine::sphere(0.0, 0.0, 0.0, 1.0),
|
||||
)
|
||||
);
|
||||
let substrate = assembly.elements_by_id.with_untracked(
|
||||
|
@ -456,7 +456,7 @@ fn load_dodeca_packing_assemb(assembly: &Assembly) {
|
|||
id_a.clone(),
|
||||
format!("A{label_sub}"),
|
||||
COLOR_A,
|
||||
engine::sphere(0.0, small_coord, big_coord, face_radii[k])
|
||||
engine::sphere(0.0, small_coord, big_coord, face_radii[k]),
|
||||
)
|
||||
);
|
||||
faces.push(
|
||||
|
@ -472,7 +472,7 @@ fn load_dodeca_packing_assemb(assembly: &Assembly) {
|
|||
id_b.clone(),
|
||||
format!("B{label_sub}"),
|
||||
COLOR_B,
|
||||
engine::sphere(small_coord, big_coord, 0.0, face_radii[k])
|
||||
engine::sphere(small_coord, big_coord, 0.0, face_radii[k]),
|
||||
)
|
||||
);
|
||||
faces.push(
|
||||
|
@ -488,7 +488,7 @@ fn load_dodeca_packing_assemb(assembly: &Assembly) {
|
|||
id_c.clone(),
|
||||
format!("C{label_sub}"),
|
||||
COLOR_C,
|
||||
engine::sphere(big_coord, 0.0, small_coord, face_radii[k])
|
||||
engine::sphere(big_coord, 0.0, small_coord, face_radii[k]),
|
||||
)
|
||||
);
|
||||
faces.push(
|
||||
|
@ -559,19 +559,19 @@ fn load_balanced_assemb(assembly: &Assembly) {
|
|||
"outer".to_string(),
|
||||
"Outer".to_string(),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
engine::sphere(0.0, 0.0, 0.0, R_OUTER)
|
||||
engine::sphere(0.0, 0.0, 0.0, R_OUTER),
|
||||
),
|
||||
Sphere::new(
|
||||
"a".to_string(),
|
||||
"A".to_string(),
|
||||
[1.00_f32, 0.00_f32, 0.25_f32],
|
||||
engine::sphere(0.0, 4.0, 0.0, R_INNER)
|
||||
engine::sphere(0.0, 4.0, 0.0, R_INNER),
|
||||
),
|
||||
Sphere::new(
|
||||
"b".to_string(),
|
||||
"B".to_string(),
|
||||
[0.00_f32, 0.25_f32, 1.00_f32],
|
||||
engine::sphere(0.0, -4.0, 0.0, R_INNER)
|
||||
engine::sphere(0.0, -4.0, 0.0, R_INNER),
|
||||
),
|
||||
];
|
||||
for sphere in spheres {
|
||||
|
@ -589,7 +589,7 @@ fn load_balanced_assemb(assembly: &Assembly) {
|
|||
for (sphere, radius) in [
|
||||
(outer.clone(), R_OUTER),
|
||||
(a.clone(), R_INNER),
|
||||
(b.clone(), R_INNER)
|
||||
(b.clone(), R_INNER),
|
||||
] {
|
||||
let curvature_regulator = sphere.regulators().with_untracked(
|
||||
|regs| regs.first().unwrap().clone()
|
||||
|
@ -618,7 +618,7 @@ fn load_off_center_assemb(assembly: &Assembly) {
|
|||
"point".to_string(),
|
||||
"Point".to_string(),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
engine::point(1e-9, 0.0, 0.0)
|
||||
engine::point(1e-9, 0.0, 0.0),
|
||||
),
|
||||
);
|
||||
let _ = assembly.try_insert_element(
|
||||
|
@ -626,7 +626,7 @@ fn load_off_center_assemb(assembly: &Assembly) {
|
|||
"sphere".to_string(),
|
||||
"Sphere".to_string(),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
engine::sphere(0.0, 0.0, 0.0, 1.0)
|
||||
engine::sphere(0.0, 0.0, 0.0, 1.0),
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -658,14 +658,14 @@ fn load_radius_ratio_assemb(assembly: &Assembly) {
|
|||
"sphere_faces".to_string(),
|
||||
"Insphere".to_string(),
|
||||
GRAY,
|
||||
engine::sphere(0.0, 0.0, 0.0, 0.5)
|
||||
engine::sphere(0.0, 0.0, 0.0, 0.5),
|
||||
),
|
||||
Sphere::new(
|
||||
"sphere_vertices".to_string(),
|
||||
"Circumsphere".to_string(),
|
||||
GRAY,
|
||||
engine::sphere(0.0, 0.0, 0.0, 0.25)
|
||||
)
|
||||
engine::sphere(0.0, 0.0, 0.0, 0.25),
|
||||
),
|
||||
];
|
||||
for sphere in spheres {
|
||||
let _ = assembly.try_insert_element(sphere);
|
||||
|
@ -678,13 +678,13 @@ fn load_radius_ratio_assemb(assembly: &Assembly) {
|
|||
[1.00_f32, 0.50_f32, 0.75_f32],
|
||||
[1.00_f32, 0.75_f32, 0.50_f32],
|
||||
[1.00_f32, 1.00_f32, 0.50_f32],
|
||||
[0.75_f32, 0.50_f32, 1.00_f32]
|
||||
[0.75_f32, 0.50_f32, 1.00_f32],
|
||||
].into_iter(),
|
||||
[
|
||||
engine::point(-0.6, -0.8, -0.6),
|
||||
engine::point(-0.6, 0.8, 0.6),
|
||||
engine::point(0.6, -0.8, 0.6),
|
||||
engine::point(0.6, 0.8, -0.6)
|
||||
engine::point(0.6, 0.8, -0.6),
|
||||
].into_iter()
|
||||
).map(
|
||||
|(k, color, representation)| {
|
||||
|
@ -692,7 +692,7 @@ fn load_radius_ratio_assemb(assembly: &Assembly) {
|
|||
format!("v{k}"),
|
||||
format!("Vertex {k}"),
|
||||
color,
|
||||
representation
|
||||
representation,
|
||||
)
|
||||
}
|
||||
);
|
||||
|
@ -709,13 +709,13 @@ fn load_radius_ratio_assemb(assembly: &Assembly) {
|
|||
[1.00_f32, 0.00_f32, 0.25_f32],
|
||||
[1.00_f32, 0.25_f32, 0.00_f32],
|
||||
[0.75_f32, 0.75_f32, 0.00_f32],
|
||||
[0.25_f32, 0.00_f32, 1.00_f32]
|
||||
[0.25_f32, 0.00_f32, 1.00_f32],
|
||||
].into_iter(),
|
||||
[
|
||||
engine::sphere_with_offset(base_dir[0], base_dir[1], base_dir[2], offset, 0.0),
|
||||
engine::sphere_with_offset(base_dir[0], -base_dir[1], -base_dir[2], offset, 0.0),
|
||||
engine::sphere_with_offset(-base_dir[0], base_dir[1], -base_dir[2], offset, 0.0),
|
||||
engine::sphere_with_offset(-base_dir[0], -base_dir[1], base_dir[2], offset, 0.0)
|
||||
engine::sphere_with_offset(-base_dir[0], -base_dir[1], base_dir[2], offset, 0.0),
|
||||
].into_iter()
|
||||
).map(
|
||||
|(k, color, representation)| {
|
||||
|
@ -723,7 +723,7 @@ fn load_radius_ratio_assemb(assembly: &Assembly) {
|
|||
format!("f{k}"),
|
||||
format!("Face {k}"),
|
||||
color,
|
||||
representation
|
||||
representation,
|
||||
)
|
||||
}
|
||||
);
|
||||
|
@ -736,7 +736,7 @@ fn load_radius_ratio_assemb(assembly: &Assembly) {
|
|||
for j in index_range.clone() {
|
||||
let [face_j, vertex_j] = [
|
||||
format!("f{j}"),
|
||||
format!("v{j}")
|
||||
format!("v{j}"),
|
||||
].map(
|
||||
|id| assembly.elements_by_id.with_untracked(
|
||||
|elts_by_id| elts_by_id[&id].clone()
|
||||
|
@ -797,7 +797,7 @@ fn load_irisawa_hexlet_assemb(assembly: &Assembly) {
|
|||
[0.75_f32, 0.75_f32, 0.00_f32],
|
||||
[0.25_f32, 1.00_f32, 0.00_f32],
|
||||
[0.00_f32, 0.25_f32, 1.00_f32],
|
||||
[0.25_f32, 0.00_f32, 1.00_f32]
|
||||
[0.25_f32, 0.00_f32, 1.00_f32],
|
||||
].into_iter();
|
||||
|
||||
// create the spheres
|
||||
|
@ -806,19 +806,19 @@ fn load_irisawa_hexlet_assemb(assembly: &Assembly) {
|
|||
"outer".to_string(),
|
||||
"Outer".to_string(),
|
||||
[0.5_f32, 0.5_f32, 0.5_f32],
|
||||
engine::sphere(0.0, 0.0, 0.0, 1.5)
|
||||
engine::sphere(0.0, 0.0, 0.0, 1.5),
|
||||
),
|
||||
Sphere::new(
|
||||
"sun".to_string(),
|
||||
"Sun".to_string(),
|
||||
[0.75_f32, 0.75_f32, 0.75_f32],
|
||||
engine::sphere(0.0, -0.75, 0.0, 0.75)
|
||||
engine::sphere(0.0, -0.75, 0.0, 0.75),
|
||||
),
|
||||
Sphere::new(
|
||||
"moon".to_string(),
|
||||
"Moon".to_string(),
|
||||
[0.25_f32, 0.25_f32, 0.25_f32],
|
||||
engine::sphere(0.0, 0.75, 0.0, 0.75)
|
||||
engine::sphere(0.0, 0.75, 0.0, 0.75),
|
||||
),
|
||||
].into_iter().chain(
|
||||
index_range.clone().zip(colors).map(
|
||||
|
@ -828,7 +828,7 @@ fn load_irisawa_hexlet_assemb(assembly: &Assembly) {
|
|||
format!("chain{k}"),
|
||||
format!("Chain {k}"),
|
||||
color,
|
||||
engine::sphere(1.0 * ang.sin(), 0.0, 1.0 * ang.cos(), 0.5)
|
||||
engine::sphere(1.0 * ang.sin(), 0.0, 1.0 * ang.cos(), 0.5),
|
||||
)
|
||||
}
|
||||
)
|
||||
|
@ -865,7 +865,7 @@ fn load_irisawa_hexlet_assemb(assembly: &Assembly) {
|
|||
(outer.clone(), "1"),
|
||||
(sun.clone(), "-1"),
|
||||
(moon.clone(), "-1"),
|
||||
(chain_sphere_next.clone(), "-1")
|
||||
(chain_sphere_next.clone(), "-1"),
|
||||
] {
|
||||
let tangency = InversiveDistanceRegulator::new([chain_sphere.clone(), other_sphere]);
|
||||
tangency.set_point.set(SpecifiedValue::try_from(inversive_distance.to_string()).unwrap());
|
||||
|
@ -918,7 +918,7 @@ pub fn TestAssemblyChooser() -> View {
|
|||
"off-center" => load_off_center_assemb(assembly),
|
||||
"radius-ratio" => load_radius_ratio_assemb(assembly),
|
||||
"irisawa-hexlet" => load_irisawa_hexlet_assemb(assembly),
|
||||
_ => ()
|
||||
_ => (),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,7 +16,7 @@ pub fn sphere(center_x: f64, center_y: f64, center_z: f64, radius: f64) -> DVect
|
|||
center_y / radius,
|
||||
center_z / radius,
|
||||
0.5 / radius,
|
||||
0.5 * (center_norm_sq / radius - radius)
|
||||
0.5 * (center_norm_sq / radius - radius),
|
||||
])
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ pub fn sphere_with_offset(dir_x: f64, dir_y: f64, dir_z: f64, off: f64, curv: f6
|
|||
norm_sp * dir_y,
|
||||
norm_sp * dir_z,
|
||||
0.5 * curv,
|
||||
off * (1.0 + 0.5 * off * curv)
|
||||
off * (1.0 + 0.5 * off * curv),
|
||||
])
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ pub fn project_point_to_normalized(rep: &mut DVector<f64>) {
|
|||
|
||||
pub struct MatrixEntry {
|
||||
index: (usize, usize),
|
||||
value: f64
|
||||
value: f64,
|
||||
}
|
||||
|
||||
pub struct PartialMatrix(Vec<MatrixEntry>);
|
||||
|
@ -65,7 +65,7 @@ impl PartialMatrix {
|
|||
|
||||
pub fn push(&mut self, row: usize, col: usize, value: f64) {
|
||||
let PartialMatrix(entries) = self;
|
||||
entries.push(MatrixEntry { index: (row, col), value: value });
|
||||
entries.push(MatrixEntry { index: (row, col), value });
|
||||
}
|
||||
|
||||
pub fn push_sym(&mut self, row: usize, col: usize, value: f64) {
|
||||
|
@ -135,22 +135,26 @@ impl<'a> IntoIterator for &'a PartialMatrix {
|
|||
pub struct ConfigSubspace {
|
||||
assembly_dim: usize,
|
||||
basis_std: Vec<DMatrix<f64>>,
|
||||
basis_proj: Vec<DMatrix<f64>>
|
||||
basis_proj: Vec<DMatrix<f64>>,
|
||||
}
|
||||
|
||||
impl ConfigSubspace {
|
||||
pub fn zero(assembly_dim: usize) -> ConfigSubspace {
|
||||
ConfigSubspace {
|
||||
assembly_dim: assembly_dim,
|
||||
assembly_dim,
|
||||
basis_proj: Vec::new(),
|
||||
basis_std: Vec::new()
|
||||
basis_std: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
// approximate the kernel of a symmetric endomorphism of the configuration
|
||||
// space for `assembly_dim` elements. we consider an eigenvector to be part
|
||||
// of the kernel if its eigenvalue is smaller than the constant `THRESHOLD`
|
||||
fn symmetric_kernel(a: DMatrix<f64>, proj_to_std: DMatrix<f64>, assembly_dim: usize) -> ConfigSubspace {
|
||||
fn symmetric_kernel(
|
||||
a: DMatrix<f64>,
|
||||
proj_to_std: DMatrix<f64>,
|
||||
assembly_dim: usize,
|
||||
) -> ConfigSubspace {
|
||||
// find a basis for the kernel. the basis is expressed in the projection
|
||||
// coordinates, and it's orthonormal with respect to the projection
|
||||
// inner product
|
||||
|
@ -170,7 +174,7 @@ impl ConfigSubspace {
|
|||
const ELEMENT_DIM: usize = 5;
|
||||
const UNIFORM_DIM: usize = 4;
|
||||
ConfigSubspace {
|
||||
assembly_dim: assembly_dim,
|
||||
assembly_dim,
|
||||
basis_std: basis_std.column_iter().map(
|
||||
|v| Into::<DMatrix<f64>>::into(
|
||||
v.reshape_generic(Dyn(ELEMENT_DIM), Dyn(assembly_dim))
|
||||
|
@ -180,7 +184,7 @@ impl ConfigSubspace {
|
|||
|v| Into::<DMatrix<f64>>::into(
|
||||
v.reshape_generic(Dyn(UNIFORM_DIM), Dyn(assembly_dim))
|
||||
)
|
||||
).collect()
|
||||
).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,9 +218,9 @@ pub struct DescentHistory {
|
|||
pub config: Vec<DMatrix<f64>>,
|
||||
pub scaled_loss: Vec<f64>,
|
||||
pub neg_grad: Vec<DMatrix<f64>>,
|
||||
pub hess_eigvals: Vec::<DVector<f64>>,
|
||||
pub hess_eigvals: Vec<DVector<f64>>,
|
||||
pub base_step: Vec<DMatrix<f64>>,
|
||||
pub backoff_steps: Vec<i32>
|
||||
pub backoff_steps: Vec<i32>,
|
||||
}
|
||||
|
||||
impl DescentHistory {
|
||||
|
@ -246,7 +250,7 @@ impl ConstraintProblem {
|
|||
ConstraintProblem {
|
||||
gram: PartialMatrix::new(),
|
||||
frozen: PartialMatrix::new(),
|
||||
guess: DMatrix::<f64>::zeros(ELEMENT_DIM, element_count)
|
||||
guess: DMatrix::<f64>::zeros(ELEMENT_DIM, element_count),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,7 +259,7 @@ impl ConstraintProblem {
|
|||
ConstraintProblem {
|
||||
gram: PartialMatrix::new(),
|
||||
frozen: PartialMatrix::new(),
|
||||
guess: DMatrix::from_columns(guess_columns)
|
||||
guess: DMatrix::from_columns(guess_columns),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -269,25 +273,21 @@ lazy_static! {
|
|||
0.0, 1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, -2.0,
|
||||
0.0, 0.0, 0.0, -2.0, 0.0
|
||||
0.0, 0.0, 0.0, -2.0, 0.0,
|
||||
]);
|
||||
}
|
||||
|
||||
struct SearchState {
|
||||
config: DMatrix<f64>,
|
||||
err_proj: DMatrix<f64>,
|
||||
loss: f64
|
||||
loss: f64,
|
||||
}
|
||||
|
||||
impl SearchState {
|
||||
fn from_config(gram: &PartialMatrix, config: DMatrix<f64>) -> SearchState {
|
||||
let err_proj = gram.sub_proj(&(config.tr_mul(&*Q) * &config));
|
||||
let loss = err_proj.norm_squared();
|
||||
SearchState {
|
||||
config: config,
|
||||
err_proj: err_proj,
|
||||
loss: loss
|
||||
}
|
||||
SearchState { config, err_proj, loss }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -314,7 +314,7 @@ pub fn local_unif_to_std(v: DVectorView<f64>) -> DMatrix<f64> {
|
|||
curv, 0.0, 0.0, 0.0, v[0],
|
||||
0.0, curv, 0.0, 0.0, v[1],
|
||||
0.0, 0.0, curv, 0.0, v[2],
|
||||
0.0, 0.0, 0.0, 0.0, 1.0
|
||||
0.0, 0.0, 0.0, 0.0, 1.0,
|
||||
])
|
||||
} else {
|
||||
// `v` represents a sphere. the normalization condition says that the
|
||||
|
@ -323,7 +323,7 @@ pub fn local_unif_to_std(v: DVectorView<f64>) -> DMatrix<f64> {
|
|||
curv, 0.0, 0.0, 0.0, v[0],
|
||||
0.0, curv, 0.0, 0.0, v[1],
|
||||
0.0, 0.0, curv, 0.0, v[2],
|
||||
curv*v[0], curv*v[1], curv*v[2], curv*v[3], curv*v[4] + 1.0
|
||||
curv*v[0], curv*v[1], curv*v[2], curv*v[3], curv*v[4] + 1.0,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
@ -336,7 +336,7 @@ fn seek_better_config(
|
|||
base_target_improvement: f64,
|
||||
min_efficiency: f64,
|
||||
backoff: f64,
|
||||
max_backoff_steps: i32
|
||||
max_backoff_steps: i32,
|
||||
) -> Option<(SearchState, i32)> {
|
||||
let mut rate = 1.0;
|
||||
for backoff_steps in 0..max_backoff_steps {
|
||||
|
@ -354,12 +354,12 @@ fn seek_better_config(
|
|||
// a first-order neighborhood of a configuration
|
||||
pub struct ConfigNeighborhood {
|
||||
pub config: DMatrix<f64>,
|
||||
pub nbhd: ConfigSubspace
|
||||
pub nbhd: ConfigSubspace,
|
||||
}
|
||||
|
||||
pub struct Realization {
|
||||
pub result: Result<ConfigNeighborhood, String>,
|
||||
pub history: DescentHistory
|
||||
pub history: DescentHistory,
|
||||
}
|
||||
|
||||
// seek a matrix `config` that matches the partial matrix `problem.frozen` and
|
||||
|
@ -373,12 +373,10 @@ pub fn realize_gram(
|
|||
backoff: f64,
|
||||
reg_scale: f64,
|
||||
max_descent_steps: i32,
|
||||
max_backoff_steps: i32
|
||||
max_backoff_steps: i32,
|
||||
) -> Realization {
|
||||
// destructure the problem data
|
||||
let ConstraintProblem {
|
||||
gram, guess, frozen
|
||||
} = problem;
|
||||
let ConstraintProblem { gram, guess, frozen } = problem;
|
||||
|
||||
// start the descent history
|
||||
let mut history = DescentHistory::new();
|
||||
|
@ -391,10 +389,10 @@ pub fn realize_gram(
|
|||
let result = Ok(
|
||||
ConfigNeighborhood {
|
||||
config: guess.clone(),
|
||||
nbhd: ConfigSubspace::zero(0)
|
||||
nbhd: ConfigSubspace::zero(0),
|
||||
}
|
||||
);
|
||||
return Realization { result, history }
|
||||
return Realization { result, history };
|
||||
}
|
||||
|
||||
// find the dimension of the search space
|
||||
|
@ -475,7 +473,7 @@ pub fn realize_gram(
|
|||
Some(cholesky) => cholesky,
|
||||
None => return Realization {
|
||||
result: Err("Cholesky decomposition failed".to_string()),
|
||||
history
|
||||
history,
|
||||
}
|
||||
};
|
||||
let base_step_stacked = hess_cholesky.solve(&neg_grad_stacked);
|
||||
|
@ -485,17 +483,17 @@ pub fn realize_gram(
|
|||
// use backtracking line search to find a better configuration
|
||||
if let Some((better_state, backoff_steps)) = seek_better_config(
|
||||
gram, &state, &base_step, neg_grad.dot(&base_step),
|
||||
min_efficiency, backoff, max_backoff_steps
|
||||
min_efficiency, backoff, max_backoff_steps,
|
||||
) {
|
||||
state = better_state;
|
||||
history.backoff_steps.push(backoff_steps);
|
||||
} else {
|
||||
return Realization {
|
||||
result: Err("Line search failed".to_string()),
|
||||
history
|
||||
}
|
||||
history,
|
||||
};
|
||||
}
|
||||
}
|
||||
let result = if state.loss < tol {
|
||||
// express the uniform basis in the standard basis
|
||||
const UNIFORM_DIM: usize = 4;
|
||||
|
@ -539,7 +537,7 @@ pub mod examples {
|
|||
[
|
||||
sphere(0.0, 0.0, 0.0, 15.0),
|
||||
sphere(0.0, 0.0, -9.0, 5.0),
|
||||
sphere(0.0, 0.0, 11.0, 3.0)
|
||||
sphere(0.0, 0.0, 11.0, 3.0),
|
||||
].into_iter().chain(
|
||||
(1..=6).map(
|
||||
|k| {
|
||||
|
@ -598,7 +596,7 @@ pub mod examples {
|
|||
point(0.0, 0.0, 0.0),
|
||||
point(ang_hor.cos(), ang_hor.sin(), 0.0),
|
||||
point(x_vert, y_vert, -0.5),
|
||||
point(x_vert, y_vert, 0.5)
|
||||
point(x_vert, y_vert, 0.5),
|
||||
]
|
||||
}
|
||||
).collect::<Vec<_>>().as_slice()
|
||||
|
@ -641,15 +639,15 @@ mod tests {
|
|||
MatrixEntry { index: (0, 0), value: 14.0 },
|
||||
MatrixEntry { index: (0, 2), value: 28.0 },
|
||||
MatrixEntry { index: (1, 1), value: 42.0 },
|
||||
MatrixEntry { index: (1, 2), value: 49.0 }
|
||||
MatrixEntry { index: (1, 2), value: 49.0 },
|
||||
]);
|
||||
let config = DMatrix::<f64>::from_row_slice(2, 3, &[
|
||||
1.0, 2.0, 3.0,
|
||||
4.0, 5.0, 6.0
|
||||
4.0, 5.0, 6.0,
|
||||
]);
|
||||
let expected_result = DMatrix::<f64>::from_row_slice(2, 3, &[
|
||||
14.0, 2.0, 28.0,
|
||||
4.0, 42.0, 49.0
|
||||
4.0, 42.0, 49.0,
|
||||
]);
|
||||
assert_eq!(frozen.freeze(&config), expected_result);
|
||||
}
|
||||
|
@ -660,15 +658,15 @@ mod tests {
|
|||
MatrixEntry { index: (0, 0), value: 19.0 },
|
||||
MatrixEntry { index: (0, 2), value: 39.0 },
|
||||
MatrixEntry { index: (1, 1), value: 59.0 },
|
||||
MatrixEntry { index: (1, 2), value: 69.0 }
|
||||
MatrixEntry { index: (1, 2), value: 69.0 },
|
||||
]);
|
||||
let attempt = DMatrix::<f64>::from_row_slice(2, 3, &[
|
||||
1.0, 2.0, 3.0,
|
||||
4.0, 5.0, 6.0
|
||||
4.0, 5.0, 6.0,
|
||||
]);
|
||||
let expected_result = DMatrix::<f64>::from_row_slice(2, 3, &[
|
||||
18.0, 0.0, 36.0,
|
||||
0.0, 54.0, 63.0
|
||||
0.0, 54.0, 63.0,
|
||||
]);
|
||||
assert_eq!(target.sub_proj(&attempt), expected_result);
|
||||
}
|
||||
|
@ -686,7 +684,7 @@ mod tests {
|
|||
DMatrix::from_columns(&[
|
||||
sphere(1.0, 0.0, 0.0, a),
|
||||
sphere(-0.5, a, 0.0, a),
|
||||
sphere(-0.5, -a, 0.0, a)
|
||||
sphere(-0.5, -a, 0.0, a),
|
||||
])
|
||||
};
|
||||
let state = SearchState::from_config(&gram, config);
|
||||
|
@ -700,7 +698,7 @@ mod tests {
|
|||
fn frozen_entry_test() {
|
||||
let mut problem = ConstraintProblem::from_guess(&[
|
||||
point(0.0, 0.0, 2.0),
|
||||
sphere(0.0, 0.0, 0.0, 0.95)
|
||||
sphere(0.0, 0.0, 0.0, 0.95),
|
||||
]);
|
||||
for j in 0..2 {
|
||||
for k in j..2 {
|
||||
|
@ -744,7 +742,7 @@ mod tests {
|
|||
let mut problem = ConstraintProblem::from_guess(&[
|
||||
sphere(0.0, 0.0, 0.0, -2.0),
|
||||
sphere(0.0, 0.0, 1.0, 1.0),
|
||||
sphere(0.0, 0.0, -1.0, 1.0)
|
||||
sphere(0.0, 0.0, -1.0, 1.0),
|
||||
]);
|
||||
for j in 0..3 {
|
||||
for k in j..3 {
|
||||
|
@ -774,8 +772,8 @@ mod tests {
|
|||
DMatrix::<f64>::from_column_slice(UNIFORM_DIM, assembly_dim, &[
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, -0.5, -0.5,
|
||||
0.0, 0.0, -0.5, 0.5
|
||||
])
|
||||
0.0, 0.0, -0.5, 0.5,
|
||||
]),
|
||||
];
|
||||
let tangent_motions_std = vec![
|
||||
basis_matrix((0, 1), element_dim, assembly_dim),
|
||||
|
@ -785,8 +783,8 @@ mod tests {
|
|||
DMatrix::<f64>::from_column_slice(element_dim, assembly_dim, &[
|
||||
0.0, 0.0, 0.0, 0.00, 0.0,
|
||||
0.0, 0.0, -1.0, -0.25, -1.0,
|
||||
0.0, 0.0, -1.0, 0.25, 1.0
|
||||
])
|
||||
0.0, 0.0, -1.0, 0.25, 1.0,
|
||||
]),
|
||||
];
|
||||
|
||||
// confirm that the dimension of the tangent space is no greater than
|
||||
|
@ -862,10 +860,10 @@ mod tests {
|
|||
DVector::from_column_slice(&[0.0, 0.0, 5.0, 0.0]),
|
||||
DVector::from_column_slice(&[0.0, 0.0, 1.0, 0.0]),
|
||||
DVector::from_column_slice(&[-vel_vert_x, -vel_vert_y, -3.0, 0.0]),
|
||||
DVector::from_column_slice(&[vel_vert_x, vel_vert_y, -3.0, 0.0])
|
||||
DVector::from_column_slice(&[vel_vert_x, vel_vert_y, -3.0, 0.0]),
|
||||
]
|
||||
}
|
||||
).collect::<Vec<_>>()
|
||||
).collect::<Vec<_>>(),
|
||||
];
|
||||
let tangent_motions_std = tangent_motions_unif.iter().map(
|
||||
|motion| DMatrix::from_columns(
|
||||
|
@ -898,7 +896,7 @@ mod tests {
|
|||
0.0, 1.0, 0.0, 0.0, dis[1],
|
||||
0.0, 0.0, 1.0, 0.0, dis[2],
|
||||
2.0*dis[0], 2.0*dis[1], 2.0*dis[2], 1.0, dis.norm_squared(),
|
||||
0.0, 0.0, 0.0, 0.0, 1.0
|
||||
0.0, 0.0, 0.0, 0.0, 1.0,
|
||||
])
|
||||
}
|
||||
|
||||
|
@ -910,7 +908,7 @@ mod tests {
|
|||
const SCALED_TOL: f64 = 1.0e-12;
|
||||
let mut problem_orig = ConstraintProblem::from_guess(&[
|
||||
sphere(0.0, 0.0, 0.5, 1.0),
|
||||
sphere(0.0, 0.0, -0.5, 1.0)
|
||||
sphere(0.0, 0.0, -0.5, 1.0),
|
||||
]);
|
||||
problem_orig.gram.push_sym(0, 0, 1.0);
|
||||
problem_orig.gram.push_sym(1, 1, 1.0);
|
||||
|
@ -928,13 +926,13 @@ mod tests {
|
|||
let a = 0.5 * FRAC_1_SQRT_2;
|
||||
DMatrix::from_columns(&[
|
||||
sphere(a, 0.0, 7.0 + a, 1.0),
|
||||
sphere(-a, 0.0, 7.0 - a, 1.0)
|
||||
sphere(-a, 0.0, 7.0 - a, 1.0),
|
||||
])
|
||||
};
|
||||
let problem_tfm = ConstraintProblem {
|
||||
gram: problem_orig.gram,
|
||||
frozen: problem_orig.frozen,
|
||||
guess: guess_tfm,
|
||||
frozen: problem_orig.frozen
|
||||
};
|
||||
let Realization { result: result_tfm, history: history_tfm } = realize_gram(
|
||||
&problem_tfm, SCALED_TOL, 0.5, 0.9, 1.1, 200, 110
|
||||
|
@ -962,7 +960,7 @@ mod tests {
|
|||
0.0, 1.0, 0.0, 0.0, 0.0,
|
||||
FRAC_1_SQRT_2, 0.0, FRAC_1_SQRT_2, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 1.0
|
||||
0.0, 0.0, 0.0, 0.0, 1.0,
|
||||
]);
|
||||
let transl = translation(Vector3::new(0.0, 0.0, 7.0));
|
||||
let motion_proj_tfm = transl * rot * motion_orig_proj;
|
||||
|
|
|
@ -14,20 +14,20 @@ use components::{
|
|||
add_remove::AddRemove,
|
||||
diagnostics::Diagnostics,
|
||||
display::Display,
|
||||
outline::Outline
|
||||
outline::Outline,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct AppState {
|
||||
assembly: Assembly,
|
||||
selection: Signal<BTreeSet<Rc<dyn Element>>>
|
||||
selection: Signal<BTreeSet<Rc<dyn Element>>>,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
fn new() -> AppState {
|
||||
AppState {
|
||||
assembly: Assembly::new(),
|
||||
selection: create_signal(BTreeSet::default())
|
||||
selection: create_signal(BTreeSet::default()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ use std::num::ParseFloatError;
|
|||
#[readonly::make]
|
||||
pub struct SpecifiedValue {
|
||||
pub spec: String,
|
||||
pub value: Option<f64>
|
||||
pub value: Option<f64>,
|
||||
}
|
||||
|
||||
impl SpecifiedValue {
|
||||
|
@ -37,7 +37,7 @@ impl TryFrom<String> for SpecifiedValue {
|
|||
Ok(SpecifiedValue::from_empty_spec())
|
||||
} else {
|
||||
spec.parse::<f64>().map(
|
||||
|value| SpecifiedValue { spec: spec, value: Some(value) }
|
||||
|value| SpecifiedValue { spec, value: Some(value) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue