Created
April 15, 2022 16:43
-
-
Save tobozo/d9fb5b7a930f31669cff6e5e0ec910c1 to your computer and use it in GitHub Desktop.
Compound oscillation demo for ESP32
This file contains hidden or 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 LGFX_Sprite* spriteBullets = 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; | |
float angle = 0; | |
int sqWidth; | |
int sqSize; | |
int offsetX = gridMargin; | |
int offsetY = gridMargin; | |
int spritePosX, spritePosY; | |
uint8_t blend(float a, float b, float bias=0.5) | |
{ | |
return sqrt( ((1 - bias) * (a*a)) + ( bias * (b*b ) ) ); | |
} | |
void drawGrid( float angle_offset = 0 ) | |
{ | |
float xpos,ypos; | |
float x, y; | |
for( float h=0; h<=gridSize; h++ ) { | |
for( float v=0; v<=gridSize; v++ ) { | |
if( h == 0 && v == 0 ) continue; | |
xpos = (h*sqWidth)+sqSize; | |
ypos = (v*sqWidth)+sqSize; | |
bool circle = false; | |
uint16_t barcolor; | |
uint16_t ch = map( h, 0, gridSize, 0, 255 ); | |
uint16_t cv = map( v, 0, gridSize, 0, 255 ); | |
if( v == 0 ) { | |
x = xpos + cos( (angle * h + angle_offset) ) * sqSize; | |
y = ypos + sin( (angle * h + angle_offset) ) * sqSize; | |
barcolor = tft.color565( ch, 255-ch, 128 ); | |
} else if( h == 0 ) { | |
x = xpos + cos( (angle * v + angle_offset) ) * sqSize; | |
y = ypos + sin( (angle * v + angle_offset) ) * sqSize; | |
barcolor = tft.color565( cv, 255-cv, 128 ); | |
} else { | |
x = xpos + cos( (angle + angle_offset) * h ) * sqSize; | |
y = ypos + sin( (angle + angle_offset) * v ) * sqSize; | |
barcolor = tft.color565( blend(cv, ch), 255-blend(ch, cv), 128 ); | |
} | |
spriteLines->drawPixel( offsetX+x, offsetY+y, barcolor ); | |
} | |
} | |
} | |
void drawBullets( float angle_offset = 0 ) | |
{ | |
float xpos,ypos; | |
float x, y; | |
for( float h=0; h<=gridSize; h++ ) { | |
for( float v=0; v<=gridSize; v++ ) { | |
if( h == 0 && v == 0 ) continue; | |
xpos = (h*sqWidth)+sqSize; | |
ypos = (v*sqWidth)+sqSize; | |
if( v == 0 ) { | |
x = xpos + cos( (angle * h + angle_offset) ) * sqSize; | |
y = ypos + sin( (angle * h + angle_offset) ) * sqSize; | |
} else if( h == 0 ) { | |
x = xpos + cos( (angle * v + angle_offset) ) * sqSize; | |
y = ypos + sin( (angle * v + angle_offset) ) * sqSize; | |
} else { | |
x = xpos + cos( (angle + angle_offset) * h ) * sqSize; | |
y = ypos + sin( (angle + angle_offset) * v ) * sqSize; | |
} | |
spriteBullets->fillCircle( offsetX+x, offsetY+y, 2, 1 ); | |
} | |
} | |
spriteLines->pushSprite( spriteMix, 0, 0 ); | |
spriteBullets->pushSprite( spriteMix, 0, 0, 0 ); | |
spriteMix->pushSprite( spritePosX, spritePosY ); | |
spriteBullets->fillSprite( 0 ); | |
} | |
void setupSprites() | |
{ | |
uint16_t squareSize = 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); | |
} | |
spriteLines->fillSprite(bgcolor); | |
spriteMix->setColorDepth( 8 ); | |
if( ! spriteMix->createSprite( squareSize, squareSize ) ) { | |
Serial.println("Can't create spriteMix, halting"); | |
while(1); | |
} | |
spriteMix->fillSprite(bgcolor); | |
spriteBullets->setColorDepth( 1 ); | |
spriteBullets->setPaletteColor( 0, bgcolor ); | |
spriteBullets->setPaletteColor( 1, hgcolor ); | |
if( ! spriteBullets->createSprite( squareSize, squareSize ) ) { | |
Serial.println("Can't create spriteBullets, halting"); | |
while(1); | |
} | |
spriteBullets->fillSprite(0); | |
spritePosX = tft.width()/2 - spriteMix->width()/2; | |
spritePosY = tft.height()/2 - spriteMix->height()/2; | |
} | |
void setup() | |
{ | |
M5.begin(); | |
setupSprites(); | |
// fill the grid, only needs one pass | |
// also animate bullets | |
for( float a=0; a<2*PI*gridSize; a +=.02 ) { | |
angle = fmod( a, 2*PI ); | |
drawGrid(); | |
drawBullets(); | |
} | |
} | |
void loop() | |
{ | |
drawBullets(); | |
angle = fmod( angle, 2*PI ); | |
angle += .02; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment