|
|
|
|
@ -95,22 +95,25 @@ template<UnsignedInt order, UnsignedInt dimensions, class T> class Bezier {
|
|
|
|
|
*/ |
|
|
|
|
template<class U> constexpr explicit Bezier(const Bezier<order, dimensions, U>& other) noexcept: Bezier{typename Implementation::GenerateSequence<order + 1>::Type(), other} {} |
|
|
|
|
|
|
|
|
|
/** @brief Equality comparison */ |
|
|
|
|
bool operator==(const Bezier<order, dimensions, T>& other) const { |
|
|
|
|
for(std::size_t i = 0; i != order + 1; ++i) |
|
|
|
|
if((*this)[i] != other[i]) return false; |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** @brief Non-equality comparison */ |
|
|
|
|
bool operator!=(const Bezier<order, dimensions, T>& other) const { |
|
|
|
|
return !operator==(other); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Subdivide the curve at given position |
|
|
|
|
* @brief Control point access |
|
|
|
|
* |
|
|
|
|
* Returns two Bézier curves following the original curve, split at |
|
|
|
|
* given interpolation factor. Uses the [De Casteljau's algorithm](https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm).
|
|
|
|
|
* @see @ref value() |
|
|
|
|
* @p i should not be larger than @ref Order. |
|
|
|
|
*/ |
|
|
|
|
std::pair<Bezier<order, dimensions, T>, Bezier<order, dimensions, T>> subdivide(Float t) const { |
|
|
|
|
const auto iPoints = calculateIntermediatePoints(t); |
|
|
|
|
Bezier<order, dimensions, T> left, right; |
|
|
|
|
for(std::size_t i = 0; i <= order; ++i) |
|
|
|
|
left[i] = iPoints[0][i]; |
|
|
|
|
for(std::size_t i = 0, j = order; i <= order; --j, ++i) |
|
|
|
|
right[i] = iPoints[i][j]; |
|
|
|
|
return {left, right}; |
|
|
|
|
} |
|
|
|
|
Vector<dimensions, T>& operator[](std::size_t i) { return _data[i]; } |
|
|
|
|
constexpr Vector<dimensions, T> operator[](std::size_t i) const { return _data[i]; } /**< @overload */ |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Interpolate the curve at given position |
|
|
|
|
@ -124,23 +127,20 @@ template<UnsignedInt order, UnsignedInt dimensions, class T> class Bezier {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Control point access |
|
|
|
|
* @brief Subdivide the curve at given position |
|
|
|
|
* |
|
|
|
|
* @p i should not be larger than @ref Order. |
|
|
|
|
* Returns two Bézier curves following the original curve, split at |
|
|
|
|
* given interpolation factor. Uses the [De Casteljau's algorithm](https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm).
|
|
|
|
|
* @see @ref value() |
|
|
|
|
*/ |
|
|
|
|
Vector<dimensions, T>& operator[](std::size_t i) { return _data[i]; } |
|
|
|
|
constexpr Vector<dimensions, T> operator[](std::size_t i) const { return _data[i]; } /**< @overload */ |
|
|
|
|
|
|
|
|
|
/** @brief Equality comparison */ |
|
|
|
|
bool operator==(const Bezier<order, dimensions, T>& other) const { |
|
|
|
|
for(std::size_t i = 0; i != order + 1; ++i) |
|
|
|
|
if((*this)[i] != other[i]) return false; |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** @brief Non-equality comparison */ |
|
|
|
|
bool operator!=(const Bezier<order, dimensions, T>& other) const { |
|
|
|
|
return !operator==(other); |
|
|
|
|
std::pair<Bezier<order, dimensions, T>, Bezier<order, dimensions, T>> subdivide(Float t) const { |
|
|
|
|
const auto iPoints = calculateIntermediatePoints(t); |
|
|
|
|
Bezier<order, dimensions, T> left, right; |
|
|
|
|
for(std::size_t i = 0; i <= order; ++i) |
|
|
|
|
left[i] = iPoints[0][i]; |
|
|
|
|
for(std::size_t i = 0, j = order; i <= order; --j, ++i) |
|
|
|
|
right[i] = iPoints[i][j]; |
|
|
|
|
return {left, right}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|