Refactor geom::bezier: extract a free-function de Casteljau's algorithm & support changing control points
This commit is contained in:
parent
a368eb32ff
commit
a22ea3d02e
1 changed files with 33 additions and 7 deletions
|
|
@ -8,9 +8,24 @@
|
|||
namespace psemek::geom
|
||||
{
|
||||
|
||||
// In-place de Casteljau's algorithm
|
||||
template <typename Iterator, typename T>
|
||||
auto de_casteljau(Iterator begin, Iterator end, T const & t)
|
||||
{
|
||||
while (std::next(begin) != end)
|
||||
{
|
||||
for (auto it = begin, jt = std::next(begin); jt != end; it = jt++)
|
||||
*it = lerp(*it, *jt, t);
|
||||
--end;
|
||||
}
|
||||
return *begin;
|
||||
}
|
||||
|
||||
template <typename Point>
|
||||
struct bezier
|
||||
{
|
||||
bezier() = default;
|
||||
|
||||
bezier(std::vector<Point> points)
|
||||
: points_(std::move(points))
|
||||
{
|
||||
|
|
@ -19,23 +34,34 @@ namespace psemek::geom
|
|||
temp_.resize(points_.size());
|
||||
}
|
||||
|
||||
std::vector<Point> & points()
|
||||
{
|
||||
return points_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto operator()(T const & t) const
|
||||
{
|
||||
// In-place de Casteljau's algorithm
|
||||
temp_ = points_;
|
||||
return de_casteljau(temp_.begin(), temp_.end(), t);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto tangent(T const & t) const
|
||||
{
|
||||
// In-place de Casteljau's algorithm for derivative
|
||||
tangent_temp_.resize(points_.size() - 1);
|
||||
for (std::size_t k = 0; k + 1 < points_.size(); ++k)
|
||||
{
|
||||
for (std::size_t i = 0; i + k + 1 < points_.size(); ++i)
|
||||
temp_[i] = lerp(temp_[i], temp_[i + 1], t);
|
||||
}
|
||||
return temp_.front();
|
||||
tangent_temp_[k] = points_[k + 1] - points_[k];
|
||||
return static_cast<T>(points_.size()) * de_casteljau(tangent_temp_.begin(), tangent_temp_.end(), t);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Point> const points_;
|
||||
using vector_type = decltype(Point{} - Point{});
|
||||
|
||||
std::vector<Point> points_;
|
||||
std::vector<Point> mutable temp_;
|
||||
std::vector<vector_type> mutable tangent_temp_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue