Исходник Пульсация цвета C++

rraggerr

проверенный какой-то
Автор темы
1,626
846
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Добавляете в любое место в вашем коде

C++:
   static void Pulsate( float &clr , float min , float max , float pulsate_speed )
   {
       static bool state = false;

       if( !state )
       {
           if( clr < max )
               clr += pulsate_speed;
           else
           {
               clr = max; state = !state;
           };
       }
       else
       {
           if( clr > min )
               clr -= pulsate_speed;
           else
           {
               clr = min; state = !state;
           };
       };
   };

и используете так:

C++:
 static float PlusateBlue = 255.0f;
        /*Color:: - это если пихаете в класс Color как и я */Pulsate( PlusateBlue/* переменная */, 100.f/*минимальное*/ , 255.f/*максимальное значение*/ , 1.f/*скорость*/ );

Вот как это выглядит на примере ImGui (лок на фпс включен)
p.s это самый простой метод пульсации, можно сделать лучше через HSB
 
Последнее редактирование:
  • Нравится
Реакции: atizoff и IZDATXXX

rraggerr

проверенный какой-то
Автор темы
1,626
846
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.

rraggerr

проверенный какой-то
Автор темы
1,626
846
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.

iAmerican

Известный
Друг
615
257
Более точно будет сказать переливание цвета, пульсация эт другое.
 

Losyash1337

Новичок
16
16
Я все понимаю что тебя это не волнует, но извини, это полнейший бред, а не код.
Тебе достаточно допустим:
C++:
bool mState = false;
mState ? (mColor += fSpeed) : (mColor -= fSpeed);
if(mColor == cMax || mColor == cMin) mState = !mState;

А потом жалуются люди, что у них не работает ничего :)
У float всегда погрешность будет в этом случае (и почти во всех остальных), если не можете осознать этот факт, то прошу уйти читать IEEE 754 (перевод). Кстати, реализация не самая длинная, как может показаться, вот, например, другая, более универсальная (и прожорливая):
C++:
#include <vector>
#include <Windows.h>
#include <cassert>

// ...

struct ColorState {
    uint8_t r, g, b;
    double duration;

    ColorState() { }
    ColorState(uint8_t r, uint8_t g, uint8_t b, double duration)
        : r(r), g(g), b(b), duration(duration) {
        assert(duration > 0.0);
    }
};


class ColorController {
public:
    ColorController(const std::vector<ColorState>& data) :
        m_data(data), m_state(0U), m_time(0.0), m_cycle(0.0) {

        for(const auto& x : m_data)
            m_cycle += x.duration;
    }

    void update(double delta) {
        m_time += delta;

#define _CC_NEXT_STATE(x) (((x)+1U)%m_data.size())

        while(m_time >= m_data[m_state].duration) {
            m_time -= m_data[m_state].duration;
            m_state = _CC_NEXT_STATE(m_state);
        }

        const auto& cur = m_data[m_state];
        const auto& nxt = m_data[_CC_NEXT_STATE(m_state)];
        const double t1 = m_time, t2 = cur.duration-m_time;

#undef _CC_NEXT_STATE

        m_r = static_cast<uint8_t>((t2*cur.r + t1*nxt.r) / cur.duration);
        m_g = static_cast<uint8_t>((t2*cur.g + t1*nxt.g) / cur.duration);
        m_b = static_cast<uint8_t>((t2*cur.b + t1*nxt.b) / cur.duration);
    }

    uint8_t get_r() const { return m_r; }
    uint8_t get_g() const { return m_g; }
    uint8_t get_b() const { return m_b; }

    COLORREF get_color() const {
        return RGB(m_r, m_g, m_b);
    }

private:
    size_t m_state;
    double m_time, m_cycle;
    uint8_t m_r, m_g, m_b;
    std::vector<ColorState> m_data;
};

использование:
C++:
// инициализация в отдельной функции (чтобы не засорять код в месте использования)
ColorController create_my_cc() {
    std::vector<ColorState> data(6);
    data[0] = ColorState(255, 0, 0, 0.5);
    data[1] = ColorState(0, 0, 0, 0.3);
    data[2] = ColorState(0, 255, 0, 0.5);
    data[3] = ColorState(0, 0, 0, 0.3);
    data[4] = ColorState(0, 0, 255, 0.5);
    data[5] = ColorState(0, 0, 0, 0.3);
    return ColorController(data);
}

// инициализация на месте (производится один раз!)
auto my_cc = create_my_cc();

// использование
my_cc.update(dt);
COLORREF color = my_cc.get_color()
 
  • Нравится
Реакции: atizoff и iAmerican

deropleat

Известный
105
56
А потом жалуются люди, что у них не работает ничего :)
У float всегда погрешность будет в этом случае (и почти во всех остальных), если не можете осознать этот факт, то прошу уйти читать IEEE 754 (перевод). Кстати, реализация не самая длинная, как может показаться, вот, например, другая, более универсальная (и прожорливая):
C++:
#include <vector>
#include <Windows.h>
#include <cassert>

// ...

struct ColorState {
    uint8_t r, g, b;
    double duration;

    ColorState() { }
    ColorState(uint8_t r, uint8_t g, uint8_t b, double duration)
        : r(r), g(g), b(b), duration(duration) {
        assert(duration > 0.0);
    }
};


class ColorController {
public:
    ColorController(const std::vector<ColorState>& data) :
        m_data(data), m_state(0U), m_time(0.0), m_cycle(0.0) {

        for(const auto& x : m_data)
            m_cycle += x.duration;
    }

    void update(double delta) {
        m_time += delta;

#define _CC_NEXT_STATE(x) (((x)+1U)%m_data.size())

        while(m_time >= m_data[m_state].duration) {
            m_time -= m_data[m_state].duration;
            m_state = _CC_NEXT_STATE(m_state);
        }

        const auto& cur = m_data[m_state];
        const auto& nxt = m_data[_CC_NEXT_STATE(m_state)];
        const double t1 = m_time, t2 = cur.duration-m_time;

#undef _CC_NEXT_STATE

        m_r = static_cast<uint8_t>((t2*cur.r + t1*nxt.r) / cur.duration);
        m_g = static_cast<uint8_t>((t2*cur.g + t1*nxt.g) / cur.duration);
        m_b = static_cast<uint8_t>((t2*cur.b + t1*nxt.b) / cur.duration);
    }

    uint8_t get_r() const { return m_r; }
    uint8_t get_g() const { return m_g; }
    uint8_t get_b() const { return m_b; }

    COLORREF get_color() const {
        return RGB(m_r, m_g, m_b);
    }

private:
    size_t m_state;
    double m_time, m_cycle;
    uint8_t m_r, m_g, m_b;
    std::vector<ColorState> m_data;
};

использование:
C++:
// инициализация в отдельной функции (чтобы не засорять код в месте использования)
ColorController create_my_cc() {
    std::vector<ColorState> data(6);
    data[0] = ColorState(255, 0, 0, 0.5);
    data[1] = ColorState(0, 0, 0, 0.3);
    data[2] = ColorState(0, 255, 0, 0.5);
    data[3] = ColorState(0, 0, 0, 0.3);
    data[4] = ColorState(0, 0, 255, 0.5);
    data[5] = ColorState(0, 0, 0, 0.3);
    return ColorController(data);
}

// инициализация на месте (производится один раз!)
auto my_cc = create_my_cc();

// использование
my_cc.update(dt);
COLORREF color = my_cc.get_color()
Дружочек, вопрос к тебе такой: почему ничего не работает? Где ты в моем коде нашел неработоспособный код? Прежде чем такие предъявы кидать, ты придерись к чему-нибудь, а не кидайся чем попало.
 

rraggerr

проверенный какой-то
Автор темы
1,626
846
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Дружочек, вопрос к тебе такой: почему ничего не работает? Где ты в моем коде нашел неработоспособный код? Прежде чем такие предъявы кидать, ты придерись к чему-нибудь, а не кидайся чем попало.
Кстати да, он прав, у тебя ничего не работает
 

deropleat

Известный
105
56
Кстати да, он прав, у тебя ничего не работает
Возможно потому что вы кидаете эти строчки все в 1 функцию? Подразумевалось то, что bool mState - вне функции переменная. Естественно, если вы засунули в одну функцию, то у вас всегда будет выполняться mColor -= fSpeed.
 

Losyash1337

Новичок
16
16
Дружочек, вопрос к тебе такой: почему ничего не работает? Где ты в моем коде нашел неработоспособный код? Прежде чем такие предъявы кидать, ты придерись к чему-нибудь, а не кидайся чем попало.
Хорошо, теперь я вижу, что кое-кто не знает, что такое мат. часть. Объясняю, еще раз точные сравнения double, float, да хоть __float128 противопоказаны, т.к. при работе, с числами, которые нельзя представить точно в виде двоичной дроби (например 0.7, 2.19, 1e-5, M_PI и т.п.) ты сталкиваешься с такой вещью, как погрешность, которая мешает тебе сказать, что 0.3+0.6==0.9 (можешь проверить, результат неожиданный, правда?). Вывод такой: слушай оппонента, и не ссылайся на глупость окружающих, неординарный ты мой. А код можно было сделать примерно таким:
C++:
static bool mState = false;
mState ? (mColor += fSpeed) : (mColor -= fSpeed);
if(mColor >= cMax) mState = false, mColor = cMax;
if(mColor <= cMin) mState = true,  mColor = cMin;

P.S.: именно это и написал автор топика.