initial commit
This commit is contained in:
123
earth.py
Normal file
123
earth.py
Normal file
@@ -0,0 +1,123 @@
|
||||
import curses
|
||||
import numpy as np
|
||||
import math
|
||||
import time
|
||||
|
||||
# Define the rotation speed of the globe
|
||||
ROTATION_SPEED = 0.02
|
||||
|
||||
# Define the radius of the globe (in terms of terminal characters)
|
||||
RADIUS = 10
|
||||
|
||||
# Define the number of latitude and longitude lines for the wireframe
|
||||
NUM_LATITUDE_LINES = 12
|
||||
NUM_LONGITUDE_LINES = 24
|
||||
|
||||
# Define characters for drawing the wireframe
|
||||
WIREFRAME_CHAR = '◦'
|
||||
CONTINENT_CHAR = '■' # Different character for continents outline
|
||||
|
||||
# A simplified list of latitude and longitude points for continents
|
||||
# This is a minimal representation; a real globe would need a much larger dataset
|
||||
CONTINENT_POINTS = [
|
||||
# Example points for North America, Europe, Africa, etc.
|
||||
(45, -100), (60, -100), (30, -90), # North America
|
||||
(50, 0), (55, 10), (60, 20), # Europe
|
||||
(0, 10), (-10, 20), (-30, 10), # Africa
|
||||
(-20, -50), (-30, -60), (-10, -70), # South America
|
||||
(10, 100), (20, 120), (-10, 130), # Asia
|
||||
]
|
||||
|
||||
# Function to convert latitude and longitude into 3D points on the globe
|
||||
def lat_lon_to_xyz(lat, lon, radius):
|
||||
lat_rad = math.radians(lat)
|
||||
lon_rad = math.radians(lon)
|
||||
x = radius * math.cos(lat_rad) * math.cos(lon_rad)
|
||||
y = radius * math.cos(lat_rad) * math.sin(lon_rad)
|
||||
z = radius * math.sin(lat_rad)
|
||||
return x, y, z
|
||||
|
||||
# Function to project 3D points to 2D terminal coordinates
|
||||
def project(x, y, z, screen_width, screen_height, scale=1):
|
||||
factor = scale / (z + 3)
|
||||
proj_x = int(screen_width / 2 + x * factor * screen_width / 4)
|
||||
proj_y = int(screen_height / 2 - y * factor * screen_height / 4)
|
||||
return proj_x, proj_y
|
||||
|
||||
# Function to generate globe wireframe points
|
||||
def generate_globe(radius, lat_lines, long_lines):
|
||||
points = []
|
||||
for lat in range(0, lat_lines + 1):
|
||||
theta = lat * math.pi / lat_lines
|
||||
for lon in range(0, long_lines + 1):
|
||||
phi = lon * 2 * math.pi / long_lines
|
||||
x = radius * math.sin(theta) * math.cos(phi)
|
||||
y = radius * math.sin(theta) * math.sin(phi)
|
||||
z = radius * math.cos(theta)
|
||||
points.append((x, y, z))
|
||||
return points
|
||||
|
||||
# Function to apply rotation to the globe
|
||||
def rotate(point, angle_x, angle_y, angle_z):
|
||||
x, y, z = point
|
||||
|
||||
# Rotation around X-axis
|
||||
y, z = y * math.cos(angle_x) - z * math.sin(angle_x), y * math.sin(angle_x) + z * math.cos(angle_x)
|
||||
|
||||
# Rotation around Y-axis
|
||||
x, z = x * math.cos(angle_y) + z * math.sin(angle_y), -x * math.sin(angle_y) + z * math.cos(angle_y)
|
||||
|
||||
# Rotation around Z-axis
|
||||
x, y = x * math.cos(angle_z) - y * math.sin(angle_z), x * math.sin(angle_z) + y * math.cos(angle_z)
|
||||
|
||||
return x, y, z
|
||||
|
||||
# Main drawing function
|
||||
def draw_globe(stdscr):
|
||||
curses.curs_set(0) # Hide cursor
|
||||
stdscr.nodelay(True)
|
||||
stdscr.timeout(50)
|
||||
|
||||
screen_height, screen_width = stdscr.getmaxyx()
|
||||
globe_points = generate_globe(RADIUS, NUM_LATITUDE_LINES, NUM_LONGITUDE_LINES)
|
||||
angle_x = angle_y = angle_z = 0
|
||||
|
||||
# Convert continent points to 3D points
|
||||
continent_points_3d = [lat_lon_to_xyz(lat, lon, RADIUS) for lat, lon in CONTINENT_POINTS]
|
||||
|
||||
while True:
|
||||
stdscr.clear()
|
||||
|
||||
# Increment angles for rotation
|
||||
angle_x += ROTATION_SPEED
|
||||
angle_y += ROTATION_SPEED / 2 # Slow Y-axis rotation for realism
|
||||
angle_z += ROTATION_SPEED / 4 # Slow Z-axis rotation for realism
|
||||
|
||||
# Draw the wireframe globe by rotating points and projecting them
|
||||
for point in globe_points:
|
||||
rotated_point = rotate(point, angle_x, angle_y, angle_z)
|
||||
proj_x, proj_y = project(*rotated_point, screen_width, screen_height)
|
||||
if 0 <= proj_x < screen_width and 0 <= proj_y < screen_height:
|
||||
stdscr.addch(proj_y, proj_x, WIREFRAME_CHAR)
|
||||
|
||||
# Draw the continent outlines
|
||||
for point in continent_points_3d:
|
||||
rotated_point = rotate(point, angle_x, angle_y, angle_z)
|
||||
proj_x, proj_y = project(*rotated_point, screen_width, screen_height)
|
||||
if 0 <= proj_x < screen_width and 0 <= proj_y < screen_height:
|
||||
stdscr.addch(proj_y, proj_x, CONTINENT_CHAR)
|
||||
|
||||
stdscr.refresh()
|
||||
|
||||
try:
|
||||
key = stdscr.getch()
|
||||
if key == ord('q'):
|
||||
break # Quit the application
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
time.sleep(0.05)
|
||||
|
||||
# Main entry point for curses wrapper
|
||||
if __name__ == "__main__":
|
||||
curses.wrapper(draw_globe)
|
||||
Reference in New Issue
Block a user