initial commit
This commit is contained in:
14
Makefile
Normal file
14
Makefile
Normal file
@@ -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)
|
||||||
128
earth.c
Normal file
128
earth.c
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <ncurses.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user