58 return ::Geom::length(
toSBasis(), tolerance);
64 std::vector<Coord> ts =
roots(p[
Y],
Y);
65 if(ts.empty())
return 0;
66 std::sort(ts.begin(), ts.end());
77 if ((t == 0 && ignore_0) || (t == 1 && ignore_1))
continue;
84 }
else if (tangent[
Y] < 0) {
100 THROW_NOTIMPLEMENTED();
108 std::unique_ptr<Curve>
curve;
113 , parameter_range{from, to}
118 auto const split_into_subcurves = [
this] (std::vector<Coord>
const &splits) {
119 std::vector<Subcurve>
result;
120 result.reserve(splits.size() + 1);
124 if (split < EPSILON || split > 1.0 -
EPSILON) {
135 auto const pairwise_intersect = [=](std::vector<Subcurve>
const &subcurves) {
136 std::vector<CurveIntersection>
result;
137 for (
unsigned i = 0; i < subcurves.size(); i++) {
138 for (
unsigned j = i + 1; j < subcurves.size(); j++) {
139 auto const xings = subcurves[i].curve->intersect(*subcurves[j].
curve, eps);
140 for (
auto const &xing : xings) {
142 if (xing.first == 1. || xing.second == 1.) {
145 Coord const ti = subcurves[i].parameter_range.
valueAt(xing.first);
146 Coord const tj = subcurves[j].parameter_range.valueAt(xing.second);
147 result.emplace_back(ti, tj, xing.point());
164 auto const crits_x = deriv->
roots(0,
X);
165 auto const crits_y = deriv->roots(0,
Y);
166 if (crits_x.empty() || crits_y.empty()) {
171 auto const pieces_x = split_into_subcurves(crits_x);
172 auto const pieces_y = split_into_subcurves(crits_y);
173 auto const crossings_from_x = pairwise_intersect(pieces_x);
174 auto const crossings_from_y = pairwise_intersect(pieces_y);
175 if (crossings_from_x.empty() || crossings_from_y.empty()) {
180 std::vector<CurveIntersection>
result;
181 unsigned index_y = 0;
182 for (
auto &&candidate_x : crossings_from_x) {
184 while (index_y != crossings_from_y.size()) {
185 auto const gap = crossings_from_y[index_y].first - candidate_x.first;
188 result.emplace_back(candidate_x);
191 }
else if (gap < 0.0) {
204 for (
unsigned deriv_n = 1; deriv_n < derivs.size(); deriv_n++) {
208 return derivs[deriv_n] /
length;
216 std::vector<Point> pts;
218 if (moveto_initial) {
221 sink.
curveTo(pts[0], pts[1], pts[2]);
Defines the different types of exceptions that 2geom can throw.
Abstract continuous curve on a plane defined on [0,1].
virtual D2< SBasis > toSBasis() const =0
Convert the curve to a symmetric power basis polynomial.
virtual Point initialPoint() const =0
Retrieve the start of the curve.
virtual Point unitTangentAt(Coord t, unsigned n=3) const
Compute a vector tangent to the curve.
virtual std::vector< Coord > roots(Coord v, Dim2 d) const =0
Computes time values at which the curve intersects an axis-aligned line.
virtual void feed(PathSink &sink, bool moveto_initial) const
Feed the curve to a PathSink.
virtual std::vector< CurveIntersection > intersect(Curve const &other, Coord eps=EPSILON) const
Compute intersections with another curve.
virtual int winding(Point const &p) const
Compute the partial winding number of this curve.
virtual Coord valueAt(Coord t, Dim2 d) const
Evaluate one of the coordinates at the specified time value.
virtual std::vector< Coord > allNearestTimes(Point const &p, Coord from=0, Coord to=1) const
Compute time values at which the curve comes closest to a specified point.
virtual Coord nearestTime(Point const &p, Coord a=0, Coord b=1) const
Compute a time value at which the curve comes closest to a specified point.
virtual std::vector< CurveIntersection > intersectSelf(Coord eps=EPSILON) const
Compute intersections of this curve with itself.
virtual Coord length(Coord tolerance=0.01) const
Compute the arc length of this curve.
virtual Curve * derivative() const =0
Create a derivative of this curve.
virtual Curve * portion(Coord a, Coord b) const =0
Create a curve that corresponds to a part of this curve.
virtual std::vector< Point > pointAndDerivatives(Coord t, unsigned n) const =0
Evaluate the curve and its derivatives.
Range of real numbers that is never empty.
constexpr Coord valueAt(Coord t) const
Map the interval [0,1] onto this one.
Callback interface for processing path data.
virtual void curveTo(Point const &c0, Point const &c1, Point const &p)=0
Output a quadratic Bezier segment.
virtual void moveTo(Point const &p)=0
Move to a different point without creating a segment.
Two-dimensional point that doubles as a vector.
double Coord
Floating point type used to store coordinates.
constexpr Coord EPSILON
Default "acceptably small" value.
Various utility functions.
Coord nearest_time(Point const &p, Curve const &c)
std::vector< double > all_nearest_times(Point const &p, D2< SBasis > const &c, D2< SBasis > const &dc, double from=0, double to=1)
void split(vector< Point > const &p, double t, vector< Point > &left, vector< Point > &right)
void sbasis_to_bezier(Bezier &bz, SBasis const &sb, size_t sz=0)
Changes the basis of p to be bernstein.
bool are_near(Affine const &a1, Affine const &a2, Coord eps=EPSILON)
Nearest time routines for D2<SBasis> and Piecewise<D2<SBasis>>
callback interface for SVG path data
two-dimensional geometric operators.
Conversion between SBasis and Bezier basis polynomials.