问题
I would like to make some kind of solar system in pygame. I've managed to do a fixed one but I thought it would be more interesting to do one with planets moving around the sun and moons around planets etc. Is there a way I could do that (using pygame if possible)?
What I would like is :
Sun = pygame.draw.circle(...)
planet1 = pygame.draw.circle(...)
etc.
a = [planet1, planet2, ...]
for p in a:
move p[2] to pos(x, y)
That is what I think would work but I'm not sure how to do it. Also, I've thought about deleting the ancient planet and drawing a new one right next to it, but problem is I'm using random features (like colours, distance to the sun, number of planets in the system etc.) and it would have to keep these same features. Any ideas?
Thanks in advance!
回答1:
You can implement gravity with Newton's Law of Universal Gravitation and Newton's Second Law to get the accelerations of the planets. Give each planet an initial position, velocity and mass. Acceleration is change in velocity a = v * dt
, velocity is change in position v = r * dt
, so we can integrate to find velocity and position.
Universal gravitation: F = G * m1 * m2 / r ** 2
where F
is the magnitude of the force on the object, G
is the gravitational constant, m1
and m2
are the masses of the objects and r
is the distance between the two objects.
Newton's Second Law: F = m1 * a
where a is the acceleration.
dt = 0.01 # size of time step
G = 100 # gravitational constant
def calcGravity(sun, planet):
'Returns acceleration of planet with respect to the sun'
diff_x = sun.x - planet.x
diff_y = sun.y - planet.y
acceleration = G * sun.mass / (diff_x ** 2 + diff_y ** 2)
accel_x = acceleration * diff_x / (diff_x ** 2 + diff_y ** 2)
accel_y = acceleration * diff_y / (diff_x ** 2 + diff_y ** 2)
return accel_x, accel_y
while True:
# update position based on velocity
planet.x += planet.vel_x * dt
planet.y += planet.vel_y * dt
# update velocity based on acceleration
accel_x, accel_y = calcGravity(sun, planet)
planet.vel_x += accel_x * dt
planet.vel_y += accel_y * dt
This can produce circular and elliptical orbits. Creating an orbiting moon requires a very small timestep (dt) for the numeric integration.
Note: this approach is subtly inaccurate due to the limits of numeric integration.
Sample implementation in pygame here, including three planets revolving around a sun, a moon, and a basic orbital transfer. https://github.com/c2huc2hu/orbital_mechanics
回答2:
Coordinates of a planet rotated about the Sun through some angle with respect to the X-axis are , where r
is the distance to the Sun, theta
is that angle, and (a, b)
are the coordinates of the sun. Draw your circle centered at (x, y)
.
EDIT: General elliptical orbit:
Where
r0
is the radius of a circular orbit with the same angular momentum, and e
is the "eccentricity" of the ellipse
来源:https://stackoverflow.com/questions/38106957/pygame-make-a-circle-rotate-around-another