Развивающийся флаг РФ на матрице ws2818

sasken
Offline
Зарегистрирован: 28.10.2015

Здравствуйте.

Пытаюсь нарисовать развивающийся флаг РФ на матрице 16х16 адресных диодов ws2818b.
Мысль пока такая: есть две функции синуса идентичные, только смещенные по высоте, перебираем каждый диод в матрице и если он ниже нижней синусоиды, то он красный, если между двумя синусами находится, то синий, ну и соответственно остальное все - белое.

отрисовываем это все, потом смещаем функцию синуса на определенное значение (в скетче это переменная ruru) и повторяем процедуру.
 

void loop() {
  ruflag();
  FastLED.show();
}

void ruflag() {
  for (byte x = 0; x < WIDTH; x++) {
    for (byte y = 0; y < HEIGHT; y++) {
      if ( y >= (byte)(sin(((x)/3)+(ruru/6))+11)){
        drawPixelXY(x, y, 0xFFFFFF);
      }else if( y >= (byte)(sin(((x)/3)+(ruru/6))+5)) {
      drawPixelXY(x, y, 0x0000FF);
      }
      else{
        drawPixelXY(x, y, 0xFF0000);
      }
    }
  }
  ruru=++;
  if (ruru>250) ruru=0;
}

но работает так коряво. а еще хотелось бы чтобы не четкая граница была, а размытая. понимаю, что тогда надо делать все цветовой моделе HSV, и между белым и синим  вопросов не возникает, тут плавный переход сделать реально. типа изменять "насыщенность" в зависимости от близости к синусоиде, но как это провернуть между красным и синим? там же хрень выйдет.

Буду рад любым подсказкам куда идти и в какое направление смотреть

b707
Offline
Зарегистрирован: 26.05.2017

по-моему вы в этой строчке

if ( y >= (byte)(sin(((x)/3)+(ruru/6))+11))

в скобках запутались

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Попёрло Вам с флагом. Попробовали бы американский или британский, да хоть китайский :-)

rkit
Offline
Зарегистрирован: 23.11.2016

 

Почитай как работает sin(), может быть. А потом еще посмотри на вариант этой функции из fastled.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

sasken пишет:

Здравствуйте.

Пытаюсь нарисовать развивающийся флаг РФ на матрице 16х16 адресных диодов ws2818b.
Мысль пока такая: есть две функции синуса идентичные, только смещенные по высоте,

Очень грубо. Смотреться будет неестественно. Флаг обычно изготавливают из слабо растягивающейся ткани. Следовательно, длина флага на картинке должна быть не постоянной, а "дышать" синхронно с изгибами порлотнища.

Цитата:

перебираем каждый диод в матрице и если он ниже нижней синусоиды, то он красный, если между двумя синусами находится, то синий, ну и соответственно остальное все - белое.

Очень грубо. Надо делать плавные переходя цвета.

Цитата:

а еще хотелось бы чтобы не четкая граница была, а размытая.

Вот-вот. О чем я говорил выше.

Цитата:

понимаю, что тогда надо делать все цветовой моделе HSV,

Неправильно понимаете.

Цитата:

и между белым и синим  вопросов не возникает, тут плавный переход сделать реально. типа изменять "насыщенность" в зависимости от близости к синусоиде, но как это провернуть между красным и синим? там же хрень выйдет.

Вот потому и "возникают вопросы", что пытаетесь притянуть за уши лишнюю сущность - цветовое пространство HSV. Делайте все в RGB и никаких вопросов возникать не будет.

sasken
Offline
Зарегистрирован: 28.10.2015

b707 пишет:
по-моему вы в этой строчке в скобках запутались

Да неее. тут лишние есть, потому, что я разные коэффициенты пробовал еще.

rkit пишет:
Почитай как работает sin(), может быть. А потом еще посмотри на вариант этой функции из fastled.

а я не правильно понимаю как работает функция синус? вроде  правильно, я в первом посте даже визуализировал эти две функции, пересечение вертикальных и горизонтальных линий - это координаты светодиодов в матрице. и я использую как раз библиотеку fastled. кучу эффектов вывел, просто флаг нарисовать не получается.

andriano пишет:
Очень грубо. Смотреться будет неестественно. Флаг обычно изготавливают из слабо растягивающейся ткани.

т.е. картинку размером 16х16 с изображением флага РФ с глубиной 24 бита - изначально провальная идея?

andriano пишет:
Делайте все в RGB и никаких вопросов возникать не будет

а как это реализовать в ргб?

Ок. Чтобы не переносить эту тему в "Ищу исполнителя", спрошу тут - а сколько стоит, что бы мне написали такой код? матрица 16х16 и флаг России типа "развивающийся".

sasken
Offline
Зарегистрирован: 28.10.2015

rkit пишет:
Ок. Ругаться не надо. Я не хотел вас обидеть. Функция синуса принимает значения от - 1 до 1. Плюс коэффициент "поднятия" функции от нуля. В чем я ошибаюсь? Укажите, пожалуйста, на ошибку. Или я ищу не там?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sasken пишет:
Функция синуса принимает значения от - 1 до 1. Плюс коэффициент "поднятия" функции от нуля.
Блиин! Это точно не опечатка? Вы действительно так считаете?

sasken
Offline
Зарегистрирован: 28.10.2015

ЕвгенийП пишет:
Вы действительно так считаете?

Ну в школе учили так.

Я не понимаю - это какой-то троллинг? мне что-то подсказывает, что мы говорим о разных вещах.

y = sin(x) может быть больше 1?

Ну и y=sin(x) +b, соответственно тоже самое, но выше на b.
Обьясните, пожалуйста, что в моих рассуждениях ошибочно.

nik182
Offline
Зарегистрирован: 04.05.2015

Ошибочно то что (byte)(sin(((x)/3)... больше чем на 1 конечный результат не изменит.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sasken пишет:

Я не понимаю - это какой-то троллинг?

Я тоже так думал, и только сейчас догадался, что, скорее всего

sasken пишет:

что мы говорим о разных вещах.

В Ваших

sasken пишет:

рассуждениях ошибочно

то, что Вы путаете терминологию до наоборот и поэтому Вас невозможно понять. Вот Вы пишете:

sasken пишет:
Функция синуса принимает значения от - 1 до 1.

Функция принимает значения аргументов и возвращает собственное значение. Поэтому правильно сказать, что "функция принимает значения от минус до плюс бесконечности, и возвращает значения от 0 до 1".

А теперь скажите, что произойдёт с этим возвращаемым значением при преобразовании в тип byte, как Вы это делаете? Если не знаете ответа, напишите скетч из трёх строчек и попробуйте преобразовать в байт различные числа от 0 до 1, ну там 0,1, 0,99 и др. и напечатайте их. Как попробуете - поймёте, что Вам коллеги говорят.

sasken
Offline
Зарегистрирован: 28.10.2015

ЕвгенийП пишет:
Вы путаете терминологию до наоборот и поэтому Вас невозможно понять.

согласен. виноват. тут мой косяк. конечно же возвращает значения от -1 до 1

 

ЕвгенийП пишет:
что произойдёт с этим возвращаемым значением при преобразовании в тип byte

ну при условии, что byte может быть только от 0 до 255, то вероятно оно вернет значение в этом диапазоне. мне ж нужно получить "координаты пикселей" моей матрицы, а они выражаются в целых натуральных числах. таких как byte. весь массив 16х16 матрицы как раз это byte.

Вот на картинке примерно проиллюстрировал то, что я думаю должно получится:

белые пиксели соответственно выше верхнего графика.

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sasken пишет:

ну при условии, что byte может быть только от 0 до 255, то вероятно оно вернет значение в этом диапазоне.

Простите, но это ... бред, одним словом.

Я Вам что написал?

ЕвгенийП пишет:
напишите скетч из трёх строчек и попробуйте преобразовать в байт различные числа от 0 до 1, ну там 0,1, 0,99 и др. и напечатайте их.

Так сделайте это. Попробуйте взять с десяток разных чисел в диапазоне от 0 до 1, преобразовать их в байт, как Вы это делаете в программе, и эти байты напечатать. Посмотрите на результат. 

И только сделав это, можете продолжить дискуссию

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

sasken пишет:

andriano пишет:
Очень грубо. Смотреться будет неестественно. Флаг обычно изготавливают из слабо растягивающейся ткани.

т.е. картинку размером 16х16 с изображением флага РФ с глубиной 24 бита - изначально провальная идея?

Грубовато, конечно, но практика показывает, что грамотное использование упомянутых 24 битов способно существенно улучшить ситуацию. Вы же пытаетесь из 24 бит использовать только 3, уменьшая потенциальное количество отображаемых цветов более, чем в 2 миллиона раз.

Ну и еще один важный момент: границы изображения и, соответственно, переходы цветов должны быть не только между цветами флага, но и по границе флага, которая не должна совпадать с границей экрана.

Цитата:

andriano пишет:
Делайте все в RGB и никаких вопросов возникать не будет

а как это реализовать в ргб?

Сэр когда нибудь слышал термин "линейная интерполяция"?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

sasken пишет:

ну при условии, что byte может быть только от 0 до 255, то вероятно оно вернет значение в этом диапазоне.

Предположение верное, но оно не отвечает на вопрос: какое именно значение будет присвоено байту?

sasken
Offline
Зарегистрирован: 28.10.2015

ЕвгенийП пишет:

И только сделав это, можете продолжить дискуссию


Понял. Спасибо. Попробую обязательно.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

sasken пишет:
ЕвгенийП пишет:

И только сделав это, можете продолжить дискуссию

Понял. Спасибо. Попробую обязательно.

Меня вот всегда интересовало: зачем люди пишут подобные "ответы"? Т.е. зачем они вообще что-то пишут на форум до того, как попробовали?

sasken
Offline
Зарегистрирован: 28.10.2015

andriano пишет:
Т.е. зачем они вообще что-то пишут на форум до того, как попробовали?

ну до того, как родились строчки написанные в первом посте, немного думалось, немного чего пробовалось. было немного попыток сделать по другому и как результат, отказ от этих идей. потом был расчет - а как синус вывести вот таким образом, а как поднять, а как анимировать и так далее и так далее. это все было до того как написал вообще на форуме.
Чего-то как то я уже жалею, что написал. приходится очень много оправдываться. извиняться. а лишь из-за того, что написал вместо "значение функции принимает" фразу "функция принимает". ну не дорос я до этого форума. согласен.

и возвращаясь к вашему вопросу:

andriano пишет:
зачем люди пишут подобные "ответы"?

ну из-за вежливости. человек потратил свое время на мой идиотский вопрос. направил меня. я попробую посмотреть значения "в ручную" функциии (byte)(sin(((x)/3)... и сравнить с тем, что я "желаю" получить от этой функции. возможно это мне поможет нарисовать крутетский флаг на матрице.

b707
Offline
Зарегистрирован: 26.05.2017

sasken пишет:

я попробую посмотреть значения "в ручную" функциии (byte)(sin(((x)/3)... и сравнить с тем, что я "желаю" получить от этой функции. возможно это мне поможет нарисовать крутетский флаг на матрице.

пипец...

А сразу, просто из головы - трудно ответить на вопрос, что выдаст выражение sin(x), приведенное к целым числам??  - разрешаю минутку подумать... больше минуты уже будет перебор.

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

У меня вопрос, а зачем мудохаться с синусом на безмозглой ардуине, у которой мало памяти и проблема с математикой, но зато до жёпы флеша? (32 кб это рили много)

1. берём флаг, дуем на него, снимаем на камеру. в крайнем случае анимацию гиф. Нету камеры? - неа, она есть. В телефоне.

2. берём ffmpeg (она бесплатная)

3. делаем отдельные кадры (google://"ffmpeg video to image sequence")

4. берём пхп и пишем: взять картинку из файл0001.jpg файл0002 и т д

5. делаем с этой картинкой imagecolorat(x,y) (картинкоцветв) получаем цифру цвета

6. из этих цифр пишем в начале программы const byte flag_r[] PROGMEM={252,80,32,147,............,95}

точно также на каналы _g, _b

7. #include <avr/чототам/pgmspace.h>, pgm_read_byte[_near?яхзнепомню](); /* google://"arduino progmem example" */

8. мотаем в цикле(index=0;index<длина;index++){

  фастлед.сетпихел(номер,flag_r[index]);

  фастлед.сетпихел(номер,flag_g[index]);

  фастлед.сетпихел(номер,flag_b[index]);

}

FYI: чтобы понять магию, google://precalculated или google://предрассчитанное

sasken
Offline
Зарегистрирован: 28.10.2015

b707 пишет:
А сразу, просто из головы - трудно ответить на вопрос, что выдаст выражение sin(x), приведенное к целым числам??  - разрешаю минутку подумать... больше минуты уже будет перебор.

немного не так. функция float (sin(((x)/3)+(ruru/6))+5)) преобразованная в byte какое значение выдает. так будет правильнее задать вопрос.

ЕвгенийП пишет:
И только сделав это, можете продолжить дискуссию.

Как и сказал вчера, я попробовал. вывел значение функции при переборе аргументов. при преобразовании в byte значения менялись не так как я планировал.
Итого моя ошибка была в преобразовании всего к byte и уже сравнивать с Byte значений матрицы светодиодов.

В итоге когд подправил на такой

void ruflag() {


  for (byte x = 0; x < WIDTH; x++) {
    for (byte y = 0; y < HEIGHT; y++) {
      
      if ( (float)y >= 1.5*sin(((float)x/3)+ruru)+11 ){
        drawPixelXY(x, y, 0xFFFFFF);
      }else if ( (float)y >= 1.5*sin(((float)x/3)+ruru)+5 ) {
      drawPixelXY(x, y, 0x0000FF);
      }
      else{
        drawPixelXY(x, y, 0xFF0000);
      }
      
    }
  }
  ruru=ruru+0.2;
  if (ruru>250) ruru=0;

}

Результат работы анимации:  https://youtu.be/Tx0Np9dP0K0


 

Осталось придумать как сгладить границу.

Voodoo Doll пишет:
У меня вопрос, а зачем мудохаться с синусом на безмозглой ардуине, у которой мало памяти и проблема с математикой, но зато до жёпы флеша? (32 кб это рили много)

отличная идея, жаль она мне сразу в голову не пришла.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

А зачем ты нам показываешь флаг неизвесночей? Похож на сербский, но без эмблемы

b707
Offline
Зарегистрирован: 26.05.2017

DetSimen пишет:

А зачем ты нам показываешь флаг неизвесночей?

потому что у расеи не может быть "развИвающийся" флаг... это у гондураса может, а у нас нет

sasken
Offline
Зарегистрирован: 28.10.2015

DetSimen пишет:
А зачем ты нам показываешь флаг неизвесночей? Похож на сербский, но без эмблемы

))) ну вверх ногами же.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

дак он и "развиваца" будет неправильно. вверх ногами. 

sasken
Offline
Зарегистрирован: 28.10.2015

по делу то кто подскажет что?

Написать переход от белого к синему - тут все понятно. в HSV меняем насыщенность и все.

а вот переход от синего к красному - не понимаю. если менять цветовой тон, то получится либо зеленый/желтый, либо розовый. вообще херня какая-то.

b707
Offline
Зарегистрирован: 26.05.2017

sasken пишет:

по делу то кто подскажет что?

Написать переход от белого к синему - тут все понятно

нафига нужен переход от белого к синему? - на реальном флаге граница четкая, никакого "перехода" нет

sasken
Offline
Зарегистрирован: 28.10.2015

b707 пишет:
нафига нужен переход от белого к синему? - на реальном флаге граница четкая, никакого "перехода" нет

ну на матрице 16х16 выглядит не очень же. может с переходом будет получше

b707
Offline
Зарегистрирован: 26.05.2017

sasken пишет:

ну на матрице 16х16 выглядит не очень же. может с переходом будет получше

это называется "низкое разрешение" и никакими переходами ты это не поправишь, картинка просто станет расплывчатой, как будто через мутное стекло

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sasken пишет:

))) ну вверх ногами же.

На море это означает "терплю бедствие".

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

b707 пишет:

потому что у расеи не может быть "развИвающийся" флаг... это у гондураса может, а у нас нет

Пожалейте ТС! На флаге Гондураса надо звёзды рисовать!

Кстати, пять звёзд на флаге Гондураса означают: Гондурас, Сальвадор, Коста-Рика, Никарагуа и Гватемала. Вот где "имперские амбиции!"

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sasken пишет:

В итоге когд подправил на такой

Крайне неудачное решение! Вместо того, чтобы свести использование float к необходимому минимуму, Вы наоборот, расширили его и даже целочисленные вещи к float преобразуете :-(

sasken
Offline
Зарегистрирован: 28.10.2015

ЕвгенийП пишет:
Крайне неудачное решение!

Виноват. я в программировании вообще ни бум-бум, от того и такие дурацкие вопросы у меня.
Подскажите, пожалуйста, как надо?
Хотя я уже все переписал уже несколько раз - хочу все-таки попробовать плавный переход попробовать. хоть посмотреть как получится.

sasken
Offline
Зарегистрирован: 28.10.2015

b707 пишет:
нафига нужен переход от белого к синему? - на реальном флаге граница четкая, никакого "перехода" нет

Вы абсолютно правы. попробовал в итоге на готовой "игрушке" с рассеивателем. Получилось очень красиво.

А это без рассеивателя:

Тему можно закрывать. Всем огромное спасибо. Очень помогли.