Skip to content

Commit

Permalink
feat: expose clipper builder, add path methods
Browse files Browse the repository at this point in the history
* Exposes the Clipper builder struct that uses a
  type state API to allow boolean operations on
  multiple paths at once.
* Create Clipper builders from Paths::to_clipper_subject() and
  Paths::to_clipper_open_subject().
* Add inflate/simplify methods to Path and Paths
* Update documentation and examples
  • Loading branch information
tirithen committed May 13, 2024
1 parent f56f919 commit 0702f67
Show file tree
Hide file tree
Showing 19 changed files with 636 additions and 130 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ mod helpers;
#[macroquad::main("Difference and inflate")]
async fn main() {
let circle = circle_path((5.0, 5.0), 3.0, 32);
let rectangle: Paths = vec![(0.0, 0.0), (5.0, 0.0), (5.0, 6.0), (0.0, 6.0)].into();
let rectangle = vec![(0.0, 0.0), (5.0, 0.0), (5.0, 6.0), (0.0, 6.0)];
let circle2 = circle_path((7.0, 7.0), 1.0, 32);

let result = difference(circle, rectangle, FillRule::default())
Expand Down
29 changes: 21 additions & 8 deletions examples/difference-and-inflate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,31 @@ use macroquad::prelude::*;
mod helpers;

#[macroquad::main("Difference and inflate")]
async fn main() {
async fn main() -> Result<(), ClipperError> {
let circle = circle_path((5.0, 5.0), 3.0, 32);
let rectangle: Paths = vec![(0.0, 0.0), (5.0, 0.0), (5.0, 6.0), (0.0, 6.0)].into();
let circle2 = circle_path((7.0, 7.0), 1.0, 32);
let circle2 = circle_path((6.0, 6.0), 2.0, 32);
let circle3 = circle_path((7.0, 7.0), 1.0, 32);
let rectangle = vec![(0.0, 0.0), (5.0, 0.0), (5.0, 6.0), (0.0, 6.0)];

let result = difference(circle, rectangle, FillRule::default())
.expect("Failed to run boolean operation");
// Functional API
let _result = difference(circle.clone(), circle2.clone(), FillRule::default())?;
let _result = difference(_result, circle3.clone(), FillRule::default())?;
let _result = difference(_result, rectangle.clone(), FillRule::default())?;

let result = difference(result.clone(), circle2, FillRule::default())
.expect("Failed to run boolean operation");
let _result2 = inflate(_result, 1.0, JoinType::Round, EndType::Polygon, 0.0);
let _result2 = simplify(_result2, 0.01, false);

let result2 = inflate(result.clone(), 1.0, JoinType::Round, EndType::Polygon, 0.0);
// Alternative Clipper builder API
let result = circle
.to_clipper_subject()
.add_clip(circle2)
.add_clip(circle3)
.add_clip(rectangle)
.difference(FillRule::default())?;

let result2 = result
.inflate(1.0, JoinType::Round, EndType::Polygon, 0.0)
.simplify(0.01, false);

loop {
clear_background(BLACK);
Expand Down
12 changes: 9 additions & 3 deletions examples/difference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@ use macroquad::prelude::*;
mod helpers;

#[macroquad::main("Difference")]
async fn main() {
async fn main() -> Result<(), ClipperError> {
let path_a: Paths = vec![(0.2, 0.2), (6.0, 0.2), (6.0, 6.0), (0.2, 6.0)].into();
let path_b: Paths = vec![(5.0, 5.0), (8.0, 5.0), (8.0, 8.0), (5.0, 8.0)].into();

let result = difference(path_a.clone(), path_b.clone(), FillRule::default())
.expect("Failed to run boolean operation");
// Functional API
let _result = difference(path_a.clone(), path_b.clone(), FillRule::default())?;

// Alternative Clipper builder API
let result = path_a
.to_clipper_subject()
.add_clip(path_b.clone())
.difference(FillRule::default())?;

loop {
clear_background(BLACK);
Expand Down
6 changes: 5 additions & 1 deletion examples/inflate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ mod helpers;
async fn main() {
let path: Paths = vec![(2.0, 2.0), (6.0, 2.0), (6.0, 10.0), (2.0, 6.0)].into();

let result = inflate(path.clone(), 1.0, JoinType::Round, EndType::Polygon, 0.0);
// Functional API
let _result = inflate(path.clone(), 1.0, JoinType::Round, EndType::Polygon, 0.0);

// Alternative paths API
let result = path.inflate(1.0, JoinType::Round, EndType::Polygon, 0.0);

loop {
clear_background(BLACK);
Expand Down
12 changes: 9 additions & 3 deletions examples/intersect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@ use macroquad::prelude::*;
mod helpers;

#[macroquad::main("Intersect")]
async fn main() {
async fn main() -> Result<(), ClipperError> {
let path_a: Paths = vec![(0.2, 0.2), (6.0, 0.2), (6.0, 6.0), (0.2, 6.0)].into();
let path_b: Paths = vec![(5.0, 5.0), (8.0, 5.0), (8.0, 8.0), (5.0, 8.0)].into();

let result = intersect::<Centi>(path_a.clone(), path_b.clone(), FillRule::default())
.expect("Failed to run boolean operation");
// Functional API
let _result = intersect::<Centi>(path_a.clone(), path_b.clone(), FillRule::default())?;

// Alternative Clipper builder API
let result = path_a
.to_clipper_subject()
.add_clip(path_b.clone())
.intersect(FillRule::default())?;

loop {
clear_background(BLACK);
Expand Down
20 changes: 13 additions & 7 deletions examples/simplify.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
use clipper2::*;
use helpers::{draw_paths, draw_paths_points};
use helpers::{draw_path, draw_path_points};
use macroquad::prelude::*;

mod helpers;

#[macroquad::main("Simplify")]
async fn main() {
let path: Paths = vec![(1.0, 2.0), (1.0, 2.5), (1.2, 4.0), (1.8, 6.0)].into();
let path_simplified = simplify(path.translate(3.0, 0.0), 0.5, false);
let path: Path = vec![(1.0, 2.0), (1.0, 2.5), (1.2, 4.0), (1.8, 6.0)].into();

// Functional API
let _path = path.translate(3.0, 3.0);
let _simplified = simplify(path.clone(), 0.5, false);

// Alternative paths API
let simplified = path.translate(3.0, 0.0).simplify(0.5, false);

loop {
clear_background(BLACK);
draw_paths(&path, SKYBLUE);
draw_paths(&path_simplified, SKYBLUE);
draw_paths_points(&path, GREEN);
draw_paths_points(&path_simplified, GREEN);
draw_path(&path, SKYBLUE);
draw_path(&simplified, SKYBLUE);
draw_path_points(&path, GREEN);
draw_path_points(&simplified, GREEN);
next_frame().await
}
}
12 changes: 9 additions & 3 deletions examples/union.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@ use macroquad::prelude::*;
mod helpers;

#[macroquad::main("Union")]
async fn main() {
async fn main() -> Result<(), ClipperError> {
let path_a: Paths = vec![(0.2, 0.2), (6.0, 0.2), (6.0, 6.0), (0.2, 6.0)].into();
let path_b: Paths = vec![(5.0, 5.0), (8.0, 5.0), (8.0, 8.0), (5.0, 8.0)].into();

let result = union(path_a.clone(), path_b.clone(), FillRule::default())
.expect("Failed to run boolean operation");
// Functional API
let _result = union(path_a.clone(), path_b.clone(), FillRule::default())?;

// Alternative Clipper builder API
let result = path_a
.to_clipper_subject()
.add_clip(path_b.clone())
.union(FillRule::default())?;

loop {
clear_background(BLACK);
Expand Down
12 changes: 9 additions & 3 deletions examples/xor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@ use macroquad::prelude::*;
mod helpers;

#[macroquad::main("XOR")]
async fn main() {
async fn main() -> Result<(), ClipperError> {
let path_a: Paths = vec![(0.2, 0.2), (6.0, 0.2), (6.0, 6.0), (0.2, 6.0)].into();
let path_b: Paths = vec![(5.0, 5.0), (8.0, 5.0), (8.0, 8.0), (5.0, 8.0)].into();

let result = xor(path_a.clone(), path_b.clone(), FillRule::default())
.expect("Failed to run boolean operation");
// Functional API
let _result = xor(path_a.clone(), path_b.clone(), FillRule::default())?;

// Alternative Clipper builder API
let result = path_a
.to_clipper_subject()
.add_clip(path_b.clone())
.xor(FillRule::default())?;

loop {
clear_background(BLACK);
Expand Down

0 comments on commit 0702f67

Please sign in to comment.