Pygame make a circle rotate around another

被刻印的时光 ゝ 提交于 2021-01-28 07:05:51

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!