made array handling better in interpolator
This commit is contained in:
parent
dadeddcafa
commit
8db3e58980
1 changed files with 52 additions and 88 deletions
140
J/interpolator.h
140
J/interpolator.h
|
@ -11,10 +11,40 @@
|
|||
|
||||
#include <tr1/functional>
|
||||
|
||||
// NOTE: there is a specialisation for std::array
|
||||
// But i'm not glad with how this is done...
|
||||
|
||||
namespace J {
|
||||
|
||||
namespace interpolator_details {
|
||||
// some templates to handle arrays...
|
||||
template <typename Scalar, typename T>
|
||||
void interpolate(Scalar const & ratio, T & value, T const & begin_value, T const & end_value){
|
||||
value = (Scalar(1.0) - ratio)*begin_value + ratio*end_value;
|
||||
}
|
||||
template <typename Scalar, typename T, size_t N>
|
||||
void interpolate(Scalar const & ratio, T (& value)[N], T const (& begin_value)[N], T const (& end_value)[N]){
|
||||
for (unsigned int i = 0; i < N; ++i)
|
||||
value[i] = (Scalar(1.0) - ratio)*begin_value[i] + ratio*end_value[i];
|
||||
}
|
||||
template <typename Scalar, typename T, size_t N>
|
||||
void interpolate(Scalar const & ratio, std::array<T, N> & value, std::array<T, N> const & begin_value, std::array<T, N> const & end_value){
|
||||
for (unsigned int i = 0; i < N; ++i)
|
||||
value[i] = (Scalar(1.0) - ratio)*begin_value[i] + ratio*end_value[i];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct scalar_of {
|
||||
// TODO: find out how to make it work for user-types
|
||||
// maybe require T::Scalar
|
||||
typedef T type;
|
||||
};
|
||||
template <typename T, size_t N>
|
||||
struct scalar_of<T[N]> {
|
||||
typedef typename scalar_of<T>::type type;
|
||||
};
|
||||
template <typename T, size_t N>
|
||||
struct scalar_of<std::array<T, N> > {
|
||||
typedef typename scalar_of<T>::type type;
|
||||
};
|
||||
}
|
||||
|
||||
namespace interpolators {
|
||||
struct linear{
|
||||
|
@ -49,8 +79,10 @@ namespace interpolators {
|
|||
|
||||
template <typename T>
|
||||
class interpolator {
|
||||
typedef typename interpolator_details::scalar_of<T>::type Scalar;
|
||||
typedef std::tr1::function<Scalar (Scalar)> EaseFunction;
|
||||
|
||||
std::tr1::function<T (T)> ease_function;
|
||||
EaseFunction ease_function;
|
||||
|
||||
size_t length;
|
||||
size_t steps;
|
||||
|
@ -62,7 +94,7 @@ class interpolator {
|
|||
public:
|
||||
|
||||
template <typename S>
|
||||
interpolator(S begin_value_, size_t length_ = 100) :
|
||||
interpolator(S const & begin_value_, size_t length_ = 30) :
|
||||
ease_function(interpolators::cubic_in_out())
|
||||
, length(length_)
|
||||
, steps(length_)
|
||||
|
@ -71,7 +103,7 @@ public:
|
|||
, end_value(begin_value_) {}
|
||||
|
||||
template <typename S, typename F>
|
||||
interpolator(S begin_value_, size_t length_, F ease_function_) :
|
||||
interpolator(S const & begin_value_, size_t length_, F const & ease_function_) :
|
||||
ease_function(ease_function_)
|
||||
, length(length_)
|
||||
, steps(0)
|
||||
|
@ -87,110 +119,42 @@ public:
|
|||
return value;
|
||||
}
|
||||
|
||||
void set_value(T new_value){
|
||||
void set_value(T const & new_value){
|
||||
begin_value = value;
|
||||
end_value = new_value;
|
||||
steps = 0;
|
||||
}
|
||||
|
||||
// FIXME: temporary hack
|
||||
template <size_t N>
|
||||
void set_value(Scalar const (& new_value)[N]){
|
||||
begin_value = value;
|
||||
for(unsigned int i = 0; i < N; ++i)
|
||||
end_value[i] = new_value[i];
|
||||
steps = 0;
|
||||
}
|
||||
|
||||
void set_length(size_t new_length){
|
||||
T ratio = (T) steps / (T) length;
|
||||
Scalar ratio = (Scalar) steps / (Scalar) length;
|
||||
length = new_length;
|
||||
steps = ratio*length;
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void set_ease_function(F new_ease_function){
|
||||
void set_ease_function(F const & new_ease_function){
|
||||
ease_function = new_ease_function;
|
||||
}
|
||||
|
||||
void interpolate(){
|
||||
if(steps >= length) return;
|
||||
++steps;
|
||||
T ratio = (T) steps / (T) length;
|
||||
Scalar ratio = (Scalar) steps / (Scalar) length;
|
||||
ratio = ease_function(ratio);
|
||||
value = (T(1) - ratio)*begin_value + ratio*end_value;
|
||||
interpolator_details::interpolate(ratio, value, begin_value, end_value);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename T, size_t N>
|
||||
class interpolator<std::array<T, N> > {
|
||||
|
||||
std::tr1::function<T (T)> ease_function;
|
||||
|
||||
size_t length;
|
||||
size_t steps;
|
||||
|
||||
std::array<T, N> value;
|
||||
std::array<T, N> begin_value;
|
||||
std::array<T, N> end_value;
|
||||
|
||||
public:
|
||||
|
||||
template <typename S>
|
||||
interpolator(S begin_value_, size_t length_ = 100) :
|
||||
ease_function(interpolators::cubic_in_out())
|
||||
, length(length_)
|
||||
, steps(length_)
|
||||
, value(begin_value_)
|
||||
, begin_value(begin_value_)
|
||||
, end_value(begin_value_) {}
|
||||
|
||||
template <typename S, typename F>
|
||||
interpolator(S const & begin_value_, size_t length_, F const & ease_function_) :
|
||||
ease_function(ease_function_)
|
||||
, length(length_)
|
||||
, steps(0)
|
||||
, value(begin_value_)
|
||||
, begin_value(begin_value_)
|
||||
, end_value(begin_value_) {}
|
||||
|
||||
std::array<T, N> const & get_value() const{
|
||||
return value;
|
||||
}
|
||||
|
||||
operator std::array<T, N> const & () const{
|
||||
return value;
|
||||
}
|
||||
|
||||
void set_value(std::array<T, N> const & new_value){
|
||||
begin_value = value;
|
||||
end_value = new_value;
|
||||
steps = 0;
|
||||
}
|
||||
|
||||
void set_value(T const (& new_value)[N]){
|
||||
begin_value = value;
|
||||
for (unsigned int i = 0; i < N; ++i) {
|
||||
end_value[i] = new_value[i];
|
||||
}
|
||||
steps = 0;
|
||||
}
|
||||
|
||||
void set_length(size_t new_length){
|
||||
T ratio = (T) steps / (T) length;
|
||||
length = new_length;
|
||||
steps = ratio*length;
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void set_ease_function(F new_ease_function){
|
||||
ease_function = new_ease_function;
|
||||
}
|
||||
|
||||
void interpolate(){
|
||||
if(steps >= length) return;
|
||||
++steps;
|
||||
T ratio = (T) steps / (T) length;
|
||||
ratio = ease_function(ratio);
|
||||
for (unsigned int i = 0; i < N; ++i) {
|
||||
value[i] = (T(1) - ratio)*begin_value[i] + ratio*end_value[i];
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace J
|
||||
|
||||
#endif
|
||||
|
|
Reference in a new issue