Tips for effectively storing and displaying orbital paths in pygame

After following a tutorial on YouTube by TechWithTim, I successfully completed a solar system project in pygame. With plans to expand it further, adding more planets caused the program to crash due to memory issues related to orbit rendering. How can I efficiently store and render the orbital points without crashing?

The code snippet below is sourced from TechWithTim's YouTube channel.

import pygame
import math
pygame.init()

WIDTH, HEIGHT =  1200, 750
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Planet Simulation")

WHITE = (255, 255, 255)
YELLOW = (255, 255, 0)
BLUE = (100, 149, 237)
RED = (188, 39, 50)
DARK_GREY = (80, 78, 81)

FONT = pygame.font.SysFont("comicsans", 16)

class Planet:
    AU = 149.6e6 * 1000
    G = 6.67428e-11
    SCALE = 250 / AU  # 1AU = 100 pixels
    TIMESTEP = 3600*24 # 1 day

    def __init__(self, x, y, radius, color, mass):
        self.x = x
        self.y = y
        self.radius = radius
        self.color = color
        self.mass = mass

        self.orbit = []
        self.sun = False
        self.distance_to_sun = 0

        self.x_vel = 0
        self.y_vel = 0

    def draw(self, win):
        x = self.x * self.SCALE + WIDTH / 2
        y = self.y * self.SCALE + HEIGHT / 2

        if len(self.orbit) > 2:
            updated_points = []
            for point in self.orbit:
                x, y = point
                x = x * self.SCALE + WIDTH / 2
                y = y * self.SCALE + HEIGHT / 2
                updated_points.append((x, y))

            pygame.draw.lines(win, self.color, False, updated_points, 2)

        pygame.draw.circle(win, self.color, (x, y), self.radius)
        
        if not self.sun:
            distance_text = FONT.render(f"{round(self.distance_to_sun/1000, 1)}km", 1, WHITE)
            win.blit(distance_text, (x - distance_text.get_width()/2, y - distance_text.get_height()/2))

    def attraction(self, other):
        other_x, other_y = other.x, other.y
        distance_x = other_x - self.x
        distance_y = other_y - self.y
        distance = math.sqrt(distance_x ** 2 + distance_y ** 2)

        if other.sun:
            self.distance_to_sun = distance

        force = self.G * self.mass * other.mass / distance**2
        theta = math.atan2(distance_y, distance_x)
        force_x = math.cos(theta) * force
        force_y = math.sin(theta) * force
        return force_x, force_y

    def update_position(self, planets):
        total_fx = total_fy = 0
        for planet in planets:
            if self == planet:
                continue

            fx, fy = self.attraction(planet)
            total_fx += fx
            total_fy += fy

        self.x_vel += total_fx / self.mass * self.TIMESTEP
        self.y_vel += total_fy / self.mass * self.TIMESTEP

        self.x += self.x_vel * self.TIMESTEP
        self.y += self.y_vel * self.TIMESTEP
        self.orbit.append((self.x, self.y))


def main():
    run = True
    clock = pygame.time.Clock()

    sun = Planet(0, 0, 30, YELLOW, 1.98892 * 10**30)
    sun.sun = True

    earth = Planet(-1 * Planet.AU, 0, 16, BLUE, 5.9742 * 10**24)
    earth.y_vel = 29.783 * 1000

    mars = Planet(-1.524 * Planet.AU, 0, 12, RED, 6.39 * 10**23)
    mars.y_vel = 24.077 * 1000

    mercury = Planet(0.387 * Planet.AU, 0, 8, DARK_GREY, 3.30 * 10**23)
    mercury.y_vel = -47.4 * 1000

    venus = Planet(0.723 * Planet.AU, 0, 14, WHITE, 4.8685 * 10**24)
    venus.y_vel = -35.02 * 1000

    planets = [sun, earth, mars, mercury, venus]

    while run:
        clock.tick(60)
        WIN.fill((0, 0, 0))

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

        for planet in planets:
            planet.update_position(planets)
            planet.draw(WIN)

        pygame.display.update()

    pygame.quit()


main()

Answer №1

I encountered your issue and found a simple solution. I made a minor modification to the update_position function by adding just two lines of code that remove the first dot from the array when the circle is full.

if len(self.orbit) > 720:
    del self.orbit[0]

The number 720 represents the maximum length of the self.orbit array for the farthest planet. Adjust this value accordingly for each planet through appropriate calculations.

I trust that my resolution will be beneficial to you.

- Adam

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Setting the parameter n_batches_per_layer in tf.estimator.BoostedTreesClassifier: A guide to optimizing your model

When determining the n_batches_per_layer, what mindset should I adopt? After conducting hyperparameter tuning, I currently choose 10 from the options [1, 10, 100]. Upon further reflection, dividing my data by the batch_size gives me 6.8 batches. This lead ...

Creating a new JSON file after each iteration in Python - A step-by-step guide

Currently, I am working with a CSV file that needs to be converted into a JSON file. My goal is to save each new JSON object into a separate file. Here is an example of what I am trying to achieve: { "first_name": "Hello", "last_name": "World", "color": " ...

Search for all dictionaries within a given list that include a particular discipline name, then retrieve the specific data from each dictionary

I've been working on this dataset for a while now, but I'm struggling to get the results I need. Can someone help me find the specific data I'm looking for? Below is a sample of my data in JSON format. I want to extract all disciplines that ...

Bringing in text using pandas in Python

I need help regarding importing a table into a pandas dataframe. One of the strings in the table contains the special character 'NF-κB' with the 'kappa' symbol. However, when I use pd.read_table to import the table from 'table_pro ...

Provide the dataframe with data gathered through web scraping

I'm facing an issue while trying to add some extracted data to a dataframe. Here is the code snippet I am using: import time import requests import pandas import pandas as pd from bs4 import BeautifulSoup from selenium import webdriver from selenium. ...

Exploring the capabilities of HTML5 canvas and integrating it with Selenium using Python

I have been working on testing a web server that is built using HTML5 with a canvas. While examining the source code for the login page, I noticed very minimal content. However, upon inspecting the element in Chrome, I discovered the following snippet: &l ...

Guide to making usernames and emails case-insensitive in a Django Project

I have set up the authentication process for users in Django: class EmailBackend(ModelBackend): def authenticate(self, request, username=None, password=None, **kwargs): UserModel = get_user_model() try: user = UserModel.obje ...

Is anyone able to recognize the form of encryption being used here?

Currently, I am working on developing a program to communicate with hardware that sends encoded data wrapped within a CDATA block in an XML document. The device's software is written in Python, while I am creating the interface in Delphi. Here is a ...

The function is malfunctioning within this particular code, misinterpreting the "if" statement in Python

My recently coded Python function seems to be stuck in a loop, repeatedly running up to one hundred. When I input "5" into the interpreter (or RUN), it appears that the incorrect "if" statement is being executed. def range_v2(c): int(c) if c == ...

Eliminate any duplicate values in the dataframe column, but only if they are at the start, ensuring that

I have a dataframe that I want to plot, but there are duplicate entries in each column. I'd like to only keep the final entry in each column to avoid them showing up on the graph (ignoring duplicates in the middle and end). Can anyone help me solve t ...

Sending a pandas dataframe to a function

I need help figuring out how to pass dataframe objects into a function in Python. x = pd.Dataframe() def function(z): "code" return result result = function(x) As a beginner in Python, I would appreciate some guidance on this issue. ...

What makes node_modules bulky while Python dependencies are more lightweight?

Having recently started learning JavaScript, I couldn't help but notice that when I install libraries using npm, the node_modules folder ends up quite large and it takes a considerable amount of time. This contrasts with my experience in Python, where ...

New Syntax in Tensorflow 2.0

Here is some code that I am trying to run, written using the syntax of tensorflow 1.0: import tensorflow as tf a = tf.constant(5) b = tf.constant(2) c = tf.constant(3) d = tf.multiply(a,b) e = tf.add(b,c) f = tf.subtract(d,e) with tf.Session() as sess: ...

Executing code in a specific directory using Python's subprocess module

Attempting to execute a subprocess. Running a Python script in a specific directory to convert each file inside the directory. The conversion process is successful and now integrating it into a PYQT4 GUI. Below is what has been developed so far: def selec ...

What can be done to ensure that column names in a dataframe do not automatically change after performing a merge or join

I'm encountering an issue in Python 3.8 where my dataframe columns are automatically changing to (column name,) after using join or merge. I've tried using join, merge, and concat but they all result in the same problem :(( Here are some images ...

Tips for successfully including the command 'yes' in a Python script while running it within a tmux session

Looking for guidance on running a bash script in tmux that executes a Python script and prompts for two y/n responses. Below is the original script: #!/bin/sh tmux new-session -d -s new_session 'python3 build.py /data/build/' I attempted passin ...

Loop through the index and add the function component to it

I'm looking to update the index in this code snippet. Instead of using 'close' as the index, I want to use the corresponding x from the function. In some cases, like this one, there are only 3 available items even though I provide 4 curr. Th ...

Is it possible to utilize a Python Selenium dictionary to create a more generalized xpath for a locator class

Is it feasible to consolidate multiple XPaths into a single 'general XPath' using a Python dictionary? In a locators class, I aim to identify all elements in a formula for automated data input (in the context of testing automation). For each fiel ...

Creating a large data frame using multiple dictionaries

Attempting to create a data frame by converting multiple dictionaries within a list. dictlist This is the output of the list: [{'subject': projectmanagementplan, 'link': [provides], 'object': areas}, {'subject': hi ...

Guide to upgrading selenium to version 3.9 using conda

Can anyone guide me on updating selenium to version 3.9 using conda? I tried installing selenium through pip with no success, so I resorted to installing it via Anaconda command prompt. However, I specifically need the selenium version to be 3.9. ...