Move the engine into a module

This commit is contained in:
Aaron Fenyes 2024-07-29 13:14:32 -07:00
parent 42bdfabd91
commit 244f222eb0
2 changed files with 41 additions and 42 deletions

View File

@ -0,0 +1,38 @@
use nalgebra::*;
pub struct Circle {
pub center_x: f64,
pub center_y: f64,
pub radius: f64,
}
// construct the circle through the points given by the columns of `points`
pub fn circ_thru(points: Matrix2x3<f64>) -> Option<Circle> {
// build the matrix that maps the circle's coefficient vector to the
// negative of the linear part of the circle's equation, evaluated at the
// given points
let neg_lin_part = stack![2.0*points.transpose(), Vector3::repeat(1.0)];
// find the quadrdatic part of the circle's equation, evaluated at the given
// points
let quad_part = Vector3::from_iterator(
points.column_iter().map(|v| v.dot(&v))
);
// find the circle's coefficient vector, and from there its center and
// radius
match neg_lin_part.lu().solve(&quad_part) {
None => None,
Some(coeffs) => {
let center_x = coeffs[0];
let center_y = coeffs[1];
Some(Circle {
center_x: center_x,
center_y: center_y,
radius: (
coeffs[2] + center_x*center_x + center_y*center_y
).sqrt(),
})
}
}
}

View File

@ -1,8 +1,8 @@
use nalgebra::*; use nalgebra::Matrix2x3;
use std::f64::consts::PI as PI; use std::f64::consts::PI as PI;
use sycamore::{prelude::*, rt::{JsCast, JsValue}}; use sycamore::{prelude::*, rt::{JsCast, JsValue}};
// --- interface --- mod engine;
fn main() { fn main() {
// set up a config option that forwards panic messages to `console.error` // set up a config option that forwards panic messages to `console.error`
@ -66,7 +66,7 @@ fn main() {
// find and draw the circle through the given points // find and draw the circle through the given points
let data_vals = data.map(|sig| sig.get()).to_vec(); let data_vals = data.map(|sig| sig.get()).to_vec();
let points = Matrix2x3::from_vec(data_vals); let points = Matrix2x3::from_vec(data_vals);
if let Some(circ) = circ_thru(points) { if let Some(circ) = engine::circ_thru(points) {
ctx.begin_path(); ctx.begin_path();
ctx.set_stroke_style(&highlight_style); ctx.set_stroke_style(&highlight_style);
ctx.arc( ctx.arc(
@ -111,43 +111,4 @@ fn main() {
} }
} }
}); });
}
// --- engine ---
struct Circle {
center_x: f64,
center_y: f64,
radius: f64,
}
// construct the circle through the points given by the columns of `points`
fn circ_thru(points: Matrix2x3<f64>) -> Option<Circle> {
// build the matrix that maps the circle's coefficient vector to the
// negative of the linear part of the circle's equation, evaluated at the
// given points
let neg_lin_part = stack![2.0*points.transpose(), Vector3::repeat(1.0)];
// find the quadrdatic part of the circle's equation, evaluated at the given
// points
let quad_part = Vector3::from_iterator(
points.column_iter().map(|v| v.dot(&v))
);
// find the circle's coefficient vector, and from there its center and
// radius
match neg_lin_part.lu().solve(&quad_part) {
None => None,
Some(coeffs) => {
let center_x = coeffs[0];
let center_y = coeffs[1];
Some(Circle {
center_x: center_x,
center_y: center_y,
radius: (
coeffs[2] + center_x*center_x + center_y*center_y
).sqrt(),
})
}
}
} }