помогите с функцией сдвига массива
- Войдите на сайт для отправки комментариев
Нарыл код для циклического сдвига массива. То есть было 1-2-3-4, сдвинули на единицу, получили 4-1-2-3
Программер из меня паршивый. Накидал для проверки такой вот код:
int shiftingArray[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int sizeOfArray = 10; int shiftingPoint = 1; void shiftk(int *shiftingArray, int n, int k) { if (n <= 1) // Degenerated case return; // Reduce k to the interval 0..n-1 // using the periodicity k %= n; if (k == 0) return; if (k < 0) // Shift to the left on k k += n; // == shift to the right on n-k int i = 0; // Index of the first element of orbit int nod = gcd(n, k); while (i < nod) { // Loop for each orbit // i is the first element of orbit int j = i - k; // j is the last element of orbit if (j < 0) j += n; int x = shiftingArray[j]; // Save the value of the last element of orbit while (j != i) { // Loop for each element j of orbit int l = j - k; // l is the previous element to j if (l < 0) l += n; shiftingArray[j] = shiftingArray[l]; // copy previous element to current j = l; // go to the previous element } shiftingArray[i] = x; // copy the last element of orbit to the first ++i; // go to the next orbit } } int gcd(int x, int y) { while (y != 0) { int r = x % y; x = y; y = r; } return x; } void setup() { Serial.begin(115200); } void loop() { int r = random(-9, 9); shiftk(shiftingArray, 10, r); for (int z = 0; z < 10; z++) { Serial.print(shiftingArray[z]); Serial.print(", "); } Serial.print(" shift by: "); Serial.println(r); delay(1200); for (int k = 0; k < 10; k++) { //return to basic order shiftingArray[k] = k + 1; } }
Коротко - задаем массив значений подряд, от 1 до 10-ти. Потом сдвигаем его на рандомное количество шагов либо влево, либо - вправо. Ну и серем в ком-порт сдвинутым массивом и значением сдвига.
Все работает! Вывод идет как надо:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, shift by: 0 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, shift by: -3 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, shift by: 8 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, shift by: -6 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, shift by: 4 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, shift by: 7 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, shift by: 5 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, shift by: 1 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, shift by: -8 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, shift by: 3 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, shift by: 3 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, shift by: 4 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, shift by: 7 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, shift by: -1
Далее, я вставляю эту функцию в довольно хитрый проект и там оно не пашет. Собственно, дело не том проекте, для начала я хочу уточнить - что за вот та звездочка перед массивом при вызове shiftk?
void shiftk(int *shiftingArray, int n, int k) {
Я не совсем понимаю указатели и прочие высокие вещи. Могут ли быть грабли из-за этого принципа ссылочности на массив (или как там это правильно сказать)? - вот в чем вопрос!
Можно ли как-то переделать функцию сдвига, может быть явно задавать массив ей? Ну, типа чтобы проще было.
В проекте, в котором я использую эту функцию, там сильно мудреные процедуры. Хочу попробовать, мож при ином обращении к массиву для шевеления - оно заработает и в том проекте )
Сам алгоритм сдвига - отсюда, лекция 6
а что касается сдвига массива - значительно проще не двигать элементы в массиве, а трактовать его как кольцевой буфер и двигать указатель на начало буфера
кольцевой буфер для меня - более страшно, чем указатели )
А есть пример простой, для дошкольников? )
а без указателей - никак?
Ну, почему никак? Можно индексами.
пытался прямо скормить массив, но компилятор обызвается (
Как его обмануть? (добвить себе ума - не предлагать, то моветон )) )
Правильный: самый простой и самый быстрый вариант Вам предложили - кольцевой буфер.
Там дело в следующем: используется FastLED. В loop идет непрерывная функция засветки ленты. Процедуры там себе чего-то считают, шевелят цветом и яркостью, а она - постоянно выводит что имеется (насколько я понимаю).
Я пробовал вызывать сдвиг непрерывно, рядом с FastLED.show - на ленте ахинея по итогу.
Щас сделал сдвиг каждые shiftEvery-секунд:
И хоть я задаю shiftEvery единицей, хоть сотней (динамически есть возможность), то на ленте все равно ахинея.
Сама процедура, которая использует массив, насколько я понимаю, она ведь сначала нагенерит чего ей положено и после должен идти сдвиг.
Если во время сдвига ахинея на ленте случается из-за постоянного вызова функции вывода на ленту имеющихся значений, то по идее, при значении времени сдвига в 10 секунд - я должен хотя бы несколько секунд наблюдать нормальную анимацию, но этого не происходит.
Непойму из-за чего этот сыр-бор.
Массив объявлен перед всеми функциями, я так понимаю виден отовсюду. Мож из-за этого беда?
upd: про кольцевой буфер - загуглю. Кстати, а для ардуино-подобных контроллеров вот эта функция сдвига она быстрая? В принципе, скажем для массива из сотни-другой элементов? Или "относительно медленная"?
кольцевой буфер для меня - более страшно, чем указатели )
А есть пример простой, для дошкольников? )
Пример для дошкольников
Есть массив с десятью элементами от 0 до 9. Начало этого массива, очевидно - элемент 0
Потом вам приходит команда "подвиньте массив влево на 3 позиции". - Но вы хитрый, вы ничего не двигаете. Вы просто запоминаете -теперь у меня начало массива на позиции 3. И когда вам придет команда "выдайте нам массив на печать" - вы напечатаете массив, как он есть, без копирований элементов - только начнете не с элемента 0, а с элемента 3. Потом 4, 5. 6... Главное - отслеживать конец массива. Как дошли до последнего элемента - перешли к нулевому и продолжаете, пока не напечатаете все 10.
Понятно?
upd: про кольцевой буфер - загуглю. Кстати, а для ардуино-подобных контроллеров вот эта функция сдвига она быстрая? В принципе, скажем для массива из сотни-другой элементов? Или "относительно медленная"?
сделайте буфер как я написал выше - там вообще ничего двигать не надо. Причем сдвиг что на 1 позицию, что на 100 - занимает одинаковое (ничтожное) время. Копированием элементов массивы никто не двигает...
Я для фастледа обычный memmove использовал, как помню. Безо всяких монстроидальных функций Переставлять ничего. мне не нужно было, но для цикличного сдвига на позицию достаточно затираемый элемент сохранить, а потом засунуть его в противоположный конец.
А грабли вы себе, скорее всего, находите потому что в фастледе цвет задается не int-ом, соответсвенно - сдвигаете с нарушением разрядности числа. Сделайте сдвиг на 2, к примеру.
UPD: со сдвигом на 2 тоже не выйдет, там массив трехбайтовых структур используется.
Как дошли до последнего элемента - перешли к нулевому и продолжаете, пока не напечатаете все 10.
Понятно?
понятно-то понятно! Но был бы я кодером.... Ладно, то уже маловажно!
Суть в том, что я пока что лишь приобщаюсь к коду. Я беру готовый проект и пытаюсь его слегка поменять. Оттуда кусочек сюда - и мне радость )
Я не все процедуры понимаю до конца. Плюс не имею опыта работы с буферами этими. Так что мне проще заставить готовый код обращаться к массиву (а порою они уже и без того работают с массивом), и после уже могу спокойно вертеть буфером, получая желанный сдвиг.
По сути - я хочу двигать анимацию по ленте. Мне че-то показалось, что без этих всех дополнительный "что-если", оно будет работать шустрее, и код не будет такой загроможденный.
А в идеале - зеркалить! Причем с задаваемыми мною параметрами точки зеркалирования. А может и анимации ойной. Причем чтобы можно было отключать! Сейчас на всю ленту бегаем, а таперча зеркалим от центра, а вот зеркалим к центру... При этом процедура анимации - одна, я просто ее использую в разных позах. А в противном случае - придется дублировать процедуру, изменяя ее поведение. Лишаемся гибкости, уменьшаем вариации, плодим дополнительные хоть и миллиграммы, но лишних байтов )
Беру готовую процедуру и говорю - ты, милая, считай на половинку ленты! Она себе считает! А я беру, и просто копирую каждый кадр на вторую половинку ленты, да еще и отзеркалив. А могу и не зеркалить, и не на половинку, а на всю! Да еще и когда захочу или в зависимости от погоды на Марсе!
Да, беда в моей голове, я знаю. Думал мож кто подскажет как можно иначе пользоваться вот тем сдвигом, или какие-то грабли бы выяснил.
в фастледе цвет задается не int-ом, соответсвенно - сдвигаете с нарушением разрядности числа.
та я и юинты пробовал ) Спасибо, камрад! Первым делом я его CRGB, конечно, пытался пошевелить. Но там засада сразу!
Потом понял, что в лучшем случае могу шевелить координатами, за которым в свою очередь буду отправлять процедуры засветки.
Но и тут - облом вышел (
кстати, если чо - со мной можно на "ты". То вас - много, а я bool (еще и false, похоже :D )
Или я чего не понимаю, или - тривиальный linked list, реализация на С++ гуглится минут за пять. И не надо ничего никуда двигать - просто перемещай указатель чтения туда-сюда на сколько нужно позиций, и всё.
Вобщем, той функцией, что в первом сообщении двигать только массивы 2-байтных чисел можно. Для фастледа ее или переписывать под CRGB или на memmove заменить.
Фастлед со списками не работает, у него массив из структур применяется для задания цветов пикселей. На show() он тупо выстреливает его битстримом в страйп и был таков.
Просто человек решил применить методику из интернетов без учета специфики используемой библиотеки.
подумалось, а как быстро оно мне массив сдвинет? Можете подсказать кто-нибудь!
Судя по ТТХ алгоритма, оно занимает
т.е. всего число операций копирования равняется длине массива плюс число орбит:
num = n + gcd(n, k)
В частности, если числа n и k взаимно просты, то число копирований равно n+1
А сколько это циклов процессора или как там правильно сказать это займет, допустим для массива в сотню элементов и сдвигом на единичку (раз в секунду)? Моя лента работает на 800КГц. А сколько примерно от этого отожрет сдвиг массива? Хоть примерно?
На ESP встроенная функция подсчета fps для анимации показывает ~200. То есть 200 кадров она генерит примерно. Понятное дело, что это не совсем правильно соотносить частоту работы микрух в диодах и кадры, да еще и со сдвигом, но в целом - сильно много оно отжирает процессорного времени?
Фастлед со списками не работает...
Просто человек решил применить методику из интернетов без учета специфики используемой библиотеки.
несовсем верно! Я его решил применить в специфическом ракурсе. Я не встроенные массивы шевелю, а координаты.
вот берем известную готовую процедурку:
Которая использует заранее заданные координаты из массива:
И я (теоретически, по факу тут нет смысла) могу сдвигать эту анимацию по ленте.
Это не самый лучший пример! Я лишь показать вариант применимости. Я пробовал на примере процедуры огня. Хотел, чтобы он у меня бродил по ленте. Там ведь начало светится постоянно, а "языки" пламени наверху - периодически. И если бы двигать его по ленте, которую свернуть в кольцо - должно бы выглядеть неплохо! Но, ума не хватает, сдвиг массива координат не пашет как надо, а буферы и мемсеты - то для меня сильно мудро.
Ладно, благодарю за помощь, камрады ;)
Оно - это что? А вообще - в ардуине есть micros(). Запомнил текущее значение, цикл из тыщи функций копирования прокрутил, вычел из конечного времени начальное и поделил на кол-во циклов. Результат - в Serial вывел. Вот и будет самая, что ни на есть правдивая информация о быстродействии.
Одно скажу - на елку хватает мощи у 328-го МК для 50-60 фпс вместе с IR-управлением.
В модифицированной известной процедуре проще random применять, как мне кажется - эффект тот же ;)
А сколько это циклов процессора или как там правильно сказать это займет, допустим для массива в сотню элементов и сдвигом на единичку (раз в секунду)?
В грубой оценке - десяток тактов на байт. При 16МГц считайте грубо 1мксек на байт. Итого сотня мксек плюс/минус лапоть разумеется
Моя лента работает на 800КГц. А сколько примерно от этого отожрет сдвиг массива? Хоть примерно?
800- это выпихивание данных в ленту, как выпихнули - пауза, тогда и сдвигайте и ниче не отожрет. Но вобщем циклически оно конечно лучше.
на елку хватает мощи у 328-го МК для 50-60 фпс
та то я в курсе! ) копирование это - сильно тугое или нет? Вон, уже ответили, спасибо! Вроде не сильно тупое, раз в секунду для анимаций типа "пускать сопли из точки" - юзать можно! Как сопля приземлилась - двигаем!
Надо грызть гранит дальше! А зубки-то уже не те! Об фотошопы с иллюстраторами и прочей прикладнючестью всё пообламал. Тогда с полуслова понимал, сейчас с этим программированием - ниче не задерживается (
Но кой-чего таки впитал!
как выпихнули - пауза
а как узнать что оно невыпихует? на FastLED'е реально? или там хитрые обработчики писать нужно?
В модифицированной известной процедуре проще random применять, как мне кажется - эффект тот же ;)
та то ж код не рабочий, а абы-було! Я скопипастил, да выкинул побольше лишнего, чтобы экран не загромождать читающим. Это я проект один мучал, а там своя математика филотаксиса. И координаты проще просчитать заранее и задать в массиве, чем вычислять налету!
https://www.youtube.com/watch?v=PDc_siO9afY вот он! много крови попил, но я раздуплил как он координаты считал и сделал на 200 диодов)) (могу и больше, но оно и 200- оверпрайс вышел)
Знатная гипножаба.
Про обработчики непонятно - что имеется в виду? Считайте, что МК однозадачный - или готовит данные или посылает. Чем быстрее готовит, тем чаще посылает. Отседа и FPS. И узнавать там про отправку нечего - пока все не уйдет, новая сцена считаться не начнет.
И узнавать там про отправку нечего - пока все не уйдет, новая сцена считаться не начнет.
вот про эту отправку и хотел уточнить )
Я думал, что оно постоянно передает. Понятное дело, что там нет мультизадачности, но в целом, мол параллельно почти идет расчет процедур и вывода на ленту.
А Вы не в курсе, FastLED.show там флагов никаких не поднимает, мол "порция ленте скормлена, жду добавки"?
Можно как-то снаружи увидеть, что оно закончило ленту дергать и решило передохнуть, чтобы в этот момент заняться своими черными делами? Вплоть до того, чтобы заставить его подождать. Хотя там окошко мизерное, но для общего развития интересно )
А Вы не в курсе, FastLED.show там флагов никаких не поднимает, мол "порция ленте скормлена, жду добавки"?
Чой-то сходу ничего подобного не видно:
вот про эту отправку и хотел уточнить )
Я думал, что оно постоянно передает. Понятное дело, что там нет мультизадачности, но в целом, мол параллельно почти идет расчет процедур и вывода на ленту.
Передает всё сразу, когда вызовут. Никаких вычислений, пока из функции не вернется управление, МК делать не будет. Ритмичность вызова show() определяете самостоятельно в соответствии со сценой. Если на елке огоньки бегут со сдвигом на позицию раз в секунду - вызываете show() раз в секунду, чаще смысла нет никакого. В перерывах можно майнить.
вызываете show() раз в секунду, чаще смысла нет никакого. В перерывах можно майнить.
ну сколько проектов я перечитал на этой либе (а из годных, наверно все и еще трошечки) и сколько перепробовал, то будь там вызов FastLED.show в самой процедуре анимации, или в loop, то разницы особо нема.
Мож канеш из-за моих слабых пониманий процессов я не так понимаю, но судя по своему опыту, разницы особо нет.
Вот та "гипножаба": там вывод на ленту идет в лупе ну и прочий перебор анимаций, палитр и прочего. Так вот, на сотне диодов на ESP оно давало ~210 fps, а когда расширил до двух сотен, то фпс упал вдвое. Это не отразилось на отображении анимаций. Ну, на визуальном восприятии. Так что если оно чрезмерно много фпс генерит, то это не особо страшно.
Кстати, я настолько непонимаю как работает контроллер, что для меня остается загадкой как это одни и те же процедуры одинаково отображаются что на ардуине, что на более шустром ЕСП. Совпадение? Ну, то есть ЕСП там еще и нутрянокй управляет и остается почти как в голой ардуине под пользу?
ФПС больше, а скорость анимации на вид - почти одинаковая. Вот щас задумался ) Вроде должны метеорчики во много раз быстрее бегать, ан-нет! Молодец Крейгсман, годную либу запилил )
upd: майнить нельзя, это подрывает обороноспособость страны! ))
Никаких вычислений, пока из функции не вернется управление, МК делать не будет.
правильно ли я понимаю, что если: у меня вывод на ленту идет в луп. Если я этот вывод на ленту запилю в отдельную процедуру, оставив в лупе на том месте вызов той самой отдельной процедуры, то после вывода на ленту я могу двигать массив, и это не отобразится во время сдвига на ленте никак?
Или каким образом можно гарантировано что-то делать, чтобы это действие не пришлось на момент вывода на ленту? Вызывать FaslLED.show в отдельной процедуре, и после него в той же процедуре творить свои делишки?
Еще раз: МК - однозадачный. Если идет вывод на страйп - ничего более из пользовательского кода гарантированно не исполняется. Как только вывод закончен и управление передано обратно из функции show() - можете крутить CRGB-массивом, как хотите и в течении любого времени. Трансформировали его под новую сцену - вызвали show(), которая зашлет в контроллеры пикселей новые цвета.
Вызывать show() можете в любой процедуре - хоть в лупе, хоть в сетапе, хоть в superEffect(). Задача этой функции - выкинуть в страйп данные. Перемешиваете несколько раз CRGB-массив, но не вызываете show() - картинка не обновляется. Вызвали - на ленту ушла последняя модификация.
Смысла лупить в страйп избыточный FPS нет никакого. Чем быстрее ваша функция модифицирует массив - тем больший потенциальный FPS можете получить, сразу вызывая за ней show(). Но нужен ли FPS 200, если вы не пчела - вопрос философский.
Но нужен ли FPS 200, если вы не пчела - вопрос философский.
нужен! А чего ж не нужен, если он есть. В луп его засадил, и пусть работает!
А ты знай себе - пиши процедуры засветки!
А вот вдруг я беру, и даю внешнюю команду сменить процедуру! То ж пока не прорисует - не поймет! А в лупе когда, то он на ленту выдал, и тут же оглядывается, а что же там нам кнопочки говорят? А не давил ли их какой-то эникейщик, а не желает ли он чего-то новенького лицезреть? И тут же хоп, и обработал кнопочку, да поменял процедурку.
Не для спору пишу. Просто так уже заведено. Не изменять же специально! Но Ваше пояснение мне добавило экспириентса, честно! теперь я более четко понимаю вывод, более уверен в нем! Спасибо Вам и всем, всем, всем!
Если позволите, камрады, то чтобы не плодить новые темы - объясните, пожалуйста, о битовых сдвигах!
Вот процедура:
В ней идет деление на три куска и кускам назначается цвет!
Можно ли тут задать 4 или 5 кусков и как делать сдвиг на другие значения?
Я выделил строки, которые мне крайне непонятны. Читал про битовый сдвиг, но не особо понял. Мож у кого есть годная ссылка, где объяснено поближе к этому примеру, чтобы понятней было? Притом сдвиг вроде делают как >> или <<, а тут логическим И, да еще и сдвигают десятичное - двоичным. Нипанятна!
Спасибо! не сочтите за офтоп.
В данном случае битовый сдвиг тут не центр идеи. Признаюсь честно - я в цветовых пространствах ориентируюсь плохо, но тут суть, похоже, такая:
Берется некий индекс "жары" и для него вычисляется цвет, соответствующий ощущению температуры. Например - для высокого уровня жары берется full red + full green (кстати, индексы в структуре под другую цветовую модель - в моем фастледе они соответствуют комментариям), что дает full yellow. Потом, через подмешивание blue цвет начинает выводится в full white. Т.е. на максимальном жаре сформируется белый цвет. Сдвигом тут реализовано "усиление" цвета вчетверо, т.е. с 63 он увеличивается до 252, что дает full blue и, при последующем подмесе, - full white. Остальные варианты смешивают цвета как-то иначе. Тут я не копенгаген. Здесь есть картинки со спектрумом, может они пояснят принцип: https://github.com/FastLED/FastLED/wiki/Pixel-reference
Разбиение же устроено следующим образом:
1) N = 0..255 масштабируется к N = 0..191, потому что 192 делится на три без остатка, т.е. удобно три группы разбиения сформировать
2) N & 63 => B00111111 - этот фокус мне непонятен
3) Положим, что N вышло 63, 63 * 4 = 252 => B00111111 << 2 => B11111100 - усиливаем один раз, чтобы не делать это в каждой ветке if-а
4) 252 & 0x80 => B11111100 & B10000000 => B10000000 - максимальный жар
5) 252 & 0x40 => B11111100 & B01000000 => B01000000 - средний жар
6) остальные варианты - малый жар
объясните, пожалуйста, о битовых сдвигах!
...
Я выделил строки, которые мне крайне непонятны.
Из четырех выделенных строк три не имеют к битовым сдвигам никакого отношения.
Чтобы понять, что такое сдвиг, возьмите бумагу в клеточку и выделите в ней колонку шириной 8 клеточек.
Возьмите какое-либо число, запишите его в клеточки внутри колонки в двоичном виде.
Теперь, допустим, нужно сделать сдвиг влево на 3. Тогда берем и все нули-единички переписываем тремя клеточками левее. То, что выходит за пределы колонки - обрезаем, а пустые клеточки справа заполняем нулями.
Вообще, логический сдвиг влево эквивалентен операции умножения на степень двойки. Т.е. сдвиг на 1 эквивалентен умножению на 2^1, сдвиг на 2 эквивалентен умножению на 2^2, на 3 - умножению на 2^3 и т.д. Разумеется, с потерей разрядов, выходящих за пределы разрядности числа.
sadman41, кажись я понял твой ник: многие знания - многие печали, да? ))
Пасиб! четко рассказал!
Как я понял из буржуйских пояснений, этот хётмап - что-то типа индекса цвета в инфракрасном изображении. Ну как на видео, когда чучмеков по пустыням гоняют с вертолетов. Там, канеш, градации серого, но в кино прикрашают цветным.
Далее, фастлед умеет интерполировать промежутки! Задаем : начало - белый, середина - синий, конец - красный. И фастлед автоматом нам сгенерирует градиент от белого в синий и после в красный.
Мне, собственно, нужно сделать хётмап, но не для красного, а для синего. Попробовал тупо объявить последовательность при инициализации не GRB (как у 2812), a BGR. Если в картинке огня переназначить таким образом цвета - я получаю примерно то, что мне нужно.
Но, даже при дефолтных значениях в "жарких" местах я наблюдаю явный зеленый. А он - лишний. Вот и решил процедуру переделать на переменные и через вэбморду крутить переменные, подбирая нужные значения для получения необходимого результата.
Переменные я сделать умею, но не могу понять принцип работы. Вообще, этот кусок кода из огонька для древней версии фастледа. Это после они вшили heatmap в библиотеку. А это я нарыл отдельную процедуру для препарации. Но там все оказалось сложнее, чем я предполагал.
Ладно, что ж, попробую это победить )
Спасибо, ребята, за разъяснения. Стало чуть понятнее колдовство!
Из четырех выделенных строк три не имеют к битовым сдвигам никакого отношения.
А Вы ждали, чтобы малограмотный человек четко обозначил Вам "диагноз" своих непоняток?
Ну да, не сдвиг, а булева алгебра. А может и еще что-то такое. Я для того и спрашиваю, что не совсем понятно что там за шаманство!
Спасибо за потраченное время, не обессудьте, я признателен за Ваши пояснения. Но от них мало проку. sadman41 понял о чем речь и пояснил более полезно! Мне и без сдвигов нужно в голову многое накласть, боюсь даже устану сильно, а тут еще и Ваша наука ))
Мне, собственно, нужно сделать хётмап, но не для красного, а для синего. Попробовал тупо объявить последовательность при инициализации не GRB (как у 2812), a BGR. Если в картинке огня переназначить таким образом цвета - я получаю примерно то, что мне нужно.
Может Fire2012WithPalette что-то подскажет. В принципе - тоже на индекс "жары" повязано, только цвета из палитры берутся. Там уже математика не попортит картинку.
Некоторые вещи мне приходилось через CHSV делать, а потом его уже в CRGB гнать. Накладно (двойной объем данных держать), но профит есть - например повышение яркости/оттенка с черного до заданного делается элементарно. В CRGB устанешь вычисления проводить и, порой, артефакты на некоторых оттенках всё равно проскакивают.
Может Fire2012WithPalette что-то подскажет.
та я его уже примудрил )) даже нашел способ как вот те Gradient Color Palette засунуть и использовать в виде простого CRGBPalette16.
Даже цветовые профиля прикрутил на всякий случай )) Могу в любое время поставить галогенку, флуорисцентку или еще какой-то цветовой профиль из 20-ти имеющихся. Оно ж когда коту делать нечего - он яйцы лижет! А я прикручую всякий мотлох, который в состоянии прикрутить, а вдруг чего полезного с него выйдет )
Если бы палитры можно было бы динамически изменять, чтобы наблюдать результат, то это было бы здорово. Там я бы себе быстро подобрал бы. Но я не могу так сделать, поэтому через костыльки подбираюсь к решению задачи )) Даже делал разные процедуры, чтобы можно было задать 4-хцветную палитру и динамически менять цвета на каждой позиции. Но в идеале еще и позицию самой позиции цвета нужно менять! Ну, то есть половина чтобы была не на 50%, а 40 или 60 например. А то уже для меня сложно! Хётмап этот - он же не просто как палитра, где цвет растянут на оттенки и оттенки выгребаются по координатам своим. Оно ж динамическое и выглядит замечательно! Вот под себя настрою и успокоюсь ) Пойду дальше чего-то расколупывать на сях этих ваших ))