commit 7b76b576f52cfba2cb250424e7ecd9a6a8cebd20 Author: klein panic Date: Sun Sep 29 02:35:29 2024 -0400 initial commit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..aa68c88 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +CC = gcc +CFLAGS = -lncurses -lm # Link ncurses and math libraries +TARGET = earth + +all: $(TARGET) + +$(TARGET): $(TARGET).o + $(CC) -o $(TARGET) $(TARGET).o $(CFLAGS) + +$(TARGET).o: $(TARGET).c + $(CC) -c $(TARGET).c + +clean: + rm -f $(TARGET).o $(TARGET) diff --git a/earth b/earth new file mode 100755 index 0000000..e168c3b Binary files /dev/null and b/earth differ diff --git a/earth.c b/earth.c new file mode 100644 index 0000000..58ba257 --- /dev/null +++ b/earth.c @@ -0,0 +1,128 @@ +#include +#include +#include +#include + +#define WIDTH 80 +#define HEIGHT 40 +#define SPHERE_POINTS 1000 // Increased number of points for better realism +#define CONTINENT_POINTS 500 // More points for realistic continent outlines + +// Structure for 3D points +typedef struct { + float x, y, z; +} Point3D; + +// Structure for 2D points (projected from 3D) +typedef struct { + int x, y; +} Point2D; + +// Arrays to hold points on the sphere and for continents +Point3D spherePoints[SPHERE_POINTS]; +Point3D continentPoints[CONTINENT_POINTS]; + +// Function to project 3D points to 2D with perspective projection +Point2D project(Point3D point, float angleX, float angleY) { + // Apply rotations around the X and Y axes + float cosY = cos(angleY), sinY = sin(angleY); + float cosX = cos(angleX), sinX = sin(angleX); + float x = point.x * cosY - point.z * sinY; + float z = point.x * sinY + point.z * cosY; + float y = point.y * cosX - z * sinX; + z = point.y * sinX + z * cosX; + + // Simple perspective projection + float fov = 25.0; // Field of view for 3D perspective + Point2D projected = { + (int)((x / (z + 3)) * fov) + WIDTH / 2, // Offset to the center of the screen + (int)((y / (z + 3)) * fov) + HEIGHT / 2 + }; + return projected; +} + +// Function to generate points on a 3D sphere using spherical coordinates +void generate_sphere() { + int index = 0; + for (int i = 0; i < SPHERE_POINTS; i++) { + float theta = 2.0 * M_PI * (float)i / sqrt(SPHERE_POINTS); // Horizontal angle + float phi = acos(2.0 * (float)i / SPHERE_POINTS - 1); // Vertical angle + + spherePoints[index].x = sin(phi) * cos(theta); + spherePoints[index].y = cos(phi); + spherePoints[index].z = sin(phi) * sin(theta); + index++; + } +} + +// Function to convert latitude/longitude to 3D points for continents +void latlon_to_xyz(float lat, float lon, Point3D* point) { + float radLat = lat * M_PI / 180.0; // Convert to radians + float radLon = lon * M_PI / 180.0; // Convert to radians + point->x = cos(radLat) * cos(radLon); + point->y = sin(radLat); + point->z = cos(radLat) * sin(radLon); +} + +// Function to generate the wireframe outline of continents using more realistic data +void generate_continents() { + // Example: a few detailed latitude/longitude points along major continents + float latitudes[] = {51.1657, 40.7128, -33.9249, 35.6895, -34.6037}; // Major cities as an example + float longitudes[] = {10.4515, -74.0060, 18.4241, 139.6917, -58.3816}; // Corresponding longitudes + + int index = 0; + for (int i = 0; i < sizeof(latitudes) / sizeof(float); i++) { + if (index < CONTINENT_POINTS) { + latlon_to_xyz(latitudes[i], longitudes[i], &continentPoints[index++]); + } + } +} + +// Draw the Earth with the rotating sphere and continents overlay +void draw_earth(float angleX, float angleY) { + clear(); + + // Draw the wireframe for the sphere + for (int i = 0; i < SPHERE_POINTS; i++) { + Point2D projected = project(spherePoints[i], angleX, angleY); + if (projected.x >= 0 && projected.x < WIDTH && projected.y >= 0 && projected.y < HEIGHT) { + mvprintw(projected.y, projected.x, "o"); // Draw points for the sphere + } + } + + // Draw the wireframe for the continents + for (int i = 0; i < CONTINENT_POINTS; i++) { + Point2D projected = project(continentPoints[i], angleX, angleY); + if (projected.x >= 0 && projected.x < WIDTH && projected.y >= 0 && projected.y < HEIGHT) { + mvprintw(projected.y, projected.x, "x"); // Draw points for the continents + } + } + + refresh(); +} + +int main() { + initscr(); // Start ncurses + curs_set(0); // Hide cursor + timeout(0); // Non-blocking input + noecho(); // Disable character echo + + // Generate sphere points and continent wireframe + generate_sphere(); + generate_continents(); + + float angleX = 0, angleY = 0; + while (1) { + draw_earth(angleX, angleY); // Draw the rotating Earth + angleX += 0.01; // Rotate around X axis + angleY += 0.02; // Rotate around Y axis + usleep(50000); // Delay for animation speed + + int ch = getch(); // Check for user input + if (ch == 'q') break; // Quit if 'q' is pressed + } + + endwin(); // End ncurses + return 0; +} + diff --git a/earth.o b/earth.o new file mode 100644 index 0000000..8da53a9 Binary files /dev/null and b/earth.o differ