如何从计算结果中列出列表?

发布于 2025-01-18 08:49:32 字数 4725 浏览 0 评论 0原文

我从YouTube研究了以下代码。

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_width()/2))

我想知道self.distance_to_sun的结果值很多。 我想在屏幕上,而不是地球上显示结果的值。 如何提取每个距离的值取决于每个行星? 我找不到路。

import pygame
import math
import os
pygame.init()
WIDTH, HEIGHT = 800, 800
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Planet Simulation")

WHITE = (255, 255, 255)
YELLOW = (255, 255, 0)
BLUE = (100, 149, 237) # Light Blue
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 = 200 / AU
    TIMESTEP = 3600 * 24
    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_width()/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, RED, 1.98855 * 10**30)
    sun.sun = True
    mercury = Planet(0.387 * Planet.AU, 0, 5, DARK_GREY, 3.302 * 10**23)
    mercury.y_vel = -47.4 * 1000
    venus = Planet(0.723 * Planet.AU, 0, 11, WHITE, 4.8685 * 10**24)
    venus.y_vel = -35.02 * 1000
    earth = Planet(-1 * Planet.AU, 0, 12, BLUE, 5.9736 * 10**24)
    earth.y_vel = 29.783 * 1000
    mars = Planet(-1.524 * Planet.AU, 0, 7, RED, 6.4171 * 10**23)
    mars.y_vel = 24.077 * 1000
    planets = [sun, mercury, venus, earth, mars]

    while run:
        clock.tick(60)
        screen.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(screen)
        pygame.display.update()
    pygame.quit()
main()

我认为我在语句中使用或。 但是,这并不容易。首先,我列出了有关self.distance_to_sun的空列表 而且,我遇到了墙。我对解决方案做出了更多的想法。

if not self.sun:
    distance_text = FONT.render(f"{round(self.distance_to_sun/1000,1):,}km", 1, WHITE)
    distance_text = [] # <<-- How to extract and make the list from the result of calculation
                       #      as like the self.distance_to_sun?
    while ....?
    for...?
    # and then, I want to display that
    win.blit(mercury_distance_text, (100, 100))
    win.blit(venus_distance_text, (150, 100))
    win.blit(earth_distance_text, (200, 100))
    win.blit(mars_distance_text, (250, 100))

I studied the below code from Youtube.

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_width()/2))

I wonder that self.distance_to_sun's result values are so many.
I want to display the value of result on screen, not on the planet.
How to extract each the value of distance depend on the each planet?
I can't find the way.

import pygame
import math
import os
pygame.init()
WIDTH, HEIGHT = 800, 800
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Planet Simulation")

WHITE = (255, 255, 255)
YELLOW = (255, 255, 0)
BLUE = (100, 149, 237) # Light Blue
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 = 200 / AU
    TIMESTEP = 3600 * 24
    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_width()/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, RED, 1.98855 * 10**30)
    sun.sun = True
    mercury = Planet(0.387 * Planet.AU, 0, 5, DARK_GREY, 3.302 * 10**23)
    mercury.y_vel = -47.4 * 1000
    venus = Planet(0.723 * Planet.AU, 0, 11, WHITE, 4.8685 * 10**24)
    venus.y_vel = -35.02 * 1000
    earth = Planet(-1 * Planet.AU, 0, 12, BLUE, 5.9736 * 10**24)
    earth.y_vel = 29.783 * 1000
    mars = Planet(-1.524 * Planet.AU, 0, 7, RED, 6.4171 * 10**23)
    mars.y_vel = 24.077 * 1000
    planets = [sun, mercury, venus, earth, mars]

    while run:
        clock.tick(60)
        screen.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(screen)
        pygame.display.update()
    pygame.quit()
main()

I think that I use the for or while statement.
but, it is not easy. First I made the empty list about the self.distance_to_sun
and, I meet the wall. I can't think more anything for the solution.

if not self.sun:
    distance_text = FONT.render(f"{round(self.distance_to_sun/1000,1):,}km", 1, WHITE)
    distance_text = [] # <<-- How to extract and make the list from the result of calculation
                       #      as like the self.distance_to_sun?
    while ....?
    for...?
    # and then, I want to display that
    win.blit(mercury_distance_text, (100, 100))
    win.blit(venus_distance_text, (150, 100))
    win.blit(earth_distance_text, (200, 100))
    win.blit(mars_distance_text, (250, 100))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心碎的声音 2025-01-25 08:49:32

从这个问题来看,我猜您想将距离文本渲染到例如左上角。

首先,我修改了 Planet 类的 __init__ 函数,以便您可以传入名称,并添加了 __hash__ 字典。

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

def __hash__(self) -> int:
        return hash(self.name)

然后,在draw函数中,传入一个index参数,来控制y轴偏移。

 def draw(self, win, index):
        ...
        #-----------------------------------------------------------------------------------------------
        if not self.sun:
            distance_text = FONT.render(f"{self.name}: {round(self.distance_to_sun/1000, 1):,}km", 1, WHITE)
            win.blit(distance_text, (10, 10 + index * 20))
        #-----------------------------------------------------------------------------------------------

索引参数由 main() 中的枚举 for 循环提供:

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

    sun = Planet(0, 0, 30, RED, 1.98855 * 10**30, "Sun")
    sun.sun = True
    mercury = Planet(0.387 * Planet.AU, 0, 5, DARK_GREY, 3.302 * 10**23, "Mercury")
    mercury.y_vel = -47.4 * 1000
    venus = Planet(0.723 * Planet.AU, 0, 11, WHITE, 4.8685 * 10**24, "Venus")
    venus.y_vel = -35.02 * 1000
    earth = Planet(-1 * Planet.AU, 0, 12, BLUE, 5.9736 * 10**24, "Earth")
    earth.y_vel = 29.783 * 1000
    mars = Planet(-1.524 * Planet.AU, 0, 7, RED, 6.4171 * 10**23, "Mars")
    mars.y_vel = 24.077 * 1000
    planets_and_distance = {sun: None, mercury: None, venus: None, earth: None, mars: None}

    while run:
        clock.tick(60)
        screen.fill((0, 0, 0))
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
        
        copy_of_dict = dict(planets_and_distance)
        for planet_count, planet in enumerate(planets_and_distance):
            planet.update_position(planets_and_distance.keys())
            planet.draw(screen, planet_count)
            if planet.sun:
                continue
            copy_of_dict[planet] = (planet.distance_to_sun)
        planets_and_distance = dict(copy_of_dict)

        pygame.display.update()
    pygame.quit()

在这里,如果您确实想使用每个行星和太阳之间的距离,我创建了一个字典,其键是每个行星;其值是距离。

单击此处查看结果


完整代码:

import pygame
import math
import os
pygame.init()
WIDTH, HEIGHT = 800, 800
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Planet Simulation")

WHITE = (255, 255, 255)
YELLOW = (255, 255, 0)
BLUE = (100, 149, 237) # Light Blue
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 = 200 / AU
    TIMESTEP = 3600 * 24
    def __init__(self, x, y, radius, color, mass, name):
        self.x = x
        self.y = y
        self.radius = radius
        self.color = color
        self.mass = mass
        self.name = name

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

        self.x_vel = 0
        self.y_vel = 0

    def __hash__(self) -> int:
        return hash(self.name)

    def draw(self, win, index):
        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"{self.name}: {round(self.distance_to_sun/1000, 1):,}km", 1, WHITE)
            win.blit(distance_text, (10, 10 + index * 20))
        #-----------------------------------------------------------------------------------------------

    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, RED, 1.98855 * 10**30, "Sun")
    sun.sun = True
    mercury = Planet(0.387 * Planet.AU, 0, 5, DARK_GREY, 3.302 * 10**23, "Mercury")
    mercury.y_vel = -47.4 * 1000
    venus = Planet(0.723 * Planet.AU, 0, 11, WHITE, 4.8685 * 10**24, "Venus")
    venus.y_vel = -35.02 * 1000
    earth = Planet(-1 * Planet.AU, 0, 12, BLUE, 5.9736 * 10**24, "Earth")
    earth.y_vel = 29.783 * 1000
    mars = Planet(-1.524 * Planet.AU, 0, 7, RED, 6.4171 * 10**23, "Mars")
    mars.y_vel = 24.077 * 1000
    planets_and_distance = {sun: None, mercury: None, venus: None, earth: None, mars: None}

    while run:
        clock.tick(60)
        screen.fill((0, 0, 0))
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
        
        copy_of_dict = dict(planets_and_distance)
        for planet_count, planet in enumerate(planets_and_distance):
            planet.update_position(planets_and_distance.keys())
            planet.draw(screen, planet_count)
            if planet.sun:
                continue
            copy_of_dict[planet] = (planet.distance_to_sun)
        planets_and_distance = dict(copy_of_dict)

        pygame.display.update()
    pygame.quit()
main()

From the question, I'm guessing you want to render the distance text to, for example, left top corner.

First, I modified the __init__ function of Planet class so you can pass in a name, and added __hash__ for dictionary.

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

def __hash__(self) -> int:
        return hash(self.name)

Then, in the draw function, pass in an index parameter, to control the y-offset.

 def draw(self, win, index):
        ...
        #-----------------------------------------------------------------------------------------------
        if not self.sun:
            distance_text = FONT.render(f"{self.name}: {round(self.distance_to_sun/1000, 1):,}km", 1, WHITE)
            win.blit(distance_text, (10, 10 + index * 20))
        #-----------------------------------------------------------------------------------------------

The index parameter is provided with the enumerate for loop in main():

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

    sun = Planet(0, 0, 30, RED, 1.98855 * 10**30, "Sun")
    sun.sun = True
    mercury = Planet(0.387 * Planet.AU, 0, 5, DARK_GREY, 3.302 * 10**23, "Mercury")
    mercury.y_vel = -47.4 * 1000
    venus = Planet(0.723 * Planet.AU, 0, 11, WHITE, 4.8685 * 10**24, "Venus")
    venus.y_vel = -35.02 * 1000
    earth = Planet(-1 * Planet.AU, 0, 12, BLUE, 5.9736 * 10**24, "Earth")
    earth.y_vel = 29.783 * 1000
    mars = Planet(-1.524 * Planet.AU, 0, 7, RED, 6.4171 * 10**23, "Mars")
    mars.y_vel = 24.077 * 1000
    planets_and_distance = {sun: None, mercury: None, venus: None, earth: None, mars: None}

    while run:
        clock.tick(60)
        screen.fill((0, 0, 0))
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
        
        copy_of_dict = dict(planets_and_distance)
        for planet_count, planet in enumerate(planets_and_distance):
            planet.update_position(planets_and_distance.keys())
            planet.draw(screen, planet_count)
            if planet.sun:
                continue
            copy_of_dict[planet] = (planet.distance_to_sun)
        planets_and_distance = dict(copy_of_dict)

        pygame.display.update()
    pygame.quit()

Here, in case you really want to use the distance between each planet and sun, I created a dictionary which the key, is each planet; and the value, is distance.

Click Here to see the Result


Full Code:

import pygame
import math
import os
pygame.init()
WIDTH, HEIGHT = 800, 800
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Planet Simulation")

WHITE = (255, 255, 255)
YELLOW = (255, 255, 0)
BLUE = (100, 149, 237) # Light Blue
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 = 200 / AU
    TIMESTEP = 3600 * 24
    def __init__(self, x, y, radius, color, mass, name):
        self.x = x
        self.y = y
        self.radius = radius
        self.color = color
        self.mass = mass
        self.name = name

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

        self.x_vel = 0
        self.y_vel = 0

    def __hash__(self) -> int:
        return hash(self.name)

    def draw(self, win, index):
        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"{self.name}: {round(self.distance_to_sun/1000, 1):,}km", 1, WHITE)
            win.blit(distance_text, (10, 10 + index * 20))
        #-----------------------------------------------------------------------------------------------

    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, RED, 1.98855 * 10**30, "Sun")
    sun.sun = True
    mercury = Planet(0.387 * Planet.AU, 0, 5, DARK_GREY, 3.302 * 10**23, "Mercury")
    mercury.y_vel = -47.4 * 1000
    venus = Planet(0.723 * Planet.AU, 0, 11, WHITE, 4.8685 * 10**24, "Venus")
    venus.y_vel = -35.02 * 1000
    earth = Planet(-1 * Planet.AU, 0, 12, BLUE, 5.9736 * 10**24, "Earth")
    earth.y_vel = 29.783 * 1000
    mars = Planet(-1.524 * Planet.AU, 0, 7, RED, 6.4171 * 10**23, "Mars")
    mars.y_vel = 24.077 * 1000
    planets_and_distance = {sun: None, mercury: None, venus: None, earth: None, mars: None}

    while run:
        clock.tick(60)
        screen.fill((0, 0, 0))
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
        
        copy_of_dict = dict(planets_and_distance)
        for planet_count, planet in enumerate(planets_and_distance):
            planet.update_position(planets_and_distance.keys())
            planet.draw(screen, planet_count)
            if planet.sun:
                continue
            copy_of_dict[planet] = (planet.distance_to_sun)
        planets_and_distance = dict(copy_of_dict)

        pygame.display.update()
    pygame.quit()
main()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文