2. Deduplicating segments
When plotting the REVERSE_DIFFERENCE example above we might have a small issue: let’s open it in Inkscape and move the shapes a bit:

The issue is that we have repeated lines. This is not an issue when showing the design on the screen, but when plotting, some lines are plotted twice. This will make plotting slower and some lines may look darker than others. No big deal with 3 circles, but with complex designs it does make a difference.
To get around this issue I wrote a simple function called .dedupe(). Using it couldn’t be easier: call the method before saving the file like this:
svg.dedupe().saveToFile(file)
Here’s the source code for Composition.dedupe() and for the required Segment.contains():
/**
* For a Composition, filter out bezier segments contained in longer bezier segments.
* The goal is to avoid drawing lines multiple times with a plotter.
*/
fun Composition.dedupe(err: Double = 1.0): Composition {
val segments = this.findShapes().flatMap {
it.shape.contours.flatMap { contour -> contour.segments }
}
val deduped = mutableListOf<Segment>()
segments.forEach { curr ->
if (deduped.none { other -> other.contains(curr, err) }) {
deduped.add(curr)
}
}
return drawComposition {
contours(deduped.map { it.contour })
}
}
/**
* Simple test to see if a segment contains a different Segment.
* Compares start, end and two points at 1/3 and 2/3.
* Returns false when comparing a Segment to itself.
*/
fun Segment.contains(other: Segment, error: Double = 0.5): Boolean =
this !== other &&
this.on(other.start, error) != null &&
this.on(other.end, error) != null &&
this.on(other.position(1.0 / 3), error) != null &&
this.on(other.position(2.0 / 3), error) != null
It probably doesn’t cover every case but maybe it helps someone?