From 32d5b348bcf1d87d3de653ddff96f4c81add4a3b Mon Sep 17 00:00:00 2001 From: Joshua Moerman Date: Fri, 21 Oct 2011 15:11:01 +0200 Subject: [PATCH] added documentation to interpolator --- J/J.m | 23 ------------- J/interpolator.h | 89 +++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 76 insertions(+), 36 deletions(-) delete mode 100644 J/J.m diff --git a/J/J.m b/J/J.m deleted file mode 100644 index d707e75..0000000 --- a/J/J.m +++ /dev/null @@ -1,23 +0,0 @@ -// -// J.m -// J -// -// Created by Joshua Moerman on 8/28/11. -// Copyright 2011 Vadovas. All rights reserved. -// - -#import "J.h" - -@implementation J - -- (id)init -{ - self = [super init]; - if (self) { - // Initialization code here. - } - - return self; -} - -@end diff --git a/J/interpolator.h b/J/interpolator.h index b0735e2..c1379ab 100644 --- a/J/interpolator.h +++ b/J/interpolator.h @@ -6,6 +6,57 @@ // Copyright 2011 Vadovas. All rights reserved. // +/* + The interpolator interpolates between the current value and the value to interpolate to, both values are stored in the interpolator object. For easing there are different functors given (in the namespace interpolators: linear, cubic_in_out, quintic_in_out, cosine_in_out), but using a custom ease function is also possible (as long as it is convertible to std::function, see below for the type). + + The constructor takes three values: the first is the begin_value (usually 0), the second is the length of interpolation time, the last is the ease function. The interpolation time and the ease function can be changed later with the corresponding setters. + + The interpolated value can be retrieved with .get_value(), setting a new value to interpolate to is done via .set_value(new_value). Updating the time is done with .interpolate(dt). + + For example (interpolating a float from 0 to 10 in 5 seconds, with easing): + // creation: + interpolator my_value (0.0, 5.0, interpolators::cosine_in_out); + my_value.set_value(10.0); + + // in update function: + my_value.interpolate(dt); + do_magic(my_value.get_value()); + + It can also be used with c-style arrays and std::array's. This can be usefull for interpolating matrices or colours and such. + + Templates and types: + interpolator + T indicates the type of the value (for example: float, float[16], std::array) + Time indicates the type of the time-steps, you can use int if the system is frame-based (default: float) + + ease_function has type std::function where S is the element-type of T, this means: + If T = float (or any other single value) -> S = float + If T = float[4] (or std::array) -> S = float + In other cases (eg. custom types) it will probably not work. + + Synopsis: + template + class interpolator { + // ctor + template + interpolator(S const & begin_value_, Time const & length_, F const & ease_function_ = interpolators::cubic_in_out()); + + // time-update: + void interpolate(Time const & dt = 1) + + // getters + operator T const & () const; + T const & get_value() const; + + // setters + void set_value(T const & new_value); + void set_length(Time new_length); + + template + void set_ease_function(F const & new_ease_function); + }; + */ + #ifndef J_interpolator_h #define J_interpolator_h @@ -22,12 +73,12 @@ namespace interpolator_details { template 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]; + interpolate(ratio, value[i], begin_value[i], end_value[i]); } template void interpolate(Scalar const & ratio, std::array & value, std::array const & begin_value, std::array const & end_value){ for (unsigned int i = 0; i < N; ++i) - value[i] = (Scalar(1.0) - ratio)*begin_value[i] + ratio*end_value[i]; + interpolate(ratio, value[i], begin_value[i], end_value[i]); } template @@ -77,39 +128,44 @@ namespace interpolators { }; } -template +template class interpolator { typedef typename interpolator_details::scalar_of::type Scalar; typedef std::tr1::function EaseFunction; EaseFunction ease_function; - size_t length; - size_t steps; + Time length; + Time steps; T value; T begin_value; T end_value; + bool done; + public: template - interpolator(S const & begin_value_, size_t length_ = 30) : + interpolator(S const & begin_value_, Time const & length_) : ease_function(interpolators::cubic_in_out()) , length(length_) , steps(length_) , value(begin_value_) , begin_value(begin_value_) - , end_value(begin_value_) {} + , end_value(begin_value_) + , done(false) {} + // NOTE: we can't use template-defaults in functions, so we have to make an overload for this one... template - interpolator(S const & begin_value_, size_t length_, F const & ease_function_) : + interpolator(S const & begin_value_, Time const & length_, F const & ease_function_) : ease_function(ease_function_) , length(length_) , steps(0) , value(begin_value_) , begin_value(begin_value_) - , end_value(begin_value_) {} + , end_value(begin_value_) + , done(false) {} operator T const & () const{ return value; @@ -123,6 +179,7 @@ public: begin_value = value; end_value = new_value; steps = 0; + done = false; } // FIXME: temporary hack @@ -132,12 +189,14 @@ public: for(unsigned int i = 0; i < N; ++i) end_value[i] = new_value[i]; steps = 0; + done = false; } - void set_length(size_t new_length){ + void set_length(Time new_length){ Scalar ratio = (Scalar) steps / (Scalar) length; length = new_length; steps = ratio*length; + done = false; } template @@ -145,9 +204,13 @@ public: ease_function = new_ease_function; } - void interpolate(){ - if(steps >= length) return; - ++steps; + void interpolate(Time const & dt = 1){ + if(done) return; + steps += dt; + if(steps >= length){ + steps = length; + done = true; + } Scalar ratio = (Scalar) steps / (Scalar) length; ratio = ease_function(ratio); interpolator_details::interpolate(ratio, value, begin_value, end_value);