diff --git a/lang-trials/rust/src/engine.rs b/lang-trials/rust/src/engine.rs new file mode 100644 index 0000000..0dbee3f --- /dev/null +++ b/lang-trials/rust/src/engine.rs @@ -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) -> Option { + // 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(), + }) + } + } +} \ No newline at end of file diff --git a/lang-trials/rust/src/main.rs b/lang-trials/rust/src/main.rs index f6b97c9..af011a2 100644 --- a/lang-trials/rust/src/main.rs +++ b/lang-trials/rust/src/main.rs @@ -1,8 +1,8 @@ -use nalgebra::*; +use nalgebra::Matrix2x3; use std::f64::consts::PI as PI; use sycamore::{prelude::*, rt::{JsCast, JsValue}}; -// --- interface --- +mod engine; fn main() { // 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 let data_vals = data.map(|sig| sig.get()).to_vec(); 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.set_stroke_style(&highlight_style); 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) -> Option { - // 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(), - }) - } - } } \ No newline at end of file