-
-
Save lovyan03/c1b8d2aa029341138d1c392b087a0d03 to your computer and use it in GitHub Desktop.
Compound oscillation demo for ESP32
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Compound oscillation demo for ESP32 | |
// Loosely coded by tobozo (c+) apr 2022 - | |
// Inspired by this GIF | |
// - https://twitter.com/bayraitt/status/1514499189975134210 | |
#include <ESP32-Chimera-Core.h> // https://github.com/tobozo/ESP32-Chimera-Core | |
static LGFX &tft(M5.Lcd); | |
static LGFX_Sprite* spriteLines = new LGFX_Sprite( &tft ); | |
static LGFX_Sprite* spriteMix = new LGFX_Sprite( &tft ); | |
static constexpr const int gridSize = 6; | |
static constexpr const int gridMargin = 10; | |
static constexpr const uint32_t bgcolor = 0x4d4845U; | |
static constexpr const uint32_t hgcolor = 0xffffffU; | |
static constexpr const uint32_t fgcolor = 0x888888U; | |
static float angle = 0; | |
static int sqWidth; | |
static int sqSize; | |
static int offsetX = gridMargin; | |
static int offsetY = gridMargin; | |
static int spritePosX, spritePosY; | |
uint8_t blend(float a, float b, float bias=0.5f) | |
{ | |
return sqrtf( ((1 - bias) * (a*a)) + ( bias * (b*b ) ) ); | |
} | |
void drawGrid( float angle_offset = 0 ) | |
{ | |
int xlist[gridSize], ylist[gridSize]; | |
for( int i=1; i<=gridSize; i++ ) { | |
int pos = (i*sqWidth)+sqSize; | |
int xp = roundf(cosf( (angle * (float)i + angle_offset) ) * sqSize); | |
int yp = roundf(sinf( (angle * (float)i + angle_offset) ) * sqSize); | |
xlist[i-1] = xp+pos; | |
ylist[i-1] = yp+pos; | |
uint16_t c = map( i, 0, gridSize, 0, 255 ); | |
spriteLines->setColor(tft.color332( c, 255-c, 128 )); | |
spriteLines->drawPixel( offsetX + xp + pos, offsetY + yp + sqSize ); | |
spriteLines->drawPixel( offsetX + xp + sqSize, offsetY + yp + pos ); | |
} | |
for( int v = 1; v <= gridSize; v++ ) { | |
int cv = map( v, 0, gridSize, 0, 255 ); | |
for( int h = 1; h <= gridSize; h++ ) { | |
int ch = map( h, 0, gridSize, 0, 255 ); | |
int c = blend(cv, ch); | |
spriteLines->setColor(tft.color332( c, 255-c, 128 )); | |
spriteLines->drawPixel( offsetX + xlist[h-1], offsetY + ylist[v-1] ); | |
} | |
} | |
} | |
void drawBullet( int x, int y ) | |
{ | |
spriteLines->pushSprite( spriteMix, 4-x, 4-y ); | |
spriteMix->fillCircle( 4, 4, 2, TFT_WHITE ); | |
spriteMix->pushSprite(spritePosX+x-4, spritePosY+y-4); | |
} | |
void drawBullets( float angle_offset = 0 ) | |
{ | |
int xlist[gridSize], ylist[gridSize]; | |
for( int i=1; i<=gridSize; i++ ) { | |
int pos = (i*sqWidth)+sqSize; | |
int xp = roundf(cosf( (angle * (float)i + angle_offset) ) * sqSize); | |
int yp = roundf(sinf( (angle * (float)i + angle_offset) ) * sqSize); | |
xlist[i-1] = xp+pos; | |
ylist[i-1] = yp+pos; | |
drawBullet( offsetX + xp + pos, offsetY + yp + sqSize ); | |
drawBullet( offsetX + xp + sqSize, offsetY + yp + pos ); | |
} | |
for( int v = 0; v < gridSize; v++ ) { | |
for( int h = 0; h < gridSize; h++ ) { | |
drawBullet( offsetX + xlist[h], offsetY + ylist[v] ); | |
} | |
} | |
} | |
void setupSprites() | |
{ | |
uint16_t squareSize = min(tft.width(),tft.height()); | |
sqWidth = (squareSize-gridMargin ) / (gridSize+1); | |
sqSize = (sqWidth/2)-4; | |
spriteLines->setColorDepth( 8 ); | |
if( ! spriteLines->createSprite( squareSize, squareSize ) ) { | |
Serial.println("Can't create spriteLines, halting"); | |
while(1) delay(1); | |
} | |
spriteLines->fillSprite(bgcolor); | |
spriteMix->setColorDepth( 8 ); | |
if( ! spriteMix->createSprite( 9, 9 ) ) { | |
Serial.println("Can't create spriteMix, halting"); | |
while(1) delay(1); | |
} | |
spriteMix->fillSprite(bgcolor); | |
spritePosX = (tft.width() - spriteLines->width() ) >> 1; | |
spritePosY = (tft.height() - spriteLines->height()) >> 1; | |
} | |
void setup() | |
{ | |
M5.begin(); | |
tft.fillScreen(tft.color16to8(tft.color24to16(bgcolor))); | |
setupSprites(); | |
// fill the grid, only needs one pass | |
// also animate bullets | |
for( float a=0; a<2*PI*gridSize; a +=.01f ) { | |
angle = fmodf( a, 2*PI ); | |
drawGrid(); | |
drawBullets(); | |
} | |
} | |
void loop() | |
{ | |
drawBullets(); | |
angle = fmodf( angle, 2*PI ); | |
angle += .01f; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment