Как плавно изменять целое число в течение некоторого времени от одного значения до другого?

Есть цвет, который задан целым значением в расширенном формате HEX с альфа каналом (HEXA).
Например, 0x12ABCDFF. Тут альфа канал = 0xFF, т. е. без прозрачности.
Нужно написать функцию с таким прототипом:
void fadeColor(int &hexa, int duration, bool in = false);
Суть ее работы:
Принимается сам цвет (вернее адрес переменной, где он хранится), прозрачность которого (альфа канал) должна измениться за время duration (в мс) либо с текущего значения (берется из hexa) до 0xFF (тогда аргумент in == true, что означает fade in - плавное появление), либо с текущего значения до 0x00 (аргумент in == false, что означает fade out - плавное исчезновение)
Вот псевдокод того, что я написал:
void fadeColor(int &hexa, int duration, bool in = false)
{
    int from = hexa; // начальное значение цвета
    int to = (in) ? (from | 0xFF) : (from - (from & 0xFF)); // конеченое значение цвета
    // у конечного значения альфа меняется либо на 00 либо на FF в зависимости от in.
    int update_rate = (to - from)/duration; // шаг изменения цвета за 1 мс

    SetTimer("_onColorFade", 1, "ddd", from, to, update_rate); // внизу объясню, что это за функция
}

void _onColorFade(int &from, int to, int update_rate)
{
    from += update_rate; // меняем цвет

    if (from == to) // если дошли до конечного цвета, то останавливаемся
        return;
    // иначе продолжаем менять цвет
    SetTimer("_onColorFade", 1, "ddd", from, to, update_rate); // снова запускаем 
}


Функция SetTimer:
1-й аргумент это функция, которая будет вызвана через время в мс, указанное во 2-м аргументе (1 раз), дальше идут параметры, передаваемые этой функции с указанием их формата.

Оказалось, что функция работает неверно, т. к. update_rate (шаг изменения цвета за 1 мс) может оказаться дробным числом, которое впоследствии обрезается и в итоге алгоритм неправильно работает. А цвета задаются только целым числом.

Короче говоря, задача такая:
плавно уменьшать число с 255 до 0 за указанное время, либо плавно увеличивать число с 0 до 255 за указанное время в миллисекундах (допустимы только целые промежуточные значения!)
Есть ли какой-то готовый алгоритм для решения такой задачи?
  • Вопрос задан
  • 398 просмотров
Пригласить эксперта
Ответы на вопрос 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Считайте во float и округляйте перед выдачей результата.

Или считайте по формуле ans = from + (to-from+0.0)*time/duration
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы