Here is a quick pass at changing from 32-bit floats to 8-bit velocity and 16-bit position. This makes each particle 48 bits instead of 128 bits. It should also speed up the math since most is done in 32-bit integers instead of floats.
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define SCREEN_ADDRESS 0x3C
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C
#define xRBound 128
#define xLBound 0
#define yDBound 64
#define yUBound 0
#define particles 20
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
struct Particle
{
int8_t dx; // Velocity in tenths of a pixel per step (+/-12.7 pixels)
int8_t dy; // Velocity in tenths of a pixel per step (+/-12.7 pixels)
int16_t xPos; // Position in hundredths of a pixel (+/-320.00 pixels)
int16_t yPos; // Position in hundredths of a pixel (+/-320.00 pixels)
} Particles[particles];
int radius = 0;
int mass = 1;
const float DEG2RAD = PI / 180.0;
const float RAD2DEG = 180.0 / PI;
void setup()
{
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(1, INPUT);
randomSeed(analogRead(1));
display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
display.setTextColor(SSD1306_WHITE);
display.setTextSize(0);
display.clearDisplay();
startParticlesRandom();
// startParticlesFine();
}
void loop()
{
displayParticles();
moveParticles();
// collisionCheck();
delay(10);
}
void collisionCheck()
{
for (int i = 0; i < particles; i++)
{
int32_t x1 = Particles[i].xPos;
int32_t y1 = Particles[i].yPos;
for (int j = 0; j < particles; j++)
{
if (i == j) continue;
int32_t dx = Particles[j].xPos - x1;
int32_t dy = Particles[j].yPos - y1;
float distance = sqrt((dx * dx / 100) + (dy * dy / 100));
if (distance - radius * 2 <= 1)
{
//Input complex physics equation that I don't understand yet so that particles will bounce and transfer energy
}
}
}
}
void startParticlesRandom()
{
for (int i = 0; i < particles; i++)
{
Particles[i].yPos = random(yUBound + radius, yDBound - radius);
Particles[i].xPos = random(xLBound + radius, xRBound - radius);
Particles[i].dx = random(-120, +120);
Particles[i].dy = random(-120, +120);
// Serial.print("particle ");
// Serial.print(i);
// Serial.println(" set!");
}
}
void startParticlesFine()
{
Particles[0].yPos = (yDBound / 2) * 100;
Particles[1].yPos = (yDBound / 2) * 100;
Particles[0].xPos = 5 * 100;
Particles[1].xPos = 123 * 100;
Particles[0].dx = 15;
Particles[1].dx = -5;
Particles[0].dy = 15;
Particles[1].dy = -5;
}
void moveParticles()
{
for (int i = 0; i < particles; i++)
{
if (Particles[i].yPos / 100 >= yDBound - radius || Particles[i].yPos / 100 <= yUBound + radius)
{
Particles[i].dy *= -1;
}
if (Particles[i].xPos / 100 >= xRBound - radius || Particles[i].xPos / 100 <= xLBound + radius)
{
Particles[i].dx *= -1;
}
// Convert velocity in 10th to position change in 100ths
Particles[i].yPos += Particles[i].dy * 10;
Particles[i].xPos += Particles[i].dx * 10;
}
}
void displayParticles()
{
display.clearDisplay();
for (int i = 0; i < particles; i++)
{
// Convert hundredths of a pixel to pixels
int x = Particles[i].xPos / 100;
int y = Particles[i].yPos / 100;
display.drawCircle(x, y, radius, WHITE);
}
display.display();
}