A geometric constraint solver written in Rust with WebAssembly bindings for web applications. This is me learning Rust, thus Angelo's Constraint Solver. This project is a work in progress and is not yet feature-complete. Contributions are welcome!
ACS is a library for solving geometric constraint systems.
- Geometric Primitives:
- Points ✅
- Lines
⚠️ (Removed temporarily, in favor of Point-based constraints) - Arcs
- Circles ✅
- Constraint Types:
- Vertical constraints (force lines to be vertical) ✅
- Horizontal constraints (force lines to be horizontal) ✅
- Parallel constraints (force two lines to be parallel) ✅
- Equal Y and X constraints (force points to have equal Y and X coordinates) ✅
- Coincident constraints (force two points to be coincident) ✅
- Point on line constraints (force a point to lie on a line) ✅
- Equal Radius constraints (force circles to have equal radius) ✅
- Perpendicular constraints (force two lines to be perpendicular)
- Angle constraints (force lines to form a specific angle)
- Dimension constraints (force lines/points to have specific lengths or distances)
- Solvers:
- - Dog-Leg solver ✅
- WebAssembly Support: Compile to WASM for use in web applications ✅
Note
This library is not yet published to crates.io or npm. You can build it from source or use the local path in your project.
Add this to your Cargo.toml
:
[dependencies]
acs = { path = "../path/to/acs" }
Important
The WebAssembly package is not yet published to npm. You can build it from source, check the Building section for details.
use acs::{ConstraintSolver, ConstraintType, Line, Point, SolverResult};
fn main() {
// Create a new constraint solver
let mut solver = ConstraintSolver::new();
// Add points
let p1 = Point::new(String::from("p1"), 0.0, 0.0, false);
let p2 = Point::new(String::from("p2"), 1.0, 1.0, false);
solver.add_point(p1);
solver.add_point(p2);
// Add a vertical constraint to the line
solver
.add_constraint(ConstraintType::Vertical("p1".into(), "p2".into()))
.unwrap();
// Solve the constraint system
let result = solver.solve().unwrap();
match result {
SolverResult::Converged { iterations, final_error, .. } => {
println!("Converged in {} iterations with error {}", iterations, final_error);
}
SolverResult::MaxIterationsReached { iterations, final_error, .. } => {
println!("Max iterations ({}) reached with error {}", iterations, final_error);
}
}
// Get the final positions
let start = solver.get_point("p1".into()).unwrap();
let end = solver.get_point("p2".into()).unwrap();
println!("Line endpoints: ({}, {}) to ({}, {})", start.x, start.y, end.x, end.y);
}
- Rust 1.70 or later
wasm-pack
for WebAssembly builds
cargo build --release
wasm-pack build --target web --out-dir pkg
The project includes comprehensive tests:
# Run all tests
cargo test
# Run specific test
cargo test --test vertical_test
# Run with output
cargo test -- --nocapture
This project is licensed under the MIT License - see the LICENSE file for details.