perfect_freehand 0.1.1

A Rust port of the perfect-freehand library for creating smooth, beautiful freehand lines
Documentation
# Perfect Freehand


__A Rust port of [perfect-freehand](https://github.com/steveruizok/perfect-freehand) library__

A library for creating smooth, natural-looking freehand strokes from input points. It produces an array of outline points that form a polygon around the input, perfect for drawing applications.

## Installation


Add this to your `Cargo.toml`:

```toml
[dependencies]
perfect_freehand = "0.1"
```

## Usage


The main function is `get_stroke()`, which takes an array of input points (like those from mouse movements) and returns a vector of outline points forming a smooth stroke polygon.

```rust
// pseudocode-ish
use perfect_freehand::{get_stroke, InputPoint, StrokeOptions};

fn main() {
    // Collect input points from user (e.g., mouse coordinates)
    let points = vec![
        InputPoint::Array([100.0, 100.0], Some(0.5)),
        InputPoint::Array([200.0, 150.0], Some(0.7)),
        InputPoint::Array([300.0, 100.0], Some(0.5)),
        // ... more points
    ];

    // Create default options
    let options = StrokeOptions::default();

    // Generate the stroke outline
    let outline = get_stroke(&points, &options);

    // Use the outline points to draw a path
    // (e.g., convert to SVG or render with a graphics library)
}
```

## Rendering


You can render the stroke points with any graphics library. Here's an example using a hypothetical graphics backend:

```rust
use perfect_freehand::{get_stroke, InputPoint, StrokeOptions};

fn render_stroke(points: &[InputPoint]) {
    let options = StrokeOptions::default();
    let outline = get_stroke(points, &options);
    
    // Draw the polygon outline
    for i in 0..outline.len() {
        let p1 = outline[i];
        let p2 = outline[(i + 1) % outline.len()];
        draw_line(p1, p2);
    }
}
```

To get filled strokes, you can triangulate the polygon using a library like [earcutr](https://crates.io/crates/earcutr) and then render the triangles:

```rust
use perfect_freehand::{get_stroke, InputPoint, StrokeOptions};
use earcutr::earcut;

fn render_filled_stroke(points: &[InputPoint]) {
    let options = StrokeOptions::default();
    let outline = get_stroke(points, &options);
    
    // Convert to vertex coordinates
    let mut vertices: Vec<f64> = Vec::new();
    for p in &outline {
        vertices.push(p[0]);
        vertices.push(p[1]);
    }
    
    // Triangulate
    let triangles = earcut(&vertices, &[], 2);
    
    // Draw each triangle
    for tri in triangles.chunks(3) {
        let a = outline[tri[0]];
        let b = outline[tri[1]];
        let c = outline[tri[2]];
        draw_triangle(a, b, c);
    }
}
```

---

## Acknowledgements


This project is a port of [perfect-freehand](https://github.com/steveruizok/perfect-freehand)  
by [Steve Ruiz](https://github.com/steveruizok). Huge thanks to him for the original work. This Rust implementation is based on and improves upon previous Rust ports of the library.

## License


This project is licensed __as the original__ under the [MIT License](./LICENSE).

---
Copyright (c) 2021 Steve Ruiz - Original  
Copyright (c) 2025 Sibai Eshak - Rust port