35#ifndef LIB2GEOM_SEEN_PATH_H
36#define LIB2GEOM_SEEN_PATH_H
47#include <boost/operators.hpp>
48#include <boost/ptr_container/ptr_vector.hpp>
60namespace PathInternal {
71 :
public boost::random_access_iterator_helper
115 return (std::ptrdiff_t)
index - (std::ptrdiff_t)other.
index;
122 friend class ::Geom::Path;
138 : boost::totally_ordered<PathTime>
268 os <<
"PathInterval[";
270 os << ival.
from() <<
" -> 0: 0.0 -> " << ival.
to();
272 os << ival.
from() <<
" -> " << ival.
to();
352 : boost::equality_comparable< Path >
391 template <
typename Iter>
397 for (Iter i = first; i != last; ++i) {
398 _data->curves.push_back(i->duplicate());
400 if (!
_data->curves.empty()) {
402 _data->curves.front().initialPoint());
450 return _data->curves[
_data->curves.size() - 2];
530 bool operator==(
Path const &other)
const;
533 template <
typename T>
537 for (std::size_t i = 0; i <
_data->curves.size(); ++i) {
538 _data->curves[i] *= tr;
543 template <
typename T>
620 std::vector<Point>
nodes()
const;
643 std::optional<Point>
const &p_from, std::optional<Point>
const &p_to)
const;
685 template <
typename Iter>
688 Sequence::iterator seq_pos(
seq_iter(pos));
690 for (; first != last; ++first) {
691 source.push_back(first->duplicate());
714 for (
auto const &
curve : *
this) {
715 if (!
curve.isDegenerate()) {
716 return curve.unitTangentAt(0.0);
725 for (
auto it =
end(); it !=
begin();) {
727 if (!it->isDegenerate()) {
728 return it->unitTangentAt(1.0);
737 _data->curves.front().setInitial(p);
775 template <
typename Iter>
777 replace(replaced, replaced + 1, first, last);
780 template <
typename Iter>
783 Sequence::iterator seq_first_replaced(
seq_iter(first_replaced));
784 Sequence::iterator seq_last_replaced(
seq_iter(last_replaced));
786 for (; first != last; ++first) {
787 source.push_back(first->duplicate());
789 do_update(seq_first_replaced, seq_last_replaced, source);
803 template <
typename CurveType,
typename... Args>
833 return iter.
path->_data->curves.begin() + iter.
index;
836 return iter.
path->_data->curves.begin() + iter.
index;
846 if (
_data.use_count() != 1) {
854 void stitch(Sequence::iterator first_replaced, Sequence::iterator last_replaced,
Sequence &sequence);
855 void do_update(Sequence::iterator first, Sequence::iterator last,
Sequence &source);
901std::ostream &operator<<(std::ostream &out,
Path const &path);
bool isDegenerate() const override
Check whether the curve has exactly zero length.
void setInitial(Point const &v) override
Change the starting point of the curve.
void setFinal(Point const &v) override
Change the ending point of the curve.
Set of all points at a fixed distance from the center.
Convex hull based on the Andrew's monotone chain algorithm.
Abstract continuous curve on a plane defined on [0,1].
Adaptor that creates 2D functions from 1D ones.
Set of points with a constant sum of distances from two foci.
Intersection between two shapes.
Range of real numbers that is never empty.
Axis-aligned rectangle that can be empty.
bool operator<(BaseIterator const &other) const
std::ptrdiff_t operator-(Self const &other) const
BaseIterator(P &p, unsigned i)
Self & operator+=(std::ptrdiff_t d)
Curve const & operator*() const
bool operator==(BaseIterator const &other) const
Self & operator-=(std::ptrdiff_t d)
Contiguous subset of the path's parameter domain.
PathTime const & finalTime() const
Get the time value of the final point.
PathInternal::Sequence::size_type size_type
static PathInterval from_direction(PathTime const &from, PathTime const &to, bool reversed, size_type path_size)
Select one of two intervals with given endpoints by parameter direction.
bool reverse() const
True if the interval goes in the direction of decreasing time values.
PathTime const & initialTime() const
Get the time value of the initial point.
PathTime inside(Coord min_dist=EPSILON) const
Get a time at least min_dist away in parameter space from the ends.
size_type curveCount() const
bool isDegenerate() const
Check whether the interval has only one point.
PathTime const & to() const
static PathInterval from_start_crossing(PathTime const &from, PathTime const &to, bool cross_start, size_type path_size)
Select one of two intervals with given endpoints by whether it includes the initial point.
PathInterval backward_interval(PathTime const &from, PathTime const &to, PathInterval::size_type path_size)
Create an interval in the direction of decreasing time value.
bool contains(PathTime const &pos) const
Test a path time for inclusion.
PathInterval forward_interval(PathTime const &from, PathTime const &to, PathInterval::size_type path_size)
Create an interval in the direction of increasing time value.
bool crossesStart() const
True if the interior of the interval contains the initial point of the path.
PathTime const & from() const
size_type pathSize() const
PathInterval()
Default interval.
std::ostream & operator<<(std::ostream &os, PathInterval const &ival)
Output an interval in the path's domain.
Curve * reverse() const override
Create a reversed version of this curve.
Curve * duplicate() const override
Create an exact copy of this curve.
ClosingSegment(Point const &p1, Point const &p2)
Curve * duplicate() const override
Create an exact copy of this curve.
StitchSegment(Point const &p1, Point const &p2)
Curve * reverse() const override
Create a reversed version of this curve.
Sequence of contiguous curves, aka spline.
bool closed() const
Check whether the path is closed.
Curve const & finalCurve() const
Point finalPoint() const
Get the last point in the path.
PathExtrema extrema(Dim2 d) const
Find the extrema of the specified coordinate.
void setStitching(bool x)
Enable or disable the throwing of exceptions when stitching discontinuities.
void close(bool closed=true)
Set whether the path is closed.
Interval timeRange() const
Get the allowed range of time values.
std::shared_ptr< PathData > _data
friend void swap(Path &a, Path &b) noexcept
Swap contents of two paths.
bool empty() const
Check whether path is empty.
OptRect boundsExact() const
Get a tight-fitting bounding box.
Path portion(PathTime const &from, PathTime const &to, bool cross_start=false) const
Get a subset of the current path with full precision.
Piecewise< D2< SBasis > > toPwSb() const
Path & operator*=(T const &tr)
Apply a transform to each curve.
Curve const & back_closed() const
friend Path operator*(Path const &path, T const &tr)
bool _exception_on_stitch
void insert(iterator pos, Iter first, Iter last)
Path(Point const &p=Point())
Construct an empty path starting at the specified point.
std::vector< PathTime > roots(Coord v, Dim2 d) const
Compute intersections with axis-aligned line.
const_iterator end() const
Curve const & back() const
Access the last curve in the path.
PathTime nearestTime(Point const &p, Coord *dist=NULL) const
std::vector< PathIntersection > intersectSelf(Coord precision=EPSILON) const
Compute intersections of the path with itself.
Point pointAt(Coord t) const
Get the point at the specified time value.
OptRect boundsFast() const
Get the approximate bounding box.
size_type size_open() const
Size without the closing segment, even if the path is closed.
void replace(iterator replaced, Iter first, Iter last)
void clear()
Remove all curves from the path.
Path withoutDegenerateCurves() const
Return a copy of the path without degenerate curves, except possibly for a degenerate closing segment...
void appendPortionTo(Path &p, PathTime const &from, PathTime const &to, bool cross_start=false) const
Append a subset of this path to another path.
void appendPortionTo(Path &p, PathInterval const &ival) const
Append a subset of this path to another path.
Path(Iter first, Iter last, bool closed=false, bool stitch=false)
Construct a path containing a range of curves.
const_iterator end_open() const
Curve const & initialCurve() const
Alias for front().
std::vector< Coord > allNearestTimes(Point const &p) const
size_type size_default() const
Natural size of the path.
ClosingSegment * _closing_seg
Path portion(Coord f, Coord t) const
Point finalUnitTangent() const
Get the unit tangent vector at the end of the path, or the zero vector if undefined.
Curve const & back_open() const
std::vector< PathIntersection > intersect(Path const &other, Coord precision=EPSILON) const
Compute intersections with another path.
static Sequence::const_iterator seq_iter(const_iterator const &iter)
void replace(iterator first_replaced, iterator last_replaced, Iter first, Iter last)
int winding(Point const &p) const
Determine the winding number at the specified point.
PathInternal::Sequence Sequence
void appendPortionTo(Path &p, Coord f, Coord t) const
Path portion(PathInterval const &ival) const
Get a subset of the current path with full precision.
Sequence::size_type size_type
bool _includesClosingSegment() const
Path portion(Interval const &i) const
Curve const & back_default() const
void append(Curve *curve)
Add a new curve to the end of the path.
static Sequence::iterator seq_iter(iterator const &iter)
Point initialPoint() const
Get the first point in the path.
Curve const & front() const
Access the first curve in the path.
void do_append(Curve *curve)
Path reversed() const
Obtain a reversed version of the current path.
PathInternal::PathData PathData
void setFinal(Point const &p)
Point initialUnitTangent() const
Get the unit tangent vector at the start of the path, or the zero vector if undefined.
PathInternal::BaseIterator< Path const > const_iterator
void snapEnds(Coord precision=EPSILON)
Reduce the closing segment to a point if it's shorter than precision.
size_type size_closed() const
Size with the closing segment, if it makes a difference.
size_type size() const
Natural size of the path.
Coord valueAt(Coord t, Dim2 d) const
Get one coordinate (X or Y) at the specified time value.
size_type max_size() const
const_iterator begin() const
void replace(iterator replaced, Curve const &curve)
void append(Curve const &curve)
Curve const & at(size_type i) const
Access a curve by index.
void checkContinuity() const
Verify the continuity invariant.
void do_update(Sequence::iterator first, Sequence::iterator last, Sequence &source)
void append(D2< SBasis > const &curve)
void append(Path const &other)
PathInternal::BaseIterator< Path > iterator
LineSegment const & closingSegment() const
Get the closing segment of the path.
std::vector< Coord > allNearestTimes(Point const &p, Coord from, Coord to) const
void setInitial(Point const &p)
Curve const & operator[](size_type i) const
Access a curve by index.
PathTime _factorTime(Coord t) const
Curve const & curveAt(Coord t, Coord *rest=NULL) const
Get the curve at the specified time value.
void stitch(Sequence::iterator first_replaced, Sequence::iterator last_replaced, Sequence &sequence)
void appendNew(Args &&... args)
Append a new curve to the path.
const_iterator end_closed() const
std::vector< Coord > nearestTimePerCurve(Point const &p) const
void swap(Path &other) noexcept
Swap contents with another path.
std::vector< Point > nodes() const
const_iterator end_default() const
Sequence::difference_type difference_type
Point operator()(Coord t) const
void stitchTo(Point const &p)
Append a stitching segment ending at the specified point.
void insert(iterator pos, Curve const &curve)
Function defined as discrete pieces.
Two-dimensional point that doubles as a vector.
Axis aligned, non-empty rectangle.
Symmetric power basis curve.
Path and its polyline approximation.
Dim2
2D axis enumeration (X or Y).
double Coord
Floating point type used to store coordinates.
constexpr Coord EPSILON
Default "acceptably small" value.
vector< vector< Point > > paths
boost::ptr_vector< Curve > Sequence
Various utility functions.
Piecewise< D2< SBasis > > paths_to_pw(PathVector const &paths)
std::ostream & operator<<(std::ostream &os, const Bezier &b)
PathIntersection parting_point(Path const &first, Path const &second, Coord precision=EPSILON)
Find the first point where two paths diverge away from one another.
Coord nearest_time(Point const &p, Curve const &c)
Intersection< PathTime > PathIntersection
std::string format_coord_nice(Coord x)
bool are_near(Affine const &a1, Affine const &a2, Coord eps=EPSILON)
Stores information about the extremum points on a path, with respect to one of the coordinate axes.
float glance_direction_at_min
Directions in which the OTHER coordinates change at the extremum points.
Point min_point
Points with the minimum and maximum value of a coordinate.
float glance_direction_at_max
PathTime min_time
Path times corresponding to minimum and maximum points.
Generalized time value in the path.
size_type curve_index
Index of the curve in the path.
Coord t
Time value in the curve.
void normalizeBackward(size_type path_size)
Convert times at or before 0 to 1 on the previous curve.
PathTime(size_type idx, Coord tval)
void normalizeForward(size_type path_size)
Convert times at or beyond 1 to 0 on the next curve.
PathInternal::Sequence::size_type size_type
bool operator==(PathTime const &other) const
bool operator<(PathTime const &other) const
PathIntersection IntersectionType
PathInterval IntervalType