Expand description
A small library dedicated to LASER path optimisation.
The goal for the library is to provide a suite of useful tools for optimising linear vector images for galvanometer-based LASER projection. To allow lasy LASERs to get more done.
This crate implements the full suite of optimisations covered in Accurate and Efficient Drawing Method for Laser Projection by Purkhet Abderyim et al. These include Graph optimisation, draw order optimisation, blanking delays and sharp angle delays. See the paper for more details.
§Optimising a Vector Image
Optimising a single frame of input_points
is achieved by the following steps:
- Convert the list of points to a list of segments, tracking whether they are blank or lit.
- Convert the segments to a graph where the nodes are points. Only a single node for each unique position is stored.
- Convert the point graph to a euler graph, determining the minimum number of blanks necessary to do so.
- Find the optimal euler circuit within the euler graph. This represents the new path that the LASER should travel.
- Interpolate the euler circuit. This step will attempt to distribute the “target count” number of points across the euler circuit while accounting for blanking and sharp angle delays in accordance with the provided configuration.
In code, these steps look like so:
let segs = points_to_segments(&input_points);
let pg = segments_to_point_graph(&input_points, segs);
let eg = point_graph_to_euler_graph(&pg);
let ec = euler_graph_to_euler_circuit(&input_points, &eg);
let output_points = interpolate_euler_circuit(&input_points, &ec, &eg, target_count, config);
§Optimising Animation
It is worth keeping in mind that, if you are working with an animated stream of frames, some consideration must be taken in how to move from the end of one frame to the beginning of the next.
For the most part, this simply requires blanking from the last point of the previous frame to the first point of the current one (or in other words, the first point of the euler circuit for the current frame).
The blank_segment_points
function can be useful for generating these points, as this same
function is used for generating blank segment points during interpolation.
§Point Types
In order to have your points be compatible with the functions provided by this crate, the
Position
, IsBlank
, Weight
, Blanked
and Lerp
traits should be implemented as
necessary. Please see their respective documentation for more information.
Note that the optimisation steps above are intended to work with two different point types: an
input point type describing the user’s original frame and an output (or raw) point type
representing the fully interpolated, optimised path. The main difference between these two
types is that the output point type does not to store its weight, as point weighting is
applied during the interpolation process. See the Weight
docs for more details.
§Graph Storage
The graphs used within the optimisation steps above will never store points directly, and
instead will store indices into the original slice of input_points
. This allows for a smaller
memory footprint and to avoid complicated generics propagating up through the graph types.
Re-exports§
Structs§
- Edge
Profile - Capture a profile of each edge to assist the interpolation process.
- Interpolation
Config - Configuration options for eulerian circuit interpolation.
- Segment
- Represents a line segment over which the laser scanner will travel.
- Segments
- An iterator yielding all lit line segments.
Enums§
- Direction
- Edge direction.
- Edge
Profile Kind - Edge profile data specific to the kind of edge.
- Segment
Kind - describes whether a line segment between two points is blank or not.
Constants§
- BLANK_
MIN_ POINTS - For the blank ab:
[a, a.blanked(), b.blanked(), (0..delay).map(|_| b.blanked())]
.
Traits§
- Blanked
- Point types that can produce a blanked copy of themselves.
- IsBlank
- Point types that can describe whether or not they are blank (black).
- Lerp
- Types that can be linearly interpolated.
- Position
- Point types that may describe position.
- Weight
- Point types that have a weight associated with them.
Functions§
- blank_
segment_ point_ count - The number of points used per blank segment given the
blank_delay_points
from a config. - blank_
segment_ points - Returns the points used to blank between two given lit points a and b.
- corner_
point_ count - The number of points added at a lit corner given its angle and angular delay rate.
- distance_
min_ point_ count - The minimum points for traversing a lit segment (not including end corner delays).
- ec_
edge_ end - Given some Euler Circuit edge
e
and its directiond
, return the index of the node that represents the end of the edge. - ec_
edge_ start - Given some Euler Circuit edge
e
and its directiond
, return the index of the node that represents the start of the edge. - euler_
circuit_ to_ segments - Produce an iterator yielding
Segment
s representing the euler circuit’s path through the euler graph. - euler_
graph_ to_ euler_ circuit - Given a Euler Graph describing the vector image to be drawn, return the optimal Euler Circuit describing the path over which the laser should travel.
- interpolate_
euler_ circuit - Interpolate the given
EulerCircuit
with the given configuration. - interpolate_
path - The same as
interpolate_profiled_path
, but performs the path profiling step internally prior to interpolation. - interpolate_
profiled_ path - Interpolate the path described by the given
edges
. - lit_
segment_ min_ point_ count - The minimum number of points used for a lit segment of the given distance and end angle.
- lit_
segment_ points - Returns the points that make up a lit segment between a and b including delay for the end corner.
- point_
graph_ to_ euler_ graph - Convert a point graph to a euler graph.
- points_
to_ segments - Create an iterator yielding segments from an iterator yielding points.
- profile_
path - Traverse a path described by an iterator yielding edges, profiling the edges along the way.
- segments_
to_ point_ graph - Convert the given laser frame vector segments to a graph of points.
Type Aliases§
- Euler
Circuit - A type used to represent a eulerian circuit through an eulerian graph.
- Euler
Graph - A type used to represent a graph of points that contains at least one euler circuit.
- Point
Graph - A type used to represent graph describing the points in a frame and how they are joined.
- Point
Index - An index into a slice of points.