6#include "QskFlickAnimator.h"
9static inline qreal qskAligned( qreal value )
11 if ( qFuzzyIsNull( value ) )
14 if ( qFuzzyCompare( value, -1.0 ) )
17 if ( qFuzzyCompare( value, 1.0 ) )
23QskFlickAnimator::QskFlickAnimator()
24 : m_velocity{ 0.0, 0.0 }
31 setEasingCurve( QEasingCurve::OutCubic );
34QskFlickAnimator::~QskFlickAnimator()
38void QskFlickAnimator::flick( qreal degrees, qreal velocity )
40 if ( velocity < 0.0 || qFuzzyIsNull( velocity ) )
47 m_velocity[ 0 ] = velocity;
48 m_velocity[ 1 ] = 0.0;
50 if ( m_velocity[ 0 ] > 0.0 )
54void QskFlickAnimator::accelerate( qreal degrees, qreal velocity )
56 if ( isRunning() && !qFuzzyIsNull( m_velocity[ 1 ] ) )
58 const qreal delta = qDegreesToRadians( degrees - m_degrees );
60 if ( qFuzzyIsNull( delta ) )
63 velocity += 4.0 * m_velocity[ 1 ];
67 const qreal cos = qFastCos( delta );
71 velocity += exp2( 2.0 * cos ) * m_velocity[ 1 ];
76 velocity = velocity * exp2( 2.0 * cos );
81 flick( degrees, velocity );
84void QskFlickAnimator::done()
86 m_velocity[ 1 ] = 0.0;
90void QskFlickAnimator::setAngle( qreal degrees )
92 if ( degrees != m_degrees )
96 const qreal radians = qDegreesToRadians( degrees );
98 m_cos = qskAligned( qFastCos( radians ) );
99 m_sin = qskAligned( qFastSin( radians ) );
103void QskFlickAnimator::setVelocity( qreal velocity )
105 m_velocity[ 0 ] = velocity;
108void QskFlickAnimator::setup()
111 m_velocity[ 1 ] = m_velocity[ 0 ];
114void QskFlickAnimator::advance( qreal value )
116 const qreal oldVelocity = m_velocity[ 1 ];
117 const int oldElapsed = m_elapsed;
119 m_velocity[ 1 ] = m_velocity[ 0 ] * ( 1.0 - value );
120 m_elapsed = elapsed();
122 const qreal duration = ( m_elapsed - oldElapsed ) / 1000.0;
123 if ( duration > 0.0 )
125 const qreal velocity = 0.5 * ( m_velocity[ 1 ] + oldVelocity );
132 const qreal distance = duration * velocity;
133 translate( m_cos * distance, m_sin * distance );