如何根据计算结果制作清单?
How to make the list from the result of calculation?
我研究了 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()
我认为我使用了 for
或 while
语句。
但是,这并不容易。首先,我制作了关于 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))
根据问题,我猜你想将距离文本渲染到例如左上角。
首先,我修改了Planet
class的__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-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))
#-----------------------------------------------------------------------------------------------
索引参数由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()
在这里,如果你真的想使用每个行星和太阳之间的距离,我创建了一个字典,其中的键是每个行星;值是距离。
Click Here to see the Result
完整代码:
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()
我研究了 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()
我认为我使用了 for
或 while
语句。
但是,这并不容易。首先,我制作了关于 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))
根据问题,我猜你想将距离文本渲染到例如左上角。
首先,我修改了Planet
class的__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-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))
#-----------------------------------------------------------------------------------------------
索引参数由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()
在这里,如果你真的想使用每个行星和太阳之间的距离,我创建了一个字典,其中的键是每个行星;值是距离。
Click Here to see the Result
完整代码:
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()