#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <math.h> // Include math library for using sin and cos functions
#define SCREEN_WIDTH 128 // OLED screen width in pixels
#define SCREEN_HEIGHT 64 // OLED screen height in pixels
#define OLED_RESET -1 // Reset pin number (set to -1 if shared with Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Serial.begin(9600);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Halt execution indefinitely
}
display.display();
delay(2000);
display.clearDisplay();
}
int range = 30;
void loop() {
int centerX = SCREEN_WIDTH / 2;
int bottomY = SCREEN_HEIGHT - 1;
int lineLength = SCREEN_HEIGHT / 2; // Length of the line as a ratio of screen height
if (range > 0) {
// Swing left by 30 degrees
for (int angle = 0; angle <= range; angle++) {
display.clearDisplay();
drawCloud(20, 10); // Draw a cloud at the specified position
drawCloudTwo(80, 10); // The second cloud
drawSun(64, 10); // The sun
// Calculate the coordinates of the two endpoints of the line
int x1 = centerX;
int y1 = bottomY - lineLength / 2;
int x2 = centerX;
int y2 = bottomY + lineLength / 2;
// Apply rotation transformation
float radiansAngle = radians(angle);
int rotatedX1 = centerX + (x1 - centerX) * cos(radiansAngle) - (y1 - bottomY) * sin(radiansAngle);
int rotatedY1 = bottomY + (x1 - centerX) * sin(radiansAngle) + (y1 - bottomY) * cos(radiansAngle);
int rotatedX2 = centerX + (x2 - centerX) * cos(radiansAngle) - (y2 - bottomY) * sin(radiansAngle);
int rotatedY2 = bottomY + (x2 - centerX) * sin(radiansAngle) + (y2 - bottomY) * cos(radiansAngle);
// Draw the line
display.drawLine(rotatedX1, rotatedY1, rotatedX2, rotatedY2, SSD1306_WHITE);
display.display();
delay(10); // Delay between frames, you can adjust it to control animation speed
}
// Swing right by 60 degrees
for (int angle = range; angle >= (0 - range); angle--) {
display.clearDisplay();
drawCloud(40, 10);
drawCloudTwo(60, 7);
drawSun(64, 10);
int x1 = centerX;
int y1 = bottomY - lineLength / 2;
int x2 = centerX;
int y2 = bottomY + lineLength / 2;
float radiansAngle = radians(angle);
int rotatedX1 = centerX + (x1 - centerX) * cos(radiansAngle) - (y1 - bottomY) * sin(radiansAngle);
int rotatedY1 = bottomY + (x1 - centerX) * sin(radiansAngle) + (y1 - bottomY) * cos(radiansAngle);
int rotatedX2 = centerX + (x2 - centerX) * cos(radiansAngle) - (y2 - bottomY) * sin(radiansAngle);
int rotatedY2 = bottomY + (x2 - centerX) * sin(radiansAngle) + (y2 - bottomY) * cos(radiansAngle);
display.drawLine(rotatedX1, rotatedY1, rotatedX2, rotatedY2, SSD1306_WHITE);
display.display();
delay(10);
}
// Swing left by 30 degrees to return to the vertical position
for (int angle = (0 - range); angle <= 0; angle++) {
display.clearDisplay();
drawCloud(60, 10);
drawCloudTwo(50, 4);
drawSun(64, 15);
int x1 = centerX;
int y1 = bottomY - lineLength / 2;
int x2 = centerX;
int y2 = bottomY + lineLength / 2;
float radiansAngle = radians(angle);
int rotatedX1 = centerX + (x1 - centerX) * cos(radiansAngle) - (y1 - bottomY) * sin(radiansAngle);
int rotatedY1 = bottomY + (x1 - centerX) * sin(radiansAngle) + (y1 - bottomY) * cos(radiansAngle);
int rotatedX2 = centerX + (x2 - centerX) * cos(radiansAngle) - (y2 - bottomY) * sin(radiansAngle);
int rotatedY2 = bottomY + (x2 - centerX) * sin(radiansAngle) + (y2 - bottomY) * cos(radiansAngle);
display.drawLine(rotatedX1, rotatedY1, rotatedX2, rotatedY2, SSD1306_WHITE);
display.display();
delay(10);
}
range = range - 5;
}
}
void drawCloud(int x, int y) {
// First cloud
display.fillCircle(x + 5, y + 5, 5, SSD1306_WHITE);
display.fillCircle(x + 12, y + 5, 7, SSD1306_WHITE);
display.fillCircle(x + 25, y + 5, 5, SSD1306_WHITE);
display.fillCircle(x + 8, y + 5, 3, SSD1306_WHITE);
display.fillCircle(x + 7, y + 10, 6, SSD1306_WHITE);
display.fillCircle(x + 15, y + 12, 5, SSD1306_WHITE);
display.fillCircle(x + 10, y + 10, 2, SSD1306_WHITE);
display.fillCircle(x + 20, y + 10, 4, SSD1306_WHITE);
}
void drawCloudTwo(int x, int y) {
// Second cloud
display.fillCircle(x + 5, y + 5, 2, SSD1306_WHITE);
display.fillCircle(x + 12, y + 3, 2, SSD1306_WHITE);
display.fillCircle(x + 25, y + 5, 5, SSD1306_WHITE);
display.fillCircle(x + 8, y + 5, 4, SSD1306_WHITE);
display.fillCircle(x + 7, y + 7, 4, SSD1306_WHITE);
display.fillCircle(x + 15, y + 12, 5, SSD1306_WHITE);
display.fillCircle(x + 10, y + 10, 2, SSD1306_WHITE);
display.fillCircle(x + 20, y + 3, 4, SSD1306_WHITE);
}
void drawSun(int x, int y) {
// Sun circle
display.fillCircle(x, y, 5, SSD1306_WHITE);
// Ray lines
int numRays = 12; // Number of ray lines
int rayLength = 8; // Length of the radiating lines
for (int i = 0; i < numRays; i++) {
float angle = map(i, 0, numRays, 0, TWO_PI); // Calculate the angle for each line
int endX = x + cos(angle) * rayLength;
int endY = y + sin(angle) * rayLength;
display.drawLine(x, y, endX, endY, SSD1306_WHITE);
}
}