HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Cosine function period

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
functionperiodcosine

Problem

I'm using the cosine function in C++ to simulate flashing for a sprite in my game. The method looks like this:

(anything in the sf namespace is part of the SFML graphics library)

void Player::update(const float& deltaTime)
{
    mAccumulatedTime += deltaTime;
    float opacity = abs(cosf(5*mAccumulatedTime)) * 255;
    static int numFlashes = 0;
    if (opacity == 255) {
        cout << ++numFlashes << endl;
    }
    mSprite.setFillColor(sf::Color(255, 255, 255, opacity));
}


So every time opacity is equal to 255 (basically the passing of one full period), numFlashes should be incremented. The problem is, cos() isn't perfect, meaning it doesn't exactly reach 1 and 0, so the if condition is rarely met. If I use rough checking like if (opacity > 255*0.9999), then numFlashes becomes really high, really fast.

Does anyone know a way to accurately check when a full period has passed? Or is that just not possible?

Solution

One may use the following closed formula to compute numFlashes:

numFlashes = 5 * mAccumulatedTime / pi.


This follows from the fact that the period of the function abs(cos(x)) is pi and, if an oscillating function in variable x has a period T, then the number of oscillations, n, is given by the formula:

n = x / T.


Thus, your function definition may be corrected, and even simplified, as follows:

const float PI = acosf(-1);

void Player::update(const float& deltaTime)
{
    mAccumulatedTime += deltaTime;
    float opacity = abs(cosf(5*mAccumulatedTime)) * 255;
    int numFlashes = 5 * mAccumulatedTime / PI;
    cout << numFlashes << endl;
    mSprite.setFillColor(sf::Color(255, 255, 255, opacity));
}

Code Snippets

numFlashes = 5 * mAccumulatedTime / pi.
const float PI = acosf(-1);

void Player::update(const float& deltaTime)
{
    mAccumulatedTime += deltaTime;
    float opacity = abs(cosf(5*mAccumulatedTime)) * 255;
    int numFlashes = 5 * mAccumulatedTime / PI;
    cout << numFlashes << endl;
    mSprite.setFillColor(sf::Color(255, 255, 255, opacity));
}

Context

StackExchange Code Review Q#14183, answer score: 6

Revisions (0)

No revisions yet.