13 #ifndef OGLPLUS_MATH_CURVE_1107121519_HPP
14 #define OGLPLUS_MATH_CURVE_1107121519_HPP
17 #include <oglplus/math/compile_time.hpp>
39 template <
typename Type,
typename Parameter,
unsigned Order>
43 ::std::vector<Type> _points;
46 static bool Connected(const ::std::vector<Type>& points)
48 return ((points.size() - 1) % Order) == 0;
57 static bool Separated(const ::std::vector<Type>& points)
59 return (points.size() % (Order+1)) == 0;
69 static bool PointsOk(const ::std::vector<Type>& points)
71 if(points.empty())
return false;
82 : _points(std::move(points))
94 : _points(std::move(points))
95 , _connected(connected)
121 , _connected(connected)
124 assert(
Connected(_points) == _connected);
127 template <std::
size_t N>
129 : _points(points.begin(), points.end())
135 template <std::
size_t N>
136 BezierCurves(const ::std::array<Type, N>& points,
bool connected)
137 : _points(points.begin(), points.end())
138 , _connected(connected)
141 assert(
Connected(_points) == _connected);
144 unsigned SegmentStep(
void)
const
148 if(_connected)
return Order;
157 if(_connected)
return (_points.size() - 1) / Order;
158 else return _points.size() / (Order+1);
172 if(t < zero) t += ::std::floor(::std::fabs(t))+one;
173 else if(t > one) t -= ::std::floor(t);
174 assert(t >= zero && t <= one);
184 if(t == one) t = zero;
185 assert(t >= zero && t < one);
189 unsigned poffs = unsigned(toffs) * SegmentStep();
191 assert(poffs < _points.size() - Order);
192 Parameter t_sub = toffs - ::std::floor(toffs);
193 return math::Bezier<Type, Parameter, Order>::Position(
194 _points.data() + poffs,
195 _points.size() - poffs,
209 unsigned sstep = SegmentStep();
214 auto p = dest.begin();
217 for(
unsigned i=0; i!=s; ++i)
219 unsigned poffs = i*sstep;
221 const Type* data = _points.data() + poffs;
222 unsigned size = _points.size() - poffs;
223 for(
unsigned j=0; j!=n; ++j)
225 typedef math::Bezier<Type, Parameter, Order> b;
226 assert(p != dest.end());
227 *p = Type(b::Position(data, size, t_sub));
233 assert(p != dest.end());
236 assert(p == dest.end());
242 ::std::vector<Type> result;
250 unsigned sstep = SegmentStep();
253 ::std::vector<Type> new_points(s * Order);
254 auto p = new_points.begin();
256 for(
unsigned i=0; i!=s; ++i)
258 for(
unsigned j=0; j!=Order; ++j)
260 unsigned k = i*sstep+j;
261 assert(p != new_points.end());
262 *p = (_points[k+1] - _points[k]) * Order;
266 assert(p == new_points.end());
268 return BezierCurves<Type,
Parameter, Order-1>(
269 std::move(new_points),
283 template <
typename Type,
typename Parameter>
285 :
public BezierCurves<Type, Parameter, 3>
288 template <
typename StdRange>
289 static std::vector<Type> _make_cpoints(
290 const StdRange& points,
294 std::size_t i = 0, n = points.size();
296 std::vector<Type> result(n * 3 + 1);
297 auto ir = result.begin();
300 unsigned a = (n+i-1)%n;
302 unsigned c = (i+1)%n;
303 unsigned d = (i+2)%n;
304 assert(ir != result.end());
307 assert(ir != result.end());
308 *ir = Type(points[b] + (points[c] - points[a])*r);
310 assert(ir != result.end());
311 *ir = Type(points[c] + (points[b] - points[d])*r);
315 assert(ir != result.end());
316 *ir = points[0]; ++ir;
317 assert(ir == result.end());
323 const ::std::vector<Type>& points,
325 ): BezierCurves<Type,
Parameter, 3>(_make_cpoints(points, r))
328 template <std::
size_t N>
330 const ::std::array<Type, N>& points,
332 ): BezierCurves<Type,
Parameter, 3>(_make_cpoints(points, r))
338 #endif // include guard
::std::vector< Type > Approximate(unsigned n) const
Returns a sequence of points on the curve (n points per segment)
Definition: curve.hpp:240
BezierCurves(const ::std::vector< Type > &points, bool connected)
Creates the bezier curves from the control points.
Definition: curve.hpp:119
A sequence of Bezier curves, possibly connected at end points.
Definition: curve.hpp:40
CubicBezierLoop(const ::std::vector< Type > &points, Parameter r=Parameter(1)/Parameter(3))
Creates a loop passing through the sequence of the input points.
Definition: curve.hpp:322
bool Separated(void) const
Returns true if the individual curves are connected.
Definition: curve.hpp:63
const ::std::vector< Type > & ControlPoints(void) const
Returns the contol points of the curve.
Definition: curve.hpp:162
Type Position01(Parameter t) const
Gets the point on the curve at position t (must be between 0.0, 1.0)
Definition: curve.hpp:179
void Approximate(std::vector< Type > &dest, unsigned n) const
Makes a sequence of points on the curve (n points per segment)
Definition: curve.hpp:207
BezierCurves< Type, Parameter, Order-1 > Derivative(void) const
Returns a derivative of this curve.
Definition: curve.hpp:248
static Parameter Wrap(Parameter t)
Wraps the parameter value to [0.0, 1.0].
Definition: curve.hpp:168
A closed smooth cubic Bezier spline passing through all input points.
Definition: curve.hpp:284
unsigned SegmentCount(void) const
Returns the count of individual curves in the sequence.
Definition: curve.hpp:153
BezierCurves(::std::vector< Type > &&points)
Creates the bezier curves from the control points.
Definition: curve.hpp:81
BezierCurves(const ::std::vector< Type > &points)
Creates the bezier curves from the control points.
Definition: curve.hpp:107
static bool PointsOk(const ::std::vector< Type > &points)
Checks if the sequence of control points is OK for this curve type.
Definition: curve.hpp:69
BezierCurves(::std::vector< Type > &&points, bool connected)
Creates the bezier curves from the control points.
Definition: curve.hpp:93
bool Connected(void) const
Returns true if the individual curves are connected.
Definition: curve.hpp:52
Type Position(Parameter t) const
Gets the point on the curve at position t wrapped to [0.0, 1.0].
Definition: curve.hpp:201