Генератор роста снежинок (ГРСН)

Да, совместить 4 матрицы светодиодов и применить секторный подход. Что-то между:



Усложняем узор до грустного.

Спойлер
#include <Adafruit_GFX.h>
#include <Adafruit_GC9A01A.h>
#include <SPI.h>


#define TFT_DC 17
#define TFT_CS 16
/*
  SCL   --> 18 (SCK)
  SDA   --> 23 (MOSI)
  RST   --> EN
*/

Adafruit_GC9A01A tft(TFT_CS, TFT_DC);
#define TFT_WIDTH  240
#define TFT_HEIGHT 240
// Константы координат смещения центра
const int CENTER_X = 120;
const int CENTER_Y = 120;
const float Z = 250.0; //от 100.0 до 1000.0 регулировка качества отрисовки пикселей с пропусками и без них
struct Point {
  float x, y;
  int R, G, B;
};
const int NUM_POINTS = 12; // Количество точек для диаграммы Вороного
Point points[NUM_POINTS];
long Y = 0; //

void setup() {
  // Инициализация генератора случайных чисел
  randomSeed(analogRead(32));
  tft.begin();
  tft.fillScreen(GC9A01A_BLACK);
  // tft.cp437(true);
  tft.setRotation(0);
  ran_Sait(3);
}

void loop() {
  if (millis() - Y > 120000ul) {//новый цикл роста узоров по условию каждые 90 секунд
    tft.fillScreen(GC9A01A_BLACK);
    Y = millis();
  }
  for (byte v = 1; v < 4; v++) {
    draw_RisSektor(v);
    delay(500);
  }
}
//////////////////////////////////////
//функция вычисления метрики (как вариант расстояния между двумя точками)
float dist(float x1, float y1, float x2, float y2, byte m) {
  if (m == 1) {
    return sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2)); //Евклидова метрика
  }
  if (m == 2) {
    return (abs(x1 - x2) + abs(y2 - y1)); //Манхэттенская метрика
  }
  if (m == 3) {
    return max(abs(x1 - x2), abs(y1 - y2)); // авторская метрика №1
  }

}
//////////////////////////////////////
// функция генерации точек (сайтов)для локусов диаграммы Вороного
void ran_Sait(byte variant) {
  for (int i = 0; i < NUM_POINTS; i++) {
    if (variant == 1 || variant == 3) {
      points[i].x = random(CENTER_X, CENTER_X + 120 );
      points[i].y = random(CENTER_Y, CENTER_Y + 60);
    }
    if (variant == 2 || variant == 3) {
      points[i].R = random(256); points[i].G = random(256); points[i].B = random(256);
    }
  }
}
//////////////////////////////////////
//функция вывода 12 отсимметриченных секторов узора по базовому сектору картинки
void draw_RisSektor(byte variant) {
  for (float f1 = 0.0; f1 <= PI / 6.0; f1 += PI / Z) {//перебор всех точек сектора
    for (int r1 = 0; r1 <= 120 ; r1 += 1) {
      int x = CENTER_X + cos(f1) * r1;
      int y = CENTER_Y + sin(f1) * r1;
      int closestPoint = 0;
      float minDist = dist(x, y, points[0].x, points[0].y, variant );

      for (int i = 1; i < NUM_POINTS; i++) {//определение точки-сайта ближайшей к перебираемой точке
        float d = dist(x, y, points[i].x, points[i].y, variant );
        if (d < minDist) {
          minDist = d;
          closestPoint = i;
        }
      }

      for (float i = 0.01; i <= 2 * PI; i += PI / 3.0) {// отрисовка точек-клонов перебираемой точки
        if (minDist > 15) {//условие роста степени заполнения элементов узора
          int x1 = CENTER_X + cos(f1 + i) * r1;
          int y1 = CENTER_Y + sin(f1 + i) * r1;

          float nx = (float)(x1 - TFT_WIDTH / 2) / (TFT_WIDTH / 2.5);          //
          float ny = (float)(y1 + 20 - TFT_HEIGHT / 2) / (TFT_HEIGHT / 3.0);   //
          // Heart equation: (x^2 + y^2 - 1)^3 - x^2 * y^3 <= 0
          float heartEquation = pow(nx * nx + ny * ny - 1, 3) - nx * nx * pow(ny, 3);
          float grey = 0.3 * abs(points[closestPoint].R - 10 * minDist) + 0.59 * abs(points[closestPoint].G - 10 * minDist) + 0.11 * abs(points[closestPoint].B - 10 * minDist);//перевод в оттенки серого
           grey = grey/2.5;//затемняем фоновое изображение
          if (heartEquation <= 0) {
            tft.drawPixel(x1, y1,  tft.color565(abs(points[closestPoint].R - 10 * minDist), abs(points[closestPoint].G - 10 * minDist), abs(points[closestPoint].B - 10 * minDist)));
          }
          else {
            tft.drawPixel(x1, y1,  tft.color565(grey, grey, grey));
          }

          int x2 = CENTER_X + cos(2 * PI - f1 + i) * r1;
          int y2 = CENTER_Y + sin(2 * PI - f1 + i) * r1;

          nx = (float)(x2 - TFT_WIDTH / 2) / (TFT_WIDTH / 2.5);          //
          ny = (float)(y2 + 20 - TFT_HEIGHT / 2) / (TFT_HEIGHT / 3.0);   //
          // Heart equation: (x^2 + y^2 - 1)^3 - x^2 * y^3 <= 0
          heartEquation = pow(nx * nx + ny * ny - 1, 3) - nx * nx * pow(ny, 3);
          if (heartEquation <= 0) {
            tft.drawPixel(x2, y2, tft.color565(abs(points[closestPoint].R - 10 * minDist), abs(points[closestPoint].G - 10 * minDist), abs(points[closestPoint].B - 10 * minDist)));
          }
          else {
            tft.drawPixel(x2, y2,  tft.color565(grey, grey, grey));
          }
        }
      }
    }
  }
  ran_Sait(3);//новая генерация точек-сайтов
}
//////////////////////////////////////

1 лайк

что дисплей просто так сломали ?))
чей то вас на грустные узоры потянуло ?
можно просто временно переключиться на другой проект…

Матрицы ждать долго.

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

https://roboshop.spb.ru/display/tft-displei/1-8-tft-display вот этот примерно, аккуратно отогнул, и просто свечу фонариком на дисплей)))
и вроде ярко… лупу найти не могу…))) наверное будет нормально работать как проектор…

Линзу. Лупа это режим для линзы :slight_smile: когда увеличивает и даёт мнимое изображение, а тут будет реальное на экране.

Пойду куплю помощнее.
Вот, тоже отогнул.



лучший вариант наверное ргб лента… только у меня она как то неравномерно светила…


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

lilik а вы эту пленку прозрачную, между дисплеем и фонариком убираете или нет ?)))
я вот убрал и вот такая картина, видно же 3 источника света ? 1 фонарик и 2 диода дисплея
разводы на дисплее от камеры…

наталкивает на мысли создать прозрачный дисплей с анимацией, в мини версии, для рекламы продуктов…
ведь можно же из tft дисплея ?
вот если дисплей полностью свет будет поглощать… при выведении черного… и будет обладать в том числе прозрачностью, может даже и умные очки!))) но это на экране lcd1602 наверное, только там есть неактивные пиксели, которые будут пропускать в любом случае…

Не знаю, у меня дисплей не очень прозрачный и надо хорошо просвечивать. Он больше напоминает светофильтр от сварочной маски :slight_smile:

Чёткость от руки на линзе плавает…и на телефоне тоже.

Максимальный коэффициент пропускания цветного дисплея примерно 0.16.

а я борюсь с пеленой на экране))) как то он хуже выводит чем другие экраны…

Получается весь успех в фонарике заложен :slight_smile:


Купил сегодня за 270р. в магазине, написано 3Вт, с встроенным аккумулятором…Друг лет пять назад показывал подобный, но за 3000р. и бил он у него конечно дальше, пятно на дереве видели метров за 150-200.
…тем не менее изображение увеличено примерно в 8-9 раз и оно вполне различимо.

Вы думаете в кино/видеопроекторах просто так матрица, лампа и оптика таких денег стоят? 8))))

ну так это на калькуляторе! из палок)))
а так разные есть https://www.instructables.com/Raspberry-Pi-Wireless-Projector/
ссылку на самый маленький на малине не найду наверное…
есть и не с понятно каким качеством за 3500!
вот на него кажется честный обзор https://ya.ru/video/preview/4810718168632472144

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


сомневаюсь что получится)))


я купил много разных дисплеев, многие оказались с браком, у некоторых вот такая пелена пропадает если отключить пин gnd на дисплее…
у других помогает замена rgb на gbr, и включением разных параметров…
тут никак… хотя может и питания просто не хватает… другие жалко разбирать)))
сталкивались с таким ?

esp8266
// Пины для дисплея
#define TFT_CS 15 // D8
#define TFT_DC 2 // D4
#define TFT_RST 4 // D2
#define TFT_MOSI 13 // D7
#define TFT_SCLK 14 // D5

Не, не сталкивался. У меня их 4, все исправны. Ломать не жалко.


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