Bezier
Fast and lightweight class for using the Bezier curves of any order in C++
bezier.h
1 /*
2  * Copyright 2019 Mirko Kokot
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef BEZIER_H
18 #define BEZIER_H
19 
20 #include <map>
21 #include <memory>
22 
23 #include "declarations.h"
24 
25 namespace Bezier
26 {
35 class Curve
36 {
37 public:
38  ~Curve() = default;
39 
44  Curve(Eigen::MatrixX2d points);
45 
50  Curve(const PointVector& points);
51 
52  Curve(const Curve& curve);
53  Curve(Curve&&) = default;
54  Curve& operator=(const Curve&);
55  Curve& operator=(Curve&&) = default;
56 
61  unsigned order() const;
62 
67  PointVector controlPoints() const;
68 
74  Point controlPoint(unsigned idx) const;
75 
80  std::pair<Point, Point> endPoints() const;
81 
87  PointVector polyline(double flatness = 0.5) const;
88 
93  double length() const;
94 
100  double length(double t) const;
101 
108  double length(double t1, double t2) const;
109 
116  double iterateByLength(double t, double s) const;
117 
121  void reverse();
122 
128  void setControlPoint(unsigned idx, const Point& point);
129 
138  void manipulateCurvature(double t, const Point& point);
139 
146  void elevateOrder();
147 
155  void lowerOrder();
156 
162  Point valueAt(double t) const;
163 
169  Eigen::MatrixX2d valueAt(const std::vector<double>& t_vector) const;
170 
176  double curvatureAt(double t) const;
177 
183  double curvatureDerivativeAt(double t) const;
184 
191  Vector tangentAt(double t, bool normalize = true) const;
192 
199  Vector normalAt(double t, bool normalize = true) const;
200 
205  const Curve& derivative() const;
206 
213  const Curve& derivative(unsigned n) const;
214 
220  Vector derivativeAt(double t) const;
221 
228  Vector derivativeAt(unsigned n, double t) const;
229 
234  std::vector<double> roots() const;
235 
240  std::vector<double> extrema() const;
241 
246  BoundingBox boundingBox() const;
247 
253  std::pair<Curve, Curve> splitCurve(double z = 0.5) const;
254 
260  PointVector intersections(const Curve& curve) const;
261 
267  double projectPoint(const Point& point) const;
268 
274  double distance(const Point& point) const;
275 
281  void applyContinuity(const Curve& source_curve, const std::vector<double>& beta_coeffs);
282 
283 protected:
288  Eigen::MatrixX2d control_points_;
289 
291  inline void resetCache();
292 
293 private:
295  unsigned N_{};
296 
300  using Coeffs = Eigen::MatrixXd;
304  using CoeffsMap = std::map<unsigned, Coeffs>;
305 
306  // private caching
307  mutable std::unique_ptr<const Curve> cached_derivative_;
308  mutable std::unique_ptr<std::vector<double>> cached_roots_;
309  mutable std::unique_ptr<BoundingBox> cached_bounding_box_;
310  mutable std::unique_ptr<PointVector> cached_polyline_;
311  mutable double cached_polyline_flatness_{};
312  mutable std::unique_ptr<Eigen::VectorXd>
313  cached_projection_polynomial_part_;
314  mutable Eigen::MatrixXd
315  cached_projection_polynomial_derivative_;
316  mutable std::unique_ptr<Eigen::VectorXd> cached_chebyshev_coeffs_;
318  // static caching
319  static CoeffsMap bernstein_coeffs_;
320  static CoeffsMap splitting_coeffs_left_;
321  static CoeffsMap splitting_coeffs_right_;
322  static CoeffsMap elevate_order_coeffs_;
323  static CoeffsMap lower_order_coeffs_;
325  static Coeffs bernsteinCoeffs(unsigned n);
328  static Coeffs splittingCoeffsLeft(unsigned n, double z = 0.5);
330  static Coeffs splittingCoeffsRight(unsigned n, double z = 0.5);
332  static Coeffs elevateOrderCoeffs(unsigned n);
334  static Coeffs lowerOrderCoeffs(unsigned n);
335 };
336 
337 } // namespace Bezier
338 
339 #endif // BEZIER_H
Bezier::BoundingBox
Eigen::AlignedBox2d BoundingBox
Bounding box class.
Definition: declarations.h:74
Bezier::Curve
A Bezier curve class.
Definition: bezier.h:35
Bezier::Curve::extrema
std::vector< double > extrema() const
Get all extrema of the curve.
Bezier::Curve::boundingBox
BoundingBox boundingBox() const
Get the bounding box of curve.
Bezier::Curve::splitCurve
std::pair< Curve, Curve > splitCurve(double z=0.5) const
Split the curve into two subcurves.
Bezier::Point
Eigen::Vector2d Point
Point in xy plane.
Definition: declarations.h:59
Bezier::Curve::lowerOrder
void lowerOrder()
Lower the curve order by 1.
Bezier::Curve::endPoints
std::pair< Point, Point > endPoints() const
Get first and last control points.
Bezier::Curve::setControlPoint
void setControlPoint(unsigned idx, const Point &point)
Set the new coordinates to a control point.
Bezier::Curve::normalAt
Vector normalAt(double t, bool normalize=true) const
Get the normal of the curve for a given t.
Bezier::Curve::tangentAt
Vector tangentAt(double t, bool normalize=true) const
Get the tangent of the curve for a given t.
Bezier::Curve::iterateByLength
double iterateByLength(double t, double s) const
Compute parameter t which is S distance from given t.
Bezier::Curve::intersections
PointVector intersections(const Curve &curve) const
Get the points of intersection with another curve.
Bezier::Curve::order
unsigned order() const
Get order of the curve (Nth order curve is described with N+1 points);.
Bezier::Curve::valueAt
Point valueAt(double t) const
Get the point on curve for a given t.
Bezier::Curve::reverse
void reverse()
Reverse order of control points.
Bezier::Curve::resetCache
void resetCache()
Reset all privately cached data.
Bezier::Curve::polyline
PointVector polyline(double flatness=0.5) const
Get a polyline representation of the curve as a vector of points on curve.
Bezier::PointVector
std::vector< Point > PointVector
A vector of Points.
Definition: declarations.h:64
Bezier::Curve::derivative
const Curve & derivative() const
Get the derivative of a curve.
Bezier::Curve::applyContinuity
void applyContinuity(const Curve &source_curve, const std::vector< double > &beta_coeffs)
applyContinuity Apply geometric continuity based on the another curve.
Bezier::Curve::roots
std::vector< double > roots() const
Get roots of the curve on both axes.
Bezier::Curve::manipulateCurvature
void manipulateCurvature(double t, const Point &point)
Manipulate the curve so that it passes through wanted point for given 't'.
Bezier::Curve::derivativeAt
Vector derivativeAt(double t) const
Get value of a derivative for a given t.
Bezier::Curve::elevateOrder
void elevateOrder()
Raise the curve order by 1.
Bezier::Curve::control_points_
Eigen::MatrixX2d control_points_
N x 2 matrix where each row corresponds to control Point.
Definition: bezier.h:288
Bezier::Curve::curvatureDerivativeAt
double curvatureDerivativeAt(double t) const
Get curvature derivative of the curve for a given t.
Bezier::Curve::Curve
Curve(Eigen::MatrixX2d points)
Create the Bezier curve.
Bezier::Vector
Eigen::Vector2d Vector
A Vector in xy plane.
Definition: declarations.h:69
Bezier
Definition: bezier.h:25
Bezier::Curve::distance
double distance(const Point &point) const
Get distance of the point to the curve.
Bezier::Curve::controlPoints
PointVector controlPoints() const
Get a vector of control points.
Bezier::Curve::curvatureAt
double curvatureAt(double t) const
Get curvature of the curve for a given t.
Bezier::Curve::controlPoint
Point controlPoint(unsigned idx) const
Get the control point at index idx.
Bezier::Curve::projectPoint
double projectPoint(const Point &point) const
Get the parameter t where curve is closest to given point.
Bezier::Curve::length
double length() const
Compute exact arc length using Chebyshev polynomials.