You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

57 lines
2.2 KiB

// Fidget spinner logic.
// This class represents a fidget spinner that can be spun to a specified
// velocity and then over time will slow down and stop. The spinner keeps track
// of its continuous (floating point) position value within the range 0...<10
// so it can map to CircuitPlayground pixel positions easily.// Author: Tony DiCola
// License: MIT License (https://opensource.org/licenses/MIT)
// Usage:
// - Create an instance of the class (specifying a custom decay value between 0 and 1,
// the lower the decay the faster the spinner slows down).
// - Call spin to start the spinner moving at the specified velocity (in pixels/second).
// - Call getPosition periodically to get the current spinner position given an elapsed
// amount of seconds since the last getPosition call.
#ifndef FIDGETANIMATION_H
#define FIDGETANIMATION_H
class FidgetSpinner {
public:
FidgetSpinner(float decay=0.5):
_position(0.0), _velocity(0.0), _elapsedS(0.0), _decay(decay)
{}
void spin(float velocity) {
// Start the fidget spinner moving at the specified velocity (in pixels/second).
// Over time the spinner will slow down based on its decay value.
_velocity = velocity;
_elapsedS = 0.0; // Reset elapsed time to start the decay from the beginning.
}
float getPosition(float deltaS) {
// Get the fidget spinner's current position after moving for the specified number
// of milliseconds. Returns a continuous value in the range 0...<10.
_elapsedS += deltaS;
// Compute current velocity based on exponential decay of initial
// velocity over the elapsed time (this causes the spinner to
// gradually slow down and mimics the effects of friction).
float currentVelocity = _velocity*pow(_decay, _elapsedS);
// Now move the position based on the current velocity.
_position += currentVelocity*deltaS;
// Finally make sure position is constrained within 0...<10 range.
_position = fmod(_position, 10.0);
if (_position < 0.0) {
// Ensure position is never negative by wrapping back to the
// same pixel position in a positive location.
_position += 10.0;
}
return _position;
}
private:
float _position;
float _velocity;
float _elapsedS;
float _decay;
};
#endif