// // timing.c // IntroOpenGL // // Created by Ilya Rimchikov on 03/05/14. // Copyright (c) 2014 IntroOpenGL. All rights reserved. // #include "timing.h" static inline float evaluateAtParameterWithCoefficients(float t, float coefficients[]) { return coefficients[0] + t*coefficients[1] + t*t*coefficients[2] + t*t*t*coefficients[3]; } static inline float evaluateDerivationAtParameterWithCoefficients(float t, float coefficients[]) { return coefficients[1] + 2*t*coefficients[2] + 3*t*t*coefficients[3]; } static inline float calcParameterViaNewtonRaphsonUsingXAndCoefficientsForX(float x, float coefficientsX[]) { // see http://en.wikipedia.org/wiki/Newton's_method // start with X being the correct value float t = x; // iterate several times //const float epsilon = 0.00001; int i; for(i = 0; i < 10; i++) { float x2 = evaluateAtParameterWithCoefficients(t, coefficientsX) - x; float d = evaluateDerivationAtParameterWithCoefficients(t, coefficientsX); float dt = x2/d; t = t - dt; } return t; } static inline float calcParameterUsingXAndCoefficientsForX (float x, float coefficientsX[]) { // for the time being, we'll guess Newton-Raphson always // returns the correct value. // if we find it doesn't find the solution often enough, // we can add additional calculation methods. float t = calcParameterViaNewtonRaphsonUsingXAndCoefficientsForX(x, coefficientsX); return t; } static int is_initialized=0; static float _coefficientsX[TIMING_NUM][4], _coefficientsY[TIMING_NUM][4]; static const float _c0x = 0.0; static const float _c0y = 0.0; static const float _c3x = 1.0; static const float _c3y = 1.0; float timing(float x, timing_type type) { if (is_initialized==0) { is_initialized=1; float c[TIMING_NUM][4]; c[Default][0]=0.25; c[Default][1]=0.1; c[Default][2]=0.25; c[Default][3]=1.0; c[EaseInEaseOut][0]=0.42; c[EaseInEaseOut][1]=0.0; c[EaseInEaseOut][2]=0.58; c[EaseInEaseOut][3]=1.0; c[EaseIn][0]=0.42; c[EaseIn][1]=0.0; c[EaseIn][2]=1.0; c[EaseIn][3]=1.0; c[EaseOut][0]=0.0; c[EaseOut][1]=0.0; c[EaseOut][2]=0.58; c[EaseOut][3]=1.0; c[Linear][0]=0.0; c[Linear][1]=0.0; c[Linear][2]=1.0; c[Linear][3]=1.0; int i; for (i=0; i