diff --git a/engine-proto/ConstructionViewer.jl b/engine-proto/alg-test/ConstructionViewer.jl similarity index 100% rename from engine-proto/ConstructionViewer.jl rename to engine-proto/alg-test/ConstructionViewer.jl diff --git a/engine-proto/Engine.Algebraic.jl b/engine-proto/alg-test/Engine.Algebraic.jl similarity index 100% rename from engine-proto/Engine.Algebraic.jl rename to engine-proto/alg-test/Engine.Algebraic.jl diff --git a/engine-proto/Engine.Numerical.jl b/engine-proto/alg-test/Engine.Numerical.jl similarity index 100% rename from engine-proto/Engine.Numerical.jl rename to engine-proto/alg-test/Engine.Numerical.jl diff --git a/engine-proto/Engine.jl b/engine-proto/alg-test/Engine.jl similarity index 100% rename from engine-proto/Engine.jl rename to engine-proto/alg-test/Engine.jl diff --git a/engine-proto/HittingSet.jl b/engine-proto/alg-test/HittingSet.jl similarity index 100% rename from engine-proto/HittingSet.jl rename to engine-proto/alg-test/HittingSet.jl diff --git a/lang-trials/rust/.gitignore b/lang-trials/rust/.gitignore new file mode 100644 index 0000000..1d4e644 --- /dev/null +++ b/lang-trials/rust/.gitignore @@ -0,0 +1,2 @@ +target/* +dist/* \ No newline at end of file diff --git a/lang-trials/rust/Cargo.toml b/lang-trials/rust/Cargo.toml new file mode 100644 index 0000000..278a7c3 --- /dev/null +++ b/lang-trials/rust/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "sycamore-trial" +version = "0.1.0" +authors = ["Aaron"] +edition = "2021" + +[features] +default = ["console_error_panic_hook"] + +[dependencies] +nalgebra = "0.33.0" +sycamore = "0.9.0-beta.2" + +# The `console_error_panic_hook` crate provides better debugging of panics by +# logging them with `console.error`. This is great for development, but requires +# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for +# code size when deploying. +console_error_panic_hook = { version = "0.1.7", optional = true } + +[dependencies.web-sys] +version = "0.3.69" +features = [ + 'CanvasRenderingContext2d', + 'HtmlCanvasElement', +] + +[dev-dependencies] +wasm-bindgen-test = "0.3.34" + +[profile.release] +# Tell `rustc` to optimize for small code size. +opt-level = "s" diff --git a/lang-trials/rust/index.html b/lang-trials/rust/index.html new file mode 100644 index 0000000..04a39a0 --- /dev/null +++ b/lang-trials/rust/index.html @@ -0,0 +1,8 @@ + + + + Lattice circle + + + + diff --git a/lang-trials/rust/main.css b/lang-trials/rust/main.css new file mode 100644 index 0000000..7045d73 --- /dev/null +++ b/lang-trials/rust/main.css @@ -0,0 +1,50 @@ +body { + margin-left: 20px; + margin-top: 20px; + color: #fcfcfc; + background-color: #202020; +} + +input { + color: inherit; + background-color: #020202; + border: 1px solid #606060; + min-width: 40px; + border-radius: 4px; +} + +input.point-1 { + border-color: #ba5d09; +} + +input.point-2 { + border-color: #0e8a06; +} + +input.point-3 { + border-color: #8951fb; +} + +#data-panel { + float: left; + margin-left: 20px; + display: grid; + grid-template-columns: auto auto; + gap: 10px 10px; + width: 120px; +} + +#data-panel > div { + text-align: center; +} + +#result-display { + margin-top: 10px; + font-weight: bold; +} + +canvas { + float: left; + background-color: #020202; + border-radius: 10px; +} \ No newline at end of file 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 new file mode 100644 index 0000000..af011a2 --- /dev/null +++ b/lang-trials/rust/src/main.rs @@ -0,0 +1,114 @@ +use nalgebra::Matrix2x3; +use std::f64::consts::PI as PI; +use sycamore::{prelude::*, rt::{JsCast, JsValue}}; + +mod engine; + +fn main() { + // set up a config option that forwards panic messages to `console.error` + #[cfg(feature = "console_error_panic_hook")] + console_error_panic_hook::set_once(); + + sycamore::render(|| { + let data = [-1.0, 0.0, 0.0, -1.0, 1.0, 0.0].map(|n| create_signal(n)); + let display = create_node_ref(); + + on_mount(move || { + let canvas = display + .get::() + .unchecked_into::(); + let ctx = canvas + .get_context("2d") + .unwrap() + .unwrap() + .dyn_into::() + .unwrap(); + + create_effect(move || { + // center and normalize the coordinate system + let width = canvas.width() as f64; + let height = canvas.height() as f64; + ctx.set_transform(1.0, 0.0, 0.0, -1.0, 0.5*width, 0.5*height).unwrap(); + + // clear the previous frame + ctx.clear_rect(-0.5*width, -0.5*width, width, height); + + // find the resolution + const R_DISP: f64 = 5.0; + let res = width / (2.0*R_DISP); + + // set colors + let highlight_style = JsValue::from("white"); + let grid_style = JsValue::from("#404040"); + let point_fill_styles = ["#ba5d09", "#0e8a06", "#8951fb"]; + let point_stroke_styles = ["#f89142", "#58c145", "#c396fc"]; + + // draw the grid + let r_grid = (R_DISP - 0.01).floor() as i32; + let edge_scr = res * R_DISP; + ctx.set_stroke_style(&grid_style); + for t in -r_grid ..= r_grid { + let t_scr = res * (t as f64); + + // draw horizontal grid line + ctx.begin_path(); + ctx.move_to(-edge_scr, t_scr); + ctx.line_to(edge_scr, t_scr); + ctx.stroke(); + + // draw vertical grid line + ctx.begin_path(); + ctx.move_to(t_scr, -edge_scr); + ctx.line_to(t_scr, edge_scr); + ctx.stroke(); + } + + // 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) = engine::circ_thru(points) { + ctx.begin_path(); + ctx.set_stroke_style(&highlight_style); + ctx.arc( + res * circ.center_x, + res * circ.center_y, + res * circ.radius, + 0.0, 2.0*PI + ).unwrap(); + ctx.stroke(); + } + + // draw the data points + for n in 0..3 { + ctx.begin_path(); + ctx.set_fill_style(&JsValue::from(point_fill_styles[n])); + ctx.set_stroke_style(&JsValue::from(point_stroke_styles[n])); + let ind_x = 2*n; + let ind_y = ind_x + 1; + ctx.arc( + res * data[ind_x].get(), + res * data[ind_y].get(), + 3.0, + 0.0, 2.0*PI + ).unwrap(); + ctx.fill(); + ctx.stroke(); + } + }); + }); + + view! { + canvas(ref=display, width="600", height="600") + div(id="data-panel") { + div { "x" } + div { "y" } + input(type="number", class="point-1", bind:valueAsNumber=data[0]) + input(type="number", class="point-1", bind:valueAsNumber=data[1]) + input(type="number", class="point-2", bind:valueAsNumber=data[2]) + input(type="number", class="point-2", bind:valueAsNumber=data[3]) + input(type="number", class="point-3", bind:valueAsNumber=data[4]) + input(type="number", class="point-3", bind:valueAsNumber=data[5]) + } + } + }); +} \ No newline at end of file