Geometry — curves and profiles#
Parametric curves, their frames, closed 2D profiles, and curves made from meshes and node contours.
The solids built from them (Tube, Extrude, Revolve, Sweep) are on the leaves page.
Curves#
-
class Curve#
- #include <curve.h>
An immutable parametric curve in 3D space.
Every curve maps a parameter t in domain() to a point. Planar curves are the case where every point lies in one plane (plane_normal()); 2D input is placed at z = 0.
The base class owns the machinery every curve shares. Each concrete curve splits itself into pieces: parameter intervals with a rigorous bounding box and a bound on how far the piece strays from its chord. From these the base class builds, once:
an AABB tree for closest-point queries;
a cumulative arc-length table (exact for straight pieces, 8-point Gauss-Legendre otherwise);
the bounding box and the plane of the curve.
Closest point: pieces whose box is farther than the best distance found so far are pruned, and each remaining piece is refined with safeguarded Newton iterations on (c(t) - p) . c’(t). The piece holding the true minimiser is never pruned, so the result is exact to Newton tolerance (about 1e-12 relative). The exception is a query point near the centre of curvature of a curved piece, where Newton can settle on a local minimum of that piece; the distance is then within twice the piece’s deviation from its chord of the true minimum. BezierCurve and BSplineCurve pieces deviate by at most 1e-5 of the control-point box diagonal. Straight pieces are projected in closed form and ArcCurve overrides the search with a closed form, so LineSegment, PolylineCurve and ArcCurve are exact.
Curves never change after construction, so every query is lock-free and curves are shared between node clones and threads. (Polyline2, the legacy 2D polyline, is the one exception: its in-place edits rebuild the curve and must not overlap other use of the same object.)
Subclassed by ArcCurve, BSplineCurve, BezierCurve, CompositeCurve, LineSegment, PolylineCurve, TrimmedCurve
Public Functions
-
inline std::pair<glm::dvec3, glm::dvec3> bounding_box() const#
Returns a box containing the whole curve.
- Returns:
The pair (minimum, maximum).
-
virtual CurveHit closest_point(const glm::dvec3 &point) const#
Finds the point of the curve closest to a point.
- Parameters:
point – The query point.
- Throws:
std::runtime_error – if the curve is empty.
- Returns:
The parameter, the closest point and the distance.
-
virtual std::vector<glm::dvec3> defining_points() const = 0#
Returns points whose plane, if any, is the plane of the curve (for example the control points).
- Returns:
The defining points.
-
virtual glm::dvec3 derivative(double t, int order = 1) const = 0#
Evaluates a derivative of the curve with respect to t.
- Parameters:
t – The parameter (clamped or wrapped as in point()).
order – 1 or 2. Where the curve has a corner, the derivative of the piece that starts at t is returned (the last piece at the end of the domain).
- Returns:
The derivative vector.
-
inline double distance(const glm::dvec3 &point) const#
Returns the distance from a point to the curve.
- Parameters:
point – The query point.
- Returns:
The unsigned distance (see closest_point()).
-
inline std::pair<double, double> domain() const#
Returns the parameter domain.
- Returns:
The pair (start, end).
-
inline double end_parameter() const#
Returns the last parameter of the domain.
- Returns:
The end parameter.
-
inline bool is_closed() const#
Returns true when the curve ends where it starts.
- Returns:
Whether the curve is closed.
-
bool is_in_xy_plane() const#
Returns true when every point of the curve has z = 0.
The bounding box must lie within 1e-9 x max(1, size()) of z = 0.
- Returns:
Whether the curve lies in the XY plane.
-
inline double length() const#
Returns the total arc length.
- Returns:
The arc length of the whole curve.
-
double length_at(double t) const#
Returns the arc length from the start of the curve to parameter t.
- Parameters:
t – The parameter (clamped or wrapped as in point()).
- Throws:
std::runtime_error – if the curve is empty.
- Returns:
The arc length from start_parameter() to t.
-
std::shared_ptr<Curve> mirrored(const glm::dvec3 &point, const glm::dvec3 &normal) const#
Returns the curve reflected in a plane.
In the XY plane, a plane normal with z = 0 reflects across the line through
pointperpendicular to that normal.- Parameters:
point – A point on the mirror plane.
normal – The mirror plane’s normal; non-zero.
- Returns:
A new curve.
-
double normalize_parameter(double t) const#
Returns t clamped to the domain (open curves) or wrapped into it (closed curves).
- Parameters:
t – The parameter.
- Returns:
The parameter inside domain().
-
double parameter_at_length(double length) const#
Returns the parameter at which the arc length from the start equals length.
- Parameters:
length – The arc length; clamped to [0, length()] (wrapped for closed curves).
- Throws:
std::runtime_error – if the curve is empty.
- Returns:
The parameter.
-
inline const std::vector<Piece> &pieces() const#
Returns the pieces the curve is split into, in parameter order.
- Returns:
The pieces.
-
inline std::optional<glm::dvec3> plane_normal() const#
Returns the normal of the plane holding the curve, or std::nullopt for a non-planar or straight curve.
The sign is canonical: z > 0, or y > 0 when z is zero, or x > 0 when both are zero.
- Returns:
The unit plane normal, or std::nullopt.
-
virtual glm::dvec3 point(double t) const = 0#
Evaluates the curve.
- Parameters:
t – The parameter. Open curves clamp it to the domain; closed curves wrap it.
- Returns:
The point at t.
-
virtual std::shared_ptr<Curve> reversed() const = 0#
Returns the same curve traversed from end to start.
- Returns:
A new curve.
-
std::shared_ptr<Curve> rotated(double degrees, const glm::dvec3 &axis = glm::dvec3(0.0, 0.0, 1.0), const glm::dvec3 ¢er = glm::dvec3(0.0)) const#
Returns the curve turned about an axis through a centre.
- Parameters:
degrees – The angle, counter-clockwise looking down the axis.
axis – The rotation axis; non-zero.
center – A point on the axis.
- Returns:
A new curve.
-
std::vector<glm::dvec3> sample(size_t count) const#
Returns points spaced evenly in arc length (see sample_parameters()).
- Parameters:
count – The number of points.
- Returns:
The points, in order.
-
std::vector<double> sample_parameters(size_t count) const#
Returns parameters spaced evenly in arc length.
- Parameters:
count – The number of parameters. Open curves include both ends; closed curves do not repeat the start.
- Throws:
std::runtime_error – if count is positive and the curve is empty.
- Returns:
The parameters, in order.
-
std::shared_ptr<Curve> scaled(double factor, const glm::dvec3 ¢er = glm::dvec3(0.0)) const#
Returns the curve scaled uniformly about a centre.
- Parameters:
factor – The scale factor; positive.
center – The fixed point.
- Returns:
A new curve.
-
double size() const#
Returns the length of the diagonal of the bounding box.
- Returns:
The diagonal length.
-
inline double start_parameter() const#
Returns the first parameter of the domain.
- Returns:
The start parameter.
-
glm::dvec3 tangent(double t) const#
Returns the unit tangent at t.
Falls back to the second derivative, then to a finite difference, where the first derivative vanishes.
- Parameters:
t – The parameter (clamped or wrapped as in point()).
- Returns:
The unit tangent.
-
std::vector<glm::dvec3> tessellate(double tolerance) const#
Returns the points of a polyline within tolerance of the curve.
- Parameters:
tolerance – The largest allowed distance between the polyline and the curve; positive.
- Returns:
The points at tessellation_parameters(tolerance).
-
std::vector<double> tessellation_parameters(double tolerance) const#
Returns parameters of a polyline that stays within tolerance of the curve.
Open curves include both ends; closed curves do not repeat the start. Straight pieces contribute only their ends.
- Parameters:
tolerance – The largest allowed distance between the polyline and the curve; positive.
- Throws:
std::runtime_error – if the tolerance is not positive or the curve is empty.
- Returns:
The parameters, in order.
-
virtual std::shared_ptr<Curve> transformed(const glm::dmat4 &matrix) const = 0#
Returns the curve with every point mapped by an affine transform.
The parameterization is kept: the new curve at t is the transform of this curve at t, and the curve keeps its type, so lines stay lines and arcs stay arcs. Lines, polylines, Bezier curves and B-splines accept any affine transform; an ArcCurve (and a curve containing one) needs a similarity, made of rotations, reflections, a uniform scale and a translation.
- Parameters:
matrix – The transform, applied to points as matrix * (x, y, z, 1).
- Throws:
std::runtime_error – if the matrix is not finite and invertible, or an arc gets a transform that is not a similarity.
- Returns:
A new curve.
-
std::shared_ptr<Curve> translated(const glm::dvec3 &offset) const#
Returns the curve moved by an offset.
- Parameters:
offset – The translation.
- Returns:
A new curve.
-
virtual std::string type_name() const = 0#
Returns the curve type name, such as “BSplineCurve”.
- Returns:
The type name.
-
virtual ~Curve() = default#
Protected Functions
-
virtual std::vector<Piece> build_pieces() const = 0#
Splits the curve into pieces (start, end, box, deviation and linear are set).
- Returns:
The pieces, in parameter order.
-
CurveHit closest_on_piece(const Piece &piece, const glm::dvec3 &point) const#
Finds the closest point of one piece.
- Parameters:
piece – The piece to search.
point – The query point.
- Returns:
The closest point of the piece (one of its ends when no interior minimum is found).
-
Curve() = default#
-
void finalize(double start, double end, bool closed)#
Builds the pieces, arc-length table, AABB tree, box and plane.
Each concrete curve calls this once, at the end of its constructor.
- Parameters:
start – The first parameter of the domain.
end – The last parameter of the domain.
closed – Whether the curve ends where it starts.
Protected Static Functions
-
static void check_affine(const glm::dmat4 &matrix, const std::string &name)#
Throws unless the matrix is a finite, invertible affine transform (last row 0, 0, 0, 1).
- Parameters:
matrix – The transform.
name – The curve type, for the message.
-
static glm::dvec3 transform_point(const glm::dmat4 &matrix, const glm::dvec3 &point)#
Applies an affine transform to a point.
- Parameters:
matrix – The transform.
point – The point.
- Returns:
matrix * (point, 1), without the w component.
Private Functions
-
double arc_length(double from, double to) const#
-
int build_bvh(size_t first, size_t count)#
-
size_t piece_index(double t) const#
Private Members
-
bool m_closed = false#
-
double m_end = 0.0#
-
double m_length = 0.0#
-
glm::dvec3 m_maximum = glm::dvec3(0.0)#
-
glm::dvec3 m_minimum = glm::dvec3(0.0)#
-
std::vector<size_t> m_piece_order#
-
std::optional<glm::dvec3> m_plane_normal#
-
double m_start = 0.0#
-
struct BvhNode#
One node of the AABB tree over the pieces.
Public Members
-
size_t count = 0#
Number of pieces covered by a leaf.
-
size_t first = 0#
First entry of m_piece_order covered by a leaf.
-
int left = -1#
Index of the first child, or -1 for a leaf.
-
glm::dvec3 maximum = glm::dvec3(0.0)#
-
glm::dvec3 minimum = glm::dvec3(0.0)#
-
int right = -1#
Index of the second child, or -1 for a leaf.
-
size_t count = 0#
-
struct Piece#
- #include <curve.h>
A parameter interval of the curve with a rigorous bounding box.
Public Members
-
double deviation = 0.0#
Upper bound on the distance from the piece to its chord.
-
double end = 0.0#
Last parameter of the piece.
-
double length = 0.0#
Arc length of the piece.
-
double length_start = 0.0#
Arc length from the curve start to the piece start.
-
bool linear = false#
True when the piece is exactly its chord.
-
glm::dvec3 maximum = glm::dvec3(0.0)#
Box maximum; contains the piece.
-
glm::dvec3 minimum = glm::dvec3(0.0)#
Box minimum; contains the piece.
-
double start = 0.0#
First parameter of the piece.
-
double deviation = 0.0#
-
struct CurveHit#
- #include <curve.h>
The point on a curve closest to a query point.
-
class LineSegment : public Curve#
- #include <line_segment.h>
A straight line segment between two points, with t in [0, 1].
Closest points, lengths and tangents are exact closed forms.
Public Functions
-
virtual glm::dvec3 derivative(double t, int order = 1) const override#
Evaluates a derivative of the curve with respect to t.
- Parameters:
t – The parameter (clamped or wrapped as in point()).
order – 1 or 2. Where the curve has a corner, the derivative of the piece that starts at t is returned (the last piece at the end of the domain).
- Returns:
The derivative vector.
-
inline const glm::dvec3 &end() const#
Returns the point at t = 1.
- Returns:
The end point.
-
LineSegment(const glm::dvec3 &start, const glm::dvec3 &end)#
Constructor.
- Parameters:
start – The point at t = 0.
end – The point at t = 1.
- Throws:
std::runtime_error – if the points are not finite.
-
virtual glm::dvec3 point(double t) const override#
Evaluates the curve.
- Parameters:
t – The parameter. Open curves clamp it to the domain; closed curves wrap it.
- Returns:
The point at t.
-
virtual std::shared_ptr<Curve> reversed() const override#
Returns the same curve traversed from end to start.
- Returns:
A new curve.
-
inline const glm::dvec3 &start() const#
Returns the point at t = 0.
- Returns:
The start point.
-
virtual std::shared_ptr<Curve> transformed(const glm::dmat4 &matrix) const override#
Returns the curve with every point mapped by an affine transform.
The parameterization is kept: the new curve at t is the transform of this curve at t, and the curve keeps its type, so lines stay lines and arcs stay arcs. Lines, polylines, Bezier curves and B-splines accept any affine transform; an ArcCurve (and a curve containing one) needs a similarity, made of rotations, reflections, a uniform scale and a translation.
- Parameters:
matrix – The transform, applied to points as matrix * (x, y, z, 1).
- Throws:
std::runtime_error – if the matrix is not finite and invertible, or an arc gets a transform that is not a similarity.
- Returns:
A new curve.
-
inline virtual std::string type_name() const override#
Returns the curve type name, such as “BSplineCurve”.
- Returns:
The type name.
Protected Functions
-
virtual std::vector<Piece> build_pieces() const override#
Splits the curve into pieces (start, end, box, deviation and linear are set).
- Returns:
The pieces, in parameter order.
-
inline virtual std::vector<glm::dvec3> defining_points() const override#
Returns points whose plane, if any, is the plane of the curve (for example the control points).
- Returns:
The defining points.
-
virtual glm::dvec3 derivative(double t, int order = 1) const override#
-
class PolylineCurve : public Curve#
- #include <polyline_curve.h>
A chain of straight segments through a list of points, open or closed.
The parameter runs over [0, n] for n segments: t = i + s lies on segment i at fraction s. A closed polyline adds the segment from the last point back to the first; a repeated first point at the end of the input is dropped. Closest points, lengths and the bounding box are exact; an AABB tree over the segments keeps closest-point queries logarithmic.
Subclassed by Polyline2
Public Functions
-
virtual glm::dvec3 derivative(double t, int order = 1) const override#
Evaluates a derivative of the curve with respect to t.
- Parameters:
t – The parameter (clamped or wrapped as in point()).
order – 1 or 2. Where the curve has a corner, the derivative of the piece that starts at t is returned (the last piece at the end of the domain).
- Returns:
The derivative vector.
-
virtual glm::dvec3 point(double t) const override#
Evaluates the curve.
- Parameters:
t – The parameter. Open curves clamp it to the domain; closed curves wrap it.
- Returns:
The point at t.
-
PolylineCurve(const std::vector<glm::dvec3> &points, bool closed = false)#
Constructor.
- Parameters:
points – The vertices, at least 2 (at least 3 for a closed polyline).
closed – True to join the last point back to the first.
- Throws:
std::runtime_error – if there are too few points or a point is not finite.
-
virtual std::shared_ptr<Curve> reversed() const override#
Returns the same curve traversed from end to start.
- Returns:
A new curve.
-
size_t segment_count() const#
Returns the number of segments.
- Returns:
The segment count; 0 for an empty polyline.
-
virtual std::shared_ptr<Curve> transformed(const glm::dmat4 &matrix) const override#
Returns the curve with every point mapped by an affine transform.
The parameterization is kept: the new curve at t is the transform of this curve at t, and the curve keeps its type, so lines stay lines and arcs stay arcs. Lines, polylines, Bezier curves and B-splines accept any affine transform; an ArcCurve (and a curve containing one) needs a similarity, made of rotations, reflections, a uniform scale and a translation.
- Parameters:
matrix – The transform, applied to points as matrix * (x, y, z, 1).
- Throws:
std::runtime_error – if the matrix is not finite and invertible, or an arc gets a transform that is not a similarity.
- Returns:
A new curve.
-
inline virtual std::string type_name() const override#
Returns the curve type name, such as “BSplineCurve”.
- Returns:
The type name.
-
inline const std::vector<glm::dvec3> &vertices() const#
Returns the vertices (a closed polyline does not repeat the first one).
- Returns:
The vertices.
Protected Functions
-
virtual std::vector<Piece> build_pieces() const override#
Splits the curve into pieces (start, end, box, deviation and linear are set).
- Returns:
The pieces, in parameter order.
-
inline virtual std::vector<glm::dvec3> defining_points() const override#
Returns points whose plane, if any, is the plane of the curve (for example the control points).
- Returns:
The defining points.
-
void rebuild(const std::vector<glm::dvec3> &points, bool closed)#
Replaces the vertices and rebuilds the curve.
Fewer than 2 points leave it empty.
- Parameters:
points – The new vertices.
closed – True to join the last point back to the first.
- Throws:
std::runtime_error – if a point is not finite.
Protected Attributes
-
std::vector<glm::dvec3> m_points#
The vertices.
Private Functions
-
size_t segment_index(double t) const#
Returns the segment holding parameter t (already normalized).
-
virtual glm::dvec3 derivative(double t, int order = 1) const override#
-
class ArcCurve : public Curve#
- #include <arc_curve.h>
A circular arc, or a full circle, with t in [0, 1].
The arc lies in the plane through center with the given normal. Angles are measured in that plane from a reference direction: world +X projected into the plane (world +Y when the normal is along X), turning counter-clockwise about the normal. So with the default normal +Z, angles are the usual polar angles in the XY plane. The arc runs from start_degrees to end_degrees; a negative sweep runs clockwise, and a sweep of 360 degrees (either sign) is a closed circle. Closest points, lengths and bounding boxes are exact.
Public Functions
-
ArcCurve(const glm::dvec3 ¢er, double radius, double start_degrees, double end_degrees, const glm::dvec3 &normal = glm::dvec3(0.0, 0.0, 1.0))#
Constructor.
- Parameters:
center – The centre of the circle.
radius – The radius; must be positive.
start_degrees – The angle at t = 0.
end_degrees – The angle at t = 1. |end - start| must be in (0, 360].
normal – The plane normal; need not be unit length.
- Throws:
std::runtime_error – if the radius, sweep or normal is invalid.
-
inline const glm::dvec3 ¢er() const#
Returns the centre.
- Returns:
The centre of the circle.
-
virtual CurveHit closest_point(const glm::dvec3 &point) const override#
Finds the point of the curve closest to a point.
Exact: the query is projected into the plane and its angle clamped to the arc.
- Parameters:
point – The query point.
- Throws:
std::runtime_error – if the curve is empty.
- Returns:
The parameter, the closest point and the distance.
-
virtual glm::dvec3 derivative(double t, int order = 1) const override#
Evaluates a derivative of the curve with respect to t.
- Parameters:
t – The parameter (clamped or wrapped as in point()).
order – 1 or 2. Where the curve has a corner, the derivative of the piece that starts at t is returned (the last piece at the end of the domain).
- Returns:
The derivative vector.
-
inline double end_degrees() const#
Returns the angle at t = 1, in degrees.
- Returns:
The end angle.
-
inline const glm::dvec3 &normal() const#
Returns the unit plane normal.
- Returns:
The normal.
-
virtual glm::dvec3 point(double t) const override#
Evaluates the curve.
- Parameters:
t – The parameter. Open curves clamp it to the domain; closed curves wrap it.
- Returns:
The point at t.
-
inline double radius() const#
Returns the radius.
- Returns:
The radius.
-
inline const glm::dvec3 &reference() const#
Returns the unit reference direction (angle 0) in the plane.
- Returns:
The reference direction.
-
virtual std::shared_ptr<Curve> reversed() const override#
Returns the same curve traversed from end to start.
- Returns:
A new curve.
-
inline double start_degrees() const#
Returns the angle at t = 0, in degrees.
- Returns:
The start angle.
-
virtual std::shared_ptr<Curve> transformed(const glm::dmat4 &matrix) const override#
Returns the curve with every point mapped by an affine transform.
The parameterization is kept: the new curve at t is the transform of this curve at t, and the curve keeps its type, so lines stay lines and arcs stay arcs. Lines, polylines, Bezier curves and B-splines accept any affine transform; an ArcCurve (and a curve containing one) needs a similarity, made of rotations, reflections, a uniform scale and a translation.
- Parameters:
matrix – The transform, applied to points as matrix * (x, y, z, 1).
- Throws:
std::runtime_error – if the matrix is not finite and invertible, or an arc gets a transform that is not a similarity.
- Returns:
A new curve.
-
inline virtual std::string type_name() const override#
Returns the curve type name, such as “BSplineCurve”.
- Returns:
The type name.
Public Static Functions
-
static std::shared_ptr<ArcCurve> circle(const glm::dvec3 ¢er, double radius, const glm::dvec3 &normal = glm::dvec3(0.0, 0.0, 1.0))#
Creates a closed circle starting at angle 0.
- Parameters:
center – The centre.
radius – The radius; must be positive.
normal – The plane normal.
- Throws:
std::runtime_error – if the radius or normal is invalid.
- Returns:
The circle.
-
static std::shared_ptr<ArcCurve> from_ends(const glm::dvec3 &start, const glm::dvec3 &end, double radius, bool counter_clockwise = true, bool large = false, const glm::dvec3 &normal = glm::dvec3(0.0, 0.0, 1.0))#
The arc of a given radius between two points.
Of the four arcs of that radius joining the points,
counter_clockwise(about the normal) andlarge(more than 180 degrees) pick one.- Parameters:
start – The first point (t = 0).
end – The last point (t = 1).
radius – The radius; at least half the distance between the points.
counter_clockwise – True to turn counter-clockwise about the normal from start to end.
large – True for the arc longer than a half circle.
normal – The plane normal; the points must lie in one plane with it.
- Throws:
std::runtime_error – if the points coincide, the radius is too small, or the chord is not perpendicular to the normal.
- Returns:
The arc.
-
static std::shared_ptr<ArcCurve> from_tangent(const glm::dvec3 &start, const glm::dvec3 &direction, const glm::dvec3 &end)#
The arc that leaves
startalongdirectionand ends atend.Its tangent at the start is
direction, so it continues a curve smoothly. It turns towardend, in the plane ofdirectionand the chord.- Parameters:
start – The first point (t = 0).
direction – The tangent at the start; non-zero.
end – The last point (t = 1).
- Throws:
std::runtime_error – if
endlies on the line throughstartalongdirection.- Returns:
The arc.
-
static std::shared_ptr<ArcCurve> through(const glm::dvec3 &start, const glm::dvec3 &middle, const glm::dvec3 &end)#
The arc from
startthroughmiddletoend.The arc lies in the plane of the three points. Its normal points to the side with a positive z component (for points in the XY plane, +Z), so a clockwise arc there has a negative sweep.
- Parameters:
start – The first point (t = 0).
middle – A point the arc passes through between the ends.
end – The last point (t = 1).
- Throws:
std::runtime_error – if the points coincide or are collinear.
- Returns:
The arc.
Protected Functions
-
virtual std::vector<Piece> build_pieces() const override#
Splits the curve into pieces (start, end, box, deviation and linear are set).
- Returns:
The pieces, in parameter order.
-
virtual std::vector<glm::dvec3> defining_points() const override#
Returns points whose plane, if any, is the plane of the curve (for example the control points).
- Returns:
The defining points.
Private Members
-
glm::dvec3 m_center#
-
double m_end_degrees#
-
glm::dvec3 m_normal#
-
double m_radius#
-
double m_start_angle#
Start angle in radians.
-
double m_start_degrees#
-
double m_sweep#
Signed sweep in radians.
-
glm::dvec3 m_x#
In-plane direction at angle 0.
-
glm::dvec3 m_y#
In-plane direction at angle 90 (normal x m_x).
-
ArcCurve(const glm::dvec3 ¢er, double radius, double start_degrees, double end_degrees, const glm::dvec3 &normal = glm::dvec3(0.0, 0.0, 1.0))#
Functions
-
double bezier_flatness(const std::vector<glm::dvec3> &control_points)#
Returns the default flatness tolerance for control points: 1e-5 times their box diagonal.
- Parameters:
control_points – The control points.
- Returns:
The tolerance, at least 1e-12.
-
std::vector<Curve::Piece> bezier_pieces(const std::vector<BezierSegment> &segments, double tolerance)#
Splits Bezier segments into curve pieces whose control polygons are flat.
Each segment is halved until its control polygon lies within tolerance of its chord and turns by at most 45 degrees. A piece’s box is its control-point box (rigorous by the convex-hull property) and its deviation is the control polygon’s chord deviation.
- Parameters:
segments – The segments, in parameter order.
tolerance – The flatness tolerance.
- Returns:
The pieces, in parameter order.
-
class BezierCurve : public Curve#
- #include <bezier_curve.h>
A polynomial Bezier curve of any degree (cubic is the usual case), with t in [0, 1].
The curve is closed when its first and last control points coincide. Closest points use the shared piece search (see Curve), with pieces flat to 1e-5 of the control-point box diagonal.
Public Functions
-
explicit BezierCurve(const std::vector<glm::dvec3> &control_points)#
Constructor.
- Parameters:
control_points – The control points, at least 2. The degree is their count minus 1.
- Throws:
std::runtime_error – if there are fewer than 2 points or a point is not finite.
-
inline const std::vector<glm::dvec3> &control_points() const#
Returns the control points.
- Returns:
The control points.
-
inline int degree() const#
Returns the degree.
- Returns:
The number of control points minus 1.
-
virtual glm::dvec3 derivative(double t, int order = 1) const override#
Evaluates a derivative of the curve with respect to t.
- Parameters:
t – The parameter (clamped or wrapped as in point()).
order – 1 or 2. Where the curve has a corner, the derivative of the piece that starts at t is returned (the last piece at the end of the domain).
- Returns:
The derivative vector.
-
virtual glm::dvec3 point(double t) const override#
Evaluates the curve.
- Parameters:
t – The parameter. Open curves clamp it to the domain; closed curves wrap it.
- Returns:
The point at t.
-
virtual std::shared_ptr<Curve> reversed() const override#
Returns the same curve traversed from end to start.
- Returns:
A new curve.
-
virtual std::shared_ptr<Curve> transformed(const glm::dmat4 &matrix) const override#
Returns the curve with every point mapped by an affine transform.
The parameterization is kept: the new curve at t is the transform of this curve at t, and the curve keeps its type, so lines stay lines and arcs stay arcs. Lines, polylines, Bezier curves and B-splines accept any affine transform; an ArcCurve (and a curve containing one) needs a similarity, made of rotations, reflections, a uniform scale and a translation.
- Parameters:
matrix – The transform, applied to points as matrix * (x, y, z, 1).
- Throws:
std::runtime_error – if the matrix is not finite and invertible, or an arc gets a transform that is not a similarity.
- Returns:
A new curve.
-
inline virtual std::string type_name() const override#
Returns the curve type name, such as “BSplineCurve”.
- Returns:
The type name.
Protected Functions
-
virtual std::vector<Piece> build_pieces() const override#
Splits the curve into pieces (start, end, box, deviation and linear are set).
- Returns:
The pieces, in parameter order.
-
inline virtual std::vector<glm::dvec3> defining_points() const override#
Returns points whose plane, if any, is the plane of the curve (for example the control points).
- Returns:
The defining points.
Private Members
-
BezierSegment m_segment#
-
explicit BezierCurve(const std::vector<glm::dvec3> &control_points)#
-
struct BezierSegment#
- #include <bezier_curve.h>
One polynomial Bezier segment mapped onto a global parameter interval.
Shared by BezierCurve and BSplineCurve (which stores its knot spans in this form). The control points of the first and second derivatives (hodographs) are kept so evaluation needs no allocation. Derivatives returned here are with respect to the global parameter.
Public Functions
-
BezierSegment(const std::vector<glm::dvec3> &control_points, double start, double end)#
Builds the segment and its hodographs.
- Parameters:
control_points – The control points, at least 2.
start – The global parameter at s = 0.
end – The global parameter at s = 1.
-
double chord_deviation() const#
Returns the largest distance from a control point to the chord.
By the convex-hull property this bounds the distance from the curve to the chord.
- Returns:
The chord deviation.
-
double control_polygon_turning() const#
Returns the total turning angle of the control polygon, in radians.
- Returns:
The turning angle.
-
inline int degree() const#
Returns the degree.
- Returns:
The number of control points minus 1.
-
glm::dvec3 derivative(double t, int order) const#
Evaluates a derivative with respect to the global parameter.
- Parameters:
t – The global parameter, in [start, end].
order – 1 or 2.
- Returns:
The derivative vector.
-
glm::dvec3 point(double t) const#
Evaluates the segment at a global parameter.
- Parameters:
t – The global parameter, in [start, end].
- Returns:
The point.
-
std::pair<BezierSegment, BezierSegment> split(double s) const#
Splits the segment at a local fraction s in (0, 1) by de Casteljau.
- Parameters:
s – The local fraction at which to split.
- Returns:
The two halves, covering [start, middle] and [middle, end] of the global parameter.
Public Members
-
double end = 1.0#
Global parameter at the last control point.
-
std::vector<glm::dvec3> first#
Control points of d/ds (degree).
-
std::vector<glm::dvec3> points#
Control points (degree + 1).
-
std::vector<glm::dvec3> second#
Control points of d2/ds2 (degree - 1).
-
double start = 0.0#
Global parameter at the first control point.
-
BezierSegment(const std::vector<glm::dvec3> &control_points, double start, double end)#
-
class BSplineCurve : public Curve#
- #include <bspline_curve.h>
A non-rational B-spline curve of any degree, open (clamped) or closed (periodic).
Open curves default to a clamped, uniform knot vector on [0, 1], so the curve starts and ends at the first and last control points. Closed curves are periodic: the first degree control points are reused after the last one, with uniform knots on [0, 1] by default. Custom knots may be given for either kind; their domain is [knots[degree], knots[count]], where count is the number of (wrapped, for closed curves) control points.
At construction every knot span is converted to a BezierSegment (Bezier extraction), so evaluation is de Casteljau on one segment and closest points use the shared piece search of Curve, with pieces flat to 1e-5 of the control-point box diagonal.
Public Functions
-
inline const std::vector<BezierSegment> &bezier_segments() const#
Returns the Bezier form of the curve, one segment per non-empty knot span.
- Returns:
The segments, in parameter order.
-
BSplineCurve(const std::vector<glm::dvec3> &control_points, int degree = 3, const std::vector<double> &knots = {}, bool closed = false)#
Constructor.
- Parameters:
control_points – The control points. Open curves need at least degree + 1; closed curves need at least max(3, degree + 1) and must not repeat the first point at the end.
degree – The polynomial degree, at least 1.
knots – Optional knots. Open: control count + degree + 1 values. Closed: control count + 2 * degree + 1 values that repeat with the period of the domain.
closed – True for a periodic curve.
- Throws:
std::runtime_error – on invalid input.
-
inline const std::vector<glm::dvec3> &control_points() const#
Returns the control points as given (without the periodic wrap).
- Returns:
The control points.
-
inline int degree() const#
Returns the degree.
- Returns:
The degree.
-
virtual glm::dvec3 derivative(double t, int order = 1) const override#
Evaluates a derivative of the curve with respect to t.
- Parameters:
t – The parameter (clamped or wrapped as in point()).
order – 1 or 2. Where the curve has a corner, the derivative of the piece that starts at t is returned (the last piece at the end of the domain).
- Returns:
The derivative vector.
-
inline const std::vector<double> &knots() const#
Returns the knot vector in use.
- Returns:
The knots.
-
virtual glm::dvec3 point(double t) const override#
Evaluates the curve.
- Parameters:
t – The parameter. Open curves clamp it to the domain; closed curves wrap it.
- Returns:
The point at t.
-
virtual std::shared_ptr<Curve> reversed() const override#
Returns the same curve traversed from end to start.
- Returns:
A new curve.
-
virtual std::shared_ptr<Curve> transformed(const glm::dmat4 &matrix) const override#
Returns the curve with every point mapped by an affine transform.
The parameterization is kept: the new curve at t is the transform of this curve at t, and the curve keeps its type, so lines stay lines and arcs stay arcs. Lines, polylines, Bezier curves and B-splines accept any affine transform; an ArcCurve (and a curve containing one) needs a similarity, made of rotations, reflections, a uniform scale and a translation.
- Parameters:
matrix – The transform, applied to points as matrix * (x, y, z, 1).
- Throws:
std::runtime_error – if the matrix is not finite and invertible, or an arc gets a transform that is not a similarity.
- Returns:
A new curve.
-
inline virtual std::string type_name() const override#
Returns the curve type name, such as “BSplineCurve”.
- Returns:
The type name.
Public Static Functions
-
static std::shared_ptr<BSplineCurve> interpolate(const std::vector<glm::dvec3> &points, int degree = 3, bool closed = false)#
Creates a B-spline passing through the given points.
Parameters follow chord length. Open curves use averaged clamped knots and start and end at the first and last point. Closed curves are periodic, with knots at the chord-length parameters; for odd degrees the curve starts at the first point. The degree is lowered when there are too few points for it.
- Parameters:
points – The points to pass through; consecutive points must differ. A closed curve needs at least 3 points and may repeat the first at the end.
degree – The degree, at least 1.
closed – True for a closed, periodic curve.
- Throws:
std::runtime_error – on invalid input.
- Returns:
The interpolating curve.
Protected Functions
-
virtual std::vector<Piece> build_pieces() const override#
Splits the curve into pieces (start, end, box, deviation and linear are set).
- Returns:
The pieces, in parameter order.
-
inline virtual std::vector<glm::dvec3> defining_points() const override#
Returns points whose plane, if any, is the plane of the curve (for example the control points).
- Returns:
The defining points.
Private Functions
-
const BezierSegment &segment(double t) const#
Returns the segment holding parameter t (already normalized).
Private Members
-
std::vector<glm::dvec3> m_control_points#
-
int m_degree#
-
std::vector<double> m_knots#
-
std::vector<BezierSegment> m_segments#
-
inline const std::vector<BezierSegment> &bezier_segments() const#
-
class CompositeCurve : public Curve#
- #include <composite_curve.h>
A chain of curves joined end to start, with t in [0, n] for n curves.
Curve i covers [i, i + 1], mapped linearly onto its own domain. Each curve must start where the previous one ends, within 1e-6 times the largest bounding-box diagonal of the member curves. The chain is closed when the last curve ends where the first one starts (same tolerance), or, for a single curve, when that curve is closed. The chain may have corners where its curves meet. Closest points and lengths come from the pieces of the member curves.
Public Functions
Constructor.
- Parameters:
curves – The curves in order, at least one.
- Throws:
std::runtime_error – if the list is empty, holds a null curve, or a curve does not start where the previous one ends.
-
inline const std::vector<std::shared_ptr<const Curve>> &curves() const#
Returns the member curves.
- Returns:
The curves, in order.
-
virtual glm::dvec3 derivative(double t, int order = 1) const override#
Evaluates a derivative of the curve with respect to t.
- Parameters:
t – The parameter (clamped or wrapped as in point()).
order – 1 or 2. Where the curve has a corner, the derivative of the piece that starts at t is returned (the last piece at the end of the domain).
- Returns:
The derivative vector.
-
std::pair<size_t, double> local_parameter(double t) const#
Maps a chain parameter to (curve index, parameter of that curve).
- Parameters:
t – The chain parameter (clamped or wrapped as in point()).
- Returns:
The index of the member curve and the parameter in its own domain.
-
virtual glm::dvec3 point(double t) const override#
Evaluates the curve.
- Parameters:
t – The parameter. Open curves clamp it to the domain; closed curves wrap it.
- Returns:
The point at t.
-
virtual std::shared_ptr<Curve> reversed() const override#
Returns the same curve traversed from end to start.
- Returns:
A new curve.
-
virtual std::shared_ptr<Curve> transformed(const glm::dmat4 &matrix) const override#
Returns the curve with every point mapped by an affine transform.
The parameterization is kept: the new curve at t is the transform of this curve at t, and the curve keeps its type, so lines stay lines and arcs stay arcs. Lines, polylines, Bezier curves and B-splines accept any affine transform; an ArcCurve (and a curve containing one) needs a similarity, made of rotations, reflections, a uniform scale and a translation.
- Parameters:
matrix – The transform, applied to points as matrix * (x, y, z, 1).
- Throws:
std::runtime_error – if the matrix is not finite and invertible, or an arc gets a transform that is not a similarity.
- Returns:
A new curve.
-
inline virtual std::string type_name() const override#
Returns the curve type name, such as “BSplineCurve”.
- Returns:
The type name.
Protected Functions
-
virtual std::vector<Piece> build_pieces() const override#
Splits the curve into pieces (start, end, box, deviation and linear are set).
- Returns:
The pieces, in parameter order.
-
virtual std::vector<glm::dvec3> defining_points() const override#
Returns points whose plane, if any, is the plane of the curve (for example the control points).
- Returns:
The defining points.
-
class TrimmedCurve : public Curve#
- #include <trimmed_curve.h>
The part of another curve between two of its parameters.
The parameter is the base curve’s own parameter, restricted to [start, end]. On a closed base curve the interval may run past the base’s end and wrap around its seam (end up to start + one period). Profile booleans use trimmed curves to keep the exact pieces of the input curves in their results.
Public Functions
-
inline const std::shared_ptr<const Curve> &base() const#
Returns the base curve.
- Returns:
The untrimmed curve.
-
inline virtual std::vector<glm::dvec3> defining_points() const override#
Returns points whose plane, if any, is the plane of the curve (for example the control points).
- Returns:
The defining points.
-
virtual glm::dvec3 derivative(double t, int order = 1) const override#
Evaluates a derivative of the curve with respect to t.
- Parameters:
t – The parameter (clamped or wrapped as in point()).
order – 1 or 2. Where the curve has a corner, the derivative of the piece that starts at t is returned (the last piece at the end of the domain).
- Returns:
The derivative vector.
-
virtual glm::dvec3 point(double t) const override#
Evaluates the curve.
- Parameters:
t – The parameter. Open curves clamp it to the domain; closed curves wrap it.
- Returns:
The point at t.
-
virtual std::shared_ptr<Curve> reversed() const override#
Returns the same curve traversed from end to start.
- Returns:
A new curve.
-
virtual std::shared_ptr<Curve> transformed(const glm::dmat4 &matrix) const override#
Returns the curve with every point mapped by an affine transform.
The parameterization is kept: the new curve at t is the transform of this curve at t, and the curve keeps its type, so lines stay lines and arcs stay arcs. Lines, polylines, Bezier curves and B-splines accept any affine transform; an ArcCurve (and a curve containing one) needs a similarity, made of rotations, reflections, a uniform scale and a translation.
- Parameters:
matrix – The transform, applied to points as matrix * (x, y, z, 1).
- Throws:
std::runtime_error – if the matrix is not finite and invertible, or an arc gets a transform that is not a similarity.
- Returns:
A new curve.
Constructor.
- Parameters:
base – The curve to trim.
start – The first parameter, in the base curve’s domain.
end – The last parameter; greater than start. Past the base’s end only for closed bases, and by less than one period.
- Throws:
std::runtime_error – if the base is null or the interval is invalid.
-
inline virtual std::string type_name() const override#
Returns the curve type name, such as “BSplineCurve”.
- Returns:
The type name.
Protected Functions
-
virtual std::vector<Piece> build_pieces() const override#
Splits the curve into pieces (start, end, box, deviation and linear are set).
- Returns:
The pieces, in parameter order.
-
inline const std::shared_ptr<const Curve> &base() const#
-
struct CurveFrame#
- #include <curve_frames.h>
An orthonormal frame on a curve: tangent, normal and binormal with normal x binormal = tangent.
Public Members
-
glm::dvec3 binormal = glm::dvec3(0.0, 1.0, 0.0)#
Unit binormal (profile v axis in a sweep).
-
glm::dvec3 normal = glm::dvec3(1.0, 0.0, 0.0)#
Unit normal (profile u axis in a sweep).
-
glm::dvec3 origin = glm::dvec3(0.0)#
The curve point.
-
glm::dvec3 tangent = glm::dvec3(0.0, 0.0, 1.0)#
Unit tangent.
-
glm::dvec3 binormal = glm::dvec3(0.0, 1.0, 0.0)#
-
class CurveFrames#
- #include <curve_frames.h>
Rotation-minimizing frames along a curve.
The frames turn as little as possible about the tangent, so a profile carried along the curve does not twist on its own. They are computed with the double-reflection method (Wang, Juttler, Zheng and Liu, 2008) on a table of points evenly spaced in arc length, and evaluated at any parameter with one more reflection from the table entry before it, so they vary continuously.
Initial frame: the binormal starts along
upmade perpendicular to the start tangent. Withoutup, a planar curve uses its plane normal (the frames then stay in the plane) and other curves the world axis least aligned with the start tangent.Closed curves: carrying the frame once around generally returns it rotated by an angle (the holonomy). That angle is spread evenly in arc length, so the frames match at the seam with the smallest constant twist rate.
Immutable after construction; frame() is thread-safe.
Public Functions
-
inline const std::shared_ptr<const Curve> &curve() const#
Returns the curve.
- Returns:
The curve the frames follow.
Constructor.
- Parameters:
curve – The curve; must have positive length.
up – Optional direction for the initial binormal; must not be parallel to the start tangent.
samples – Table size; 0 picks max(256, 8 x the number of curve pieces), at most 50000.
- Throws:
std::runtime_error – if the curve is null or has zero length, or
upis parallel to the start tangent.
-
CurveFrame frame(double t) const#
Returns the frame at parameter t (clamped or wrapped as by the curve).
- Parameters:
t – The curve parameter.
- Returns:
The frame.
-
double holonomy_degrees() const#
Returns the rotation spread along a closed curve to close the frames, in degrees (0 when open).
- Returns:
The holonomy angle in degrees.
-
inline const std::shared_ptr<const Curve> &curve() const#
Profiles#
-
class Profile#
- #include <profile.h>
An immutable closed region of the XY plane bounded by closed curves, possibly with holes.
A profile is the cross-section that Extrude, Revolve and Sweep turn into solids. Its boundary is a set of closed, planar loops at z = 0 (any Curve type); loops must not cross themselves or each other. Nesting decides what is inside: at construction every loop that lies inside an even number of other loops is an outer boundary and is turned counter-clockwise, and every other loop is a hole and is turned clockwise.
Signed distance is computed from the curves themselves: the distance to the nearest loop (each loop answers from its own exact closest-point search) with the sign from the side of the nearest boundary point, using the bisector of the two tangents at a corner. It is exact for every profile, to the closest-point accuracy of its curves (see Curve).
Operations:
Booleans (Union, Intersection, Difference) run on tessellations with Clipper2 for robust topology, then map every result edge back to the input curve it came from, so the result loops are pieces of the input curves (TrimmedCurve) joined at intersection points refined on the curves. Loops that cannot be recovered fall back to the polygon, which is within the tolerance.
offset() runs Clipper2 on the tessellation. A round offset of a profile made only of straight edges and circular arcs is also built exactly (edges moved along their normals, arcs made concentric, convex corners joined by arcs) and returned when it agrees with Clipper2’s result (same number of loops, same area within the tolerance). Otherwise the result is Clipper2’s polygon, within the tolerance.
fillet() rounds the corners between straight pieces with exact tangent arcs.
The default tolerance is min(0.001, 1e-4 x the profile size), in model units (mm). Immutable after construction: queries are thread-safe and profiles are shared between nodes.
Public Types
Public Functions
-
double area() const#
Returns the enclosed area (holes subtracted).
- Returns:
The area, by Gauss-Legendre quadrature of Green’s theorem over the loops.
-
inline std::pair<glm::dvec2, glm::dvec2> bounding_box() const#
Returns the box containing the profile.
- Returns:
The pair (minimum, maximum); both zero for the empty profile.
-
std::shared_ptr<Profile> chamfer(double distance, const std::vector<glm::dvec2> &at = {}) const#
The profile with corners cut by straight edges.
Each chosen corner between straight edges and circular arcs is cut by the edge between the points
distancefrom the corner along each side (arc length on arcs). A distance too large for the adjacent pieces is reduced at that corner, as for fillet().- Parameters:
distance – The chamfer distance along each side, positive.
at – The corners to cut (see fillet()); empty cuts every corner.
- Throws:
std::runtime_error – if the distance is not positive, or a point in
atis not near a corner.- Returns:
The chamfered profile.
-
ProfileHit closest_point(const glm::dvec2 &point) const#
The nearest boundary point, with signed distance.
- Parameters:
point – The query point.
- Throws:
std::runtime_error – for the empty profile.
- Returns:
The loop, curve parameter, point and signed distance.
-
inline bool contains(const glm::dvec2 &point) const#
Returns true when the point is inside or on the boundary.
- Parameters:
point – The query point.
- Returns:
Whether signed_distance(point) <= 0.
-
std::vector<glm::dvec2> corners(double min_angle_degrees = 0.0) const#
Returns the corners of the profile: the points of its loops where the tangent jumps.
In loop order, starting from each loop’s first corner. Use them to pick corners for fillet() and chamfer() by position. A profile that is a polygon approximation of curves (an offset can be) has a slight corner at every vertex;
min_angle_degreesskips those.- Parameters:
min_angle_degrees – Only corners where the tangent turns by more than this count.
- Returns:
The corner points.
-
double default_tolerance() const#
Returns the default operation tolerance: min(0.001, 1e-4 x size()).
- Returns:
The tolerance; 0.001 for the empty profile.
-
inline bool empty() const#
Returns true for the empty profile.
- Returns:
Whether the profile has no loops.
-
std::shared_ptr<Profile> fillet(double radius, const std::vector<glm::dvec2> &at = {}) const#
The profile with corners rounded by tangent arcs.
Rounds corners between straight edges and circular arcs, convex and concave, with the exact arc of the given radius tangent to both sides. A radius too large for the adjacent pieces is reduced at that corner so neighbouring fillets do not overlap. Corners that involve another curve (a Bezier curve or B-spline) are left as they are.
- Parameters:
radius – The fillet radius, positive.
at – The corners to round, each given by a point near it (see corners()); empty rounds every corner. Each point picks the nearest corner.
- Throws:
std::runtime_error – if the radius is not positive, or a point in
atis not near a corner (farther than 10% of the profile size).- Returns:
The filleted profile.
-
inline bool is_hole(size_t i) const#
Returns true when loop i is a hole.
- Parameters:
i – The loop index.
- Throws:
std::out_of_range – if i is not a loop index.
- Returns:
Whether loop i is a hole.
-
inline const std::vector<std::shared_ptr<const Curve>> &loops() const#
Returns the boundary loops, outer loops counter-clockwise and holes clockwise.
- Returns:
The loops.
-
double max_radius() const#
Returns an upper bound on the distance from the origin to any point of the profile.
- Returns:
The distance from the origin to the farthest bounding-box corner.
-
std::shared_ptr<Profile> mirrored(const glm::dvec2 &point = glm::dvec2(0.0), const glm::dvec2 &direction = glm::dvec2(0.0, 1.0)) const#
The profile reflected across a line.
- Parameters:
point – A point on the mirror line.
direction – The direction of the mirror line; non-zero. (0, 1) mirrors left to right.
- Throws:
std::runtime_error – if the direction is zero.
- Returns:
The mirrored profile.
-
std::shared_ptr<Profile> offset(double distance, Join join = Join::round, double tolerance = 0.0) const#
The profile grown (positive distance) or shrunk (negative distance).
Round offsets of profiles made of straight edges and arcs are exact; other offsets are polygons within the tolerance (see the class details).
- Parameters:
distance – The offset distance; finite.
join – How convex corners are joined when growing (concave ones when shrinking).
tolerance – Tessellation tolerance; 0 uses the default.
- Throws:
std::runtime_error – if the distance is not finite.
- Returns:
The offset profile (a copy when the distance is 0).
-
explicit Profile(const Polygon2 &polygon)#
Constructs a profile from a Polygon2 and its holes.
The outline and each hole with at least 3 points become closed PolylineCurves.
- Parameters:
polygon – The polygon.
Constructs a profile from closed planar loops at z = 0.
- Parameters:
loops – The boundary loops; each must be closed and lie in the XY plane. An empty list gives the empty profile.
- Throws:
std::runtime_error – if a loop is null, open, out of the XY plane, or has zero length, or if a loop crosses itself or another loop (touching at a point is allowed).
-
std::shared_ptr<Profile> rotated(double degrees, const glm::dvec2 ¢er = glm::dvec2(0.0)) const#
The profile turned counter-clockwise about a centre.
- Parameters:
degrees – The angle.
center – The centre of rotation.
- Returns:
The turned profile.
-
std::shared_ptr<Profile> round_concave(double radius) const#
Rounds every concave corner, of any curves, by growing and reshrinking the profile.
offset(radius) then offset(-radius). Gaps narrower than 2 * radius close. Exact when both offsets are (see offset()); otherwise within the offset tolerance.
- Parameters:
radius – The rounding radius, positive.
- Throws:
std::runtime_error – if the radius is not positive.
- Returns:
The rounded profile.
-
std::shared_ptr<Profile> round_convex(double radius) const#
Rounds every convex corner, of any curves, by shrinking and regrowing the profile.
offset(-radius) then offset(radius). Features thinner than 2 * radius disappear. Exact when both offsets are (see offset()); otherwise within the offset tolerance.
- Parameters:
radius – The rounding radius, positive.
- Throws:
std::runtime_error – if the radius is not positive.
- Returns:
The rounded profile.
-
std::shared_ptr<Profile> scaled(double factor, const glm::dvec2 ¢er = glm::dvec2(0.0)) const#
The profile scaled uniformly about a centre.
- Parameters:
factor – The scale factor; positive.
center – The fixed point.
- Throws:
std::runtime_error – if the factor is not positive.
- Returns:
The scaled profile.
-
double signed_distance(const glm::dvec2 &point) const#
Signed distance to the boundary: negative inside, exact (see the class details).
- Parameters:
point – The query point.
- Returns:
The signed distance; +infinity for the empty profile.
-
double size() const#
Returns the diagonal of the bounding box.
- Returns:
The diagonal length; 0 for the empty profile.
-
std::vector<std::vector<glm::dvec2>> tessellate(double tolerance = 0.0) const#
Returns each loop as a polygon within
tolerance(0 uses the default), without repeating the first point.- Parameters:
tolerance – The largest distance between the polygons and the curves; 0 uses the default.
- Returns:
One point list per loop, in the order of loops().
-
std::vector<Polygon2> to_polygons(double tolerance = 0.0) const#
Returns the profile as Polygon2 outlines, each with its holes.
Each hole goes to the smallest outline that contains it.
- Parameters:
tolerance – Tessellation tolerance; 0 uses the default.
- Returns:
The outlines.
-
std::shared_ptr<Profile> transformed(const glm::dmat4 &matrix) const#
The profile with every loop mapped by a transform.
The transform must keep the XY plane and, for profiles with arcs, be a similarity (see Curve::transformed()). translated(), rotated(), scaled() and mirrored() build it.
- Parameters:
matrix – The transform.
- Throws:
std::runtime_error – if a loop cannot take the transform.
- Returns:
The transformed profile.
Public Static Functions
-
static std::shared_ptr<Profile> circle(double radius, const glm::dvec2 ¢er = glm::dvec2(0.0))#
A circle.
- Parameters:
radius – The radius; positive.
center – The centre.
- Throws:
std::runtime_error – if the radius is not positive.
- Returns:
The profile, bounded by one ArcCurve.
The cross-section of a node at height z, traced with marching squares.
A clone of the node is prepared with the cell size as voxel size. The loops are polylines with vertices on the node’s zero level, accurate to the cell size.
- Parameters:
node – The node.
z – The height of the section.
cell_size – The marching-squares cell size; positive.
- Throws:
std::runtime_error – if the cell size is not positive.
- Returns:
The profile; empty when the plane misses the node.
The part of a that is not in b.
- Parameters:
a – The profile to cut from.
b – The profile to remove.
tolerance – Tessellation tolerance for the topology; 0 uses the smallest default tolerance of the inputs.
- Throws:
std::runtime_error – if a profile is null.
- Returns:
The difference.
Builds a profile from loose curves by chaining them end to end into closed loops.
Closed curves are loops on their own. Open curves are joined where an end of one lies within
toleranceof an end of another (either may be reversed); a small gap is bridged with a straight segment. Where more than two ends meet, the nearest end is taken. This is how drawings imported from other tools, whose pieces come in any order and direction, become profiles.- Parameters:
curves – The curves, in the XY plane, in any order and direction.
tolerance – The largest gap to close; 0 uses 1e-6 of the curves’ overall size.
- Throws:
std::runtime_error – if a curve is null or out of the XY plane, or a chain has a loose end.
- Returns:
The profile.
The intersection of two profiles.
- Parameters:
a – The first profile.
b – The second profile.
tolerance – Tessellation tolerance for the topology; 0 uses the smallest default tolerance of the inputs.
- Throws:
std::runtime_error – if a profile is null.
- Returns:
The intersection.
-
static std::shared_ptr<Profile> polygon(const std::vector<glm::dvec2> &points)#
A simple polygon through the given points (either winding; not repeating the first).
- Parameters:
points – The vertices, at least 3.
- Throws:
std::runtime_error – if there are fewer than 3 distinct points.
- Returns:
The profile, bounded by a closed PolylineCurve.
-
static std::shared_ptr<Profile> rectangle(double width, double height, const glm::dvec2 ¢er = glm::dvec2(0.0))#
An axis-aligned rectangle.
- Parameters:
width – Size along x; positive.
height – Size along y; positive.
center – The centre.
- Throws:
std::runtime_error – if a size is not positive.
- Returns:
The profile, bounded by a closed PolylineCurve.
-
static std::shared_ptr<Profile> regular_polygon(int sides, double radius, const glm::dvec2 ¢er = glm::dvec2(0.0), double rotation_degrees = 0.0)#
A regular polygon with
sidescorners on a circle ofradius(the circumradius).- Parameters:
sides – Number of corners; at least 3.
radius – The circumradius.
center – The centre.
rotation_degrees – Angle of the first corner, counter-clockwise from +X.
- Throws:
std::runtime_error – if there are fewer than 3 sides or the radius is not positive.
- Returns:
The profile.
-
static std::shared_ptr<Profile> rounded_rectangle(double width, double height, double radius, const glm::dvec2 ¢er = glm::dvec2(0.0))#
An axis-aligned rectangle with corners rounded to
radius(clamped to half the smaller side).A radius of 0 gives a plain rectangle.
- Parameters:
width – Size along x; positive.
height – Size along y; positive.
radius – The corner radius; not negative.
center – The centre.
- Throws:
std::runtime_error – if a size is not positive or the radius is negative.
- Returns:
The profile, bounded by a CompositeCurve of line segments and arcs.
-
static std::shared_ptr<Profile> slot(double length, double width, const glm::dvec2 ¢er = glm::dvec2(0.0), double angle_degrees = 0.0)#
A slot (stadium): two half circles joined by straight sides.
- Parameters:
length – Overall length, tip to tip; at least width.
width – The width, which is also the diameter of the ends.
center – The centre.
angle_degrees – Direction of the long axis, counter-clockwise from +X.
- Throws:
std::runtime_error – if the width is not positive or the length is less than the width.
- Returns:
The profile; a circle when length equals width.
The union of profiles.
- Parameters:
profiles – The profiles; an empty list gives the empty profile.
tolerance – Tessellation tolerance for the topology; 0 uses the smallest default tolerance of the inputs.
- Throws:
std::runtime_error – if a profile is null.
- Returns:
The union.
Private Functions
-
double side(const ProfileHit &hit, const glm::dvec2 &point) const#
Returns +1 when the point lies on the inside of the boundary at a hit, else -1.
-
struct ProfileHit#
- #include <profile.h>
The boundary point of a profile closest to a query point.
Curves from other data#
Curves made from other OpenVCAD data: mesh paths, mesh boundaries and contours.
Functions
-
std::vector<std::shared_ptr<PolylineCurve>> boundary_loops(const std::vector<glm::vec3> &vertices, const std::vector<Indexed_Triangle> &triangles, const std::vector<size_t> &triangle_ids = {})#
Stitches the open edges of a set of triangles into closed loops.
An edge is open when no other triangle of the set uses it. Loops follow the triangles’ winding: for an outward-facing mesh, each loop runs counter-clockwise seen from the side the mesh faces. Chains that do not close (at non-manifold edges) are left out.
- Parameters:
vertices – The mesh vertices.
triangles – The mesh triangles.
triangle_ids – The triangles to use; empty uses all of them.
- Returns:
One closed PolylineCurve per loop.
The iso-lines of a node at height z as curves, placed at that height.
Closed contours come first (as closed PolylineCurves), then open ones. See node_cross_section().
- Parameters:
node – The node.
z – The height of the plane; the curves are placed at this height.
cell_size – The marching-squares cell size (also the voxel size the clone is prepared with).
iso_value – The level to trace; 0 is the node’s surface.
- Returns:
The contours as PolylineCurves.
-
std::shared_ptr<PolylineCurve> mesh_path_curve(const MeshPath &path)#
The polyline through the points of a mesh path.
- Parameters:
path – The mesh path.
- Throws:
std::runtime_error – if the path has fewer than 2 points.
- Returns:
An open PolylineCurve through the path’s points.
Traces the iso-lines of a node on the plane at height z with marching squares.
A clone of the node is prepared with the cell size as voxel size, and the grid covers its bounding box with a two-cell margin, so contours of the zero level close.
- Parameters:
node – The node.
z – The height of the plane.
cell_size – The marching-squares cell size.
iso_value – The level to trace; 0 is the node’s surface.
- Returns:
The closed contours (counter-clockwise) and the open ones, with 2D points at z = 0.