spiropath 0.1.1

Generalized Spirograph using arbitrary paths.
Documentation
# spiropath
[![license](https://img.shields.io/crates/l/spiropath.svg)](https://github.com/orenbenkiki/spiropath/blob/master/LICENSE.txt)
[![crates.io](https://img.shields.io/crates/v/spiropath.svg)](https://crates.io/crates/spiropath)
[![Build Status](https://api.travis-ci.com/orenbenkiki/spiropath.svg?branch=master)](https://travis-ci.com/orenbenkiki/spiropath)
[![codecov](https://codecov.io/gh/orenbenkiki/spiropath/branch/master/graph/badge.svg)](https://codecov.io/gh/orenbenkiki/spiropath)
[![Docs](https://docs.rs/spiropath/badge.svg)](https://docs.rs/crate/spiropath)

Generalized Spirograph program allowing using arbitrary rotating and stationary shapes specified as
SVG paths.

## Installing

To install:

```
cargo install spiropath
```

## Using

This crate installs a `spiropath` program you can directly invoke from the command line: `spiropath
-s stationary.svg -r rotating.svg -o output.svg`, where `stationary.svg` contains a single SVG path
for the stationary shape and `rotating.svg` contains a single SVG path for the shape rotating around
it. The output SVG file will contain a single polyline tracing the path of a point affixed to the
rotating shape as it is moved around the rotating shape.

In addition this crate provides the same functionality (sans the file input/output) as a
`spiropath::spiropath` library function you can use in your own code.

A "classical" [Spirograph](https://en.wikipedia.org/wiki/Spirograph) uses only circles for both the
stationary and rotating shapes. Some Spirograph programs (or physical sets) provide more shapes but
in general these shapes are restricted to a combination of lines and arcs, and the overall
configuration (even in programs) is restricted by physics (e.g. the traced point must be internal to
the rotating shape).

In contrast, Spiropath places no restrictions on the stationary and rotating shapes (other than
requiring them to be continuous closed paths), or the position of the traced point: the rotating
shape is moved around the stationary one ignoring any collisions, and the traced point is moved with
it. You can therefore not only specify shapes using any cubic curves (rather than being restricted
to lines and arcs), but you can also use non-convex (or even self-intersecting) shapes, and in
general specify configurations which are impossible to achieve using a physical spirograph device
(e.g. placing the trace point outside the rotating shape).

In general the output SVG is expected to be further processed before the final visualization (e.g.
using [Inkscape](https://inkscape.org), so Spiropath doesn't provide options to control the path's
color, style, width, etc.

Spiropath does provide options to specify the relative sizes of the stationary and the rotating
shapes (the number of "teeth" along each of the shapes), the accuracy tolerance (as a fraction of
the tooth size), the size of the output (its bounding box), the initial rotation and offsets of the
rotating shape, the position of the traced point in the coordinates of the rotated shape, and
whether the rotating shape is placed "inside" or "outside" the stationary shape.

The resulting polyline will have a "lot" of points (depending on the tolerance); ideally we'd
convert it to a compact representation using SVG path elements such as arcs and curves. However, I
couldn't find a Rust library to do this. If you are aware of one, please let me know.

In the meanwhile, you can use external tools, for example using [Inkscape](https://inkscape.org/) to
either manually simplify the path as described in the "Simplification" section
[here](https://inkscape.org/doc/tutorials/advanced/tutorial-advanced.html) or automate this as
described
[here](https://stackoverflow.com/questions/7299564/automatizing-simplify-path-for-a-svg-file-using-inkscape).

## License

`spiropath` is distributed under the GNU AFFERO General Public License (Version 3.0). See the
[LICENSE](LICENSE.txt) for details.