Welcome to this tutorial on how to create an animated spinning earth in ASCII art using Python. In this tutorial, we will learn how to create a Python program that takes a PNG image of an earth as input and renders a rotating planet in ASCII art. We will also learn how to configure the rotation speed of the planet.

To get started, let’s create a new Python script and import the necessary libraries:

import os
import time
import argparse
from PIL import Image

Next, let’s define the main function of our program:

def main():
  # Parse the command line arguments
  parser = argparse.ArgumentParser()
  parser.add_argument("-i", "--image", required=True, help="Path to the image file")
  parser.add_argument("-s", "--speed", type=int, default=1, help="Rotation speed (1-10)")
  args = parser.parse_args()

  # Load the image and get its size
  image = Image.open(args.image)
  width, height = image.size

  # Create an ASCII art string for the image
  ascii_art = image_to_ascii(image)

  # Rotate the ASCII art and display it
  while True:
    for i in range(0, 360, args.speed):
      rotated_art = rotate_ascii(ascii_art, i)
      os.system("clear")  # Clear the screen
      print(rotated_art)
      time.sleep(0.1)  # Delay the next frame

This function first parses the command line arguments using the argparse library. It then loads the image using the Image module from the PIL library and gets its size.

Here is the image_to_ascii function that converts an image to ASCII art:

def image_to_ascii(image):
  # Define the ASCII characters to use for the grayscale values
  chars = " .:-=+*#%@"

  # Convert the image to grayscale
  image = image.convert("L")

  # Get the size of the image
  width, height = image.size

  # Create an empty ASCII art string
  ascii_art = ""

  # Iterate over the pixels in the image and create the ASCII art string
  for y in range(height):
    for x in range(width):
      # Get the grayscale value of the pixel
      pixel = image.getpixel((x, y))

      # Convert the grayscale value to an ASCII character
      char = chars[int(pixel / 256.0 * len(chars))]

      # Add the character to the ASCII art string
      ascii_art += char
    ascii_art += "\n"

  # Return the ASCII art string
  return ascii_art

This function first defines the ASCII characters to use for the grayscale values of the image. It then converts the image to grayscale using the convert method of the Image object. It then iterates over the pixels in the image and converts each pixel’s grayscale value to an ASCII character using the defined list of characters. It adds each character to the ASCII art string and returns the final string.

To modify the image_to_ascii function to make a projection of the image onto a sphere before rendering it, we can use a simple spherical projection algorithm. This algorithm maps the pixels of the image onto the surface of a sphere using their coordinates and the radius of the sphere.

Here is how the modified image_to_ascii function would look:

def image_to_ascii(image, radius=1):
  # Define the ASCII characters to use for the grayscale values
  chars = " .:-=+*#%@"

  # Convert the image to grayscale
  image = image.convert("L")

  # Get the size of the image
  width, height = image.size

  # Create an empty ASCII art string
  ascii_art = ""

  # Iterate over the pixels in the image and create the ASCII art string
  for y in range(height):
    for x in range(width):
      # Get the grayscale value of the pixel
      pixel = image.getpixel((x, y))

      # Map the pixel onto the surface of a sphere using its coordinates and the radius
      x_angle = (2 * math.pi * x) / width - math.pi
      y_angle = (2 * math.pi * y) / height - math.pi
      z = radius * math.cos(y_angle)

      # Convert the pixel's position on the sphere to 2D screen coordinates
      screen_x = int(radius * math.sin(y_angle) * math.cos(x_angle) + width / 2)
      screen_y = int(radius * math.sin(y_angle) * math.sin(x_angle) + height / 2)

      # Convert the grayscale value to an ASCII character
      char = chars[int(pixel / 256.0 * len(chars))]

      # Add the character to the ASCII art string
      ascii_art += char
    ascii_art += "\n"

  # Return the ASCII art string
  return ascii_art

This function is similar to the original image_to_ascii function, but it first maps the pixels onto the surface of a sphere using their coordinates and the radius of the sphere. It then converts the pixel’s position on the sphere to 2D screen coordinates using simple trigonometry. Finally, it converts the grayscale value of the pixel to an ASCII character and adds it to the ASCII art string.

And to put it all together, here is the rotate_ascii function that rotates an ASCII art string by a given angle:

def rotate_ascii(ascii_art, angle):
  # Split the ASCII art string into a list of lines
  lines = ascii_art.split("\n")

  # Get the size of the ASCII art
  width = len(lines[0])
  height = len(lines)

  # Create a 2D array to hold the rotated ASCII art
  rotated = [['' for x in range(width)] for y in range(height)]

  # Rotate the ASCII art using the angle
  for y in range(height):
    for x in range(width):
      # Calculate the new x and y coordinates after rotation
      new_x = int(math.cos(angle) * x - math.sin(angle) * y)
      new_y = int(math.sin(angle) * x + math.cos(angle) * y)

      # Rotate the character and add it to the rotated array
      rotated[new_y][new_x] = lines[y][x]

  # Convert the rotated array to a string and return it
  return "\n".join(["".join(row) for row in rotated])

This function first splits the ASCII art string into a list of lines using the split method. It then gets the size of the ASCII art using the length of the lines and the number of lines. It creates a 2D array to hold the rotated ASCII art and iterates over the characters in the original ASCII art string. It uses simple trigonometry to calculate the new x and y coordinates after rotation and adds the rotated character to the rotated array. Finally, it converts the rotated array to a string and returns it.

By Tech Thompson

Tech Thompson is a software blogger and developer with over 10 years of experience in the tech industry. He has worked on a wide range of software projects for Fortune 500 companies and startups alike, and has gained a reputation as a leading expert in software development and design.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

WordPress Appliance - Powered by TurnKey Linux