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
57 lines
2.2 KiB
5 years ago
|
// 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
|