Pygame使一个圆圈围绕另一个旋转

时间:2016-06-29 18:00:25

标签: python rotation position geometry pygame

我想用pygame制作某种太阳能系统。我设法做了一个固定的,但我认为做一个行星围绕太阳行星和卫星绕行星等更有意思。有没有办法可以做到这一点(如果可能的话,使用pygame)?< / p>

我想要的是:

Sun = pygame.draw.circle(...)
planet1 = pygame.draw.circle(...)
etc.

a = [planet1, planet2, ...]

for p in a:
    move p[2] to pos(x, y)

这是我认为可行的,但我不知道该怎么做。此外,我已经考虑过删除这个古老的星球,并在它旁边画一个新的星球,但问题是我使用随机特征(如颜色,到太阳的距离,系统中的行星数量等) 。)它必须保持这些相同的功能。有任何想法吗?

提前致谢!

2 个答案:

答案 0 :(得分:1)

你可以用牛顿万有引力定律和牛顿第二定律来实现引力,以获得行星的加速度。给每个行星一个初始位置,速度和质量。加速度是速度a = v * dt的变化,速度是位置v = r * dt的变化,因此我们可以整合以找到速度和位置。

万有引力F = G * m1 * m2 / r ** 2其中F是物体上力的大小,G是引力常数m1m2是对象的质量,r是两个对象之间的距离。

牛顿第二定律F = m1 * a其中a是加速度。

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 

这可以产生圆形和椭圆形轨道。创建轨道月球需要非常小的时间步长(dt)才能进行数值积分。

注意:由于数字集成的限制,这种方法略有不准确。

这里的pygame示例实现,包括围绕太阳,月亮和基本轨道转移的三个行星。 https://github.com/c2huc2hu/orbital_mechanics

答案 1 :(得分:0)

相对于X轴绕太阳旋转一定角度的行星的坐标是enter image description here,其中 private class AsyncDataClass extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... params) { String responseBody = ""; HttpParams httpParameters = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(httpParameters, 5000); HttpConnectionParams.setSoTimeout(httpParameters, 5000); HttpClient httpClient = new DefaultHttpClient(httpParameters); HttpPost httpPost = new HttpPost(params[0]); String jsonResult = ""; try { HttpResponse response = httpClient.execute(httpPost); jsonResult = inputStreamToString(response.getEntity().getContent()).toString(); System.out.println("Returned Json object " + jsonResult.toString()); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return jsonResult; } @Override protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(ctx); pDialog.setMessage("Please wait..."); pDialog.setCancelable(true); pDialog.show(); } @Override protected void onPostExecute(String result) { super.onPostExecute(result); System.out.println("Resulted Value: " + result); if(result.equals("") || result == null){ Toast.makeText(ctx, "Server connection failed", Toast.LENGTH_LONG).show(); } int jsonResult = returnParsedJsonObject(result); if(jsonResult == -1){ Toast.makeText(ctx, "Sorry No Places Found", Toast.LENGTH_LONG).show(); } if(jsonResult == 1){ //Toast.makeText(ctx, "", Toast.LENGTH_LONG).show(); try { JSONObject jsonObj = new JSONObject(result); // Getting JSON Array node places = jsonObj.getJSONArray("result"); // looping through All Contacts for (int i = 0; i < places.length(); i++) { JSONObject place = places.getJSONObject(i); // String slot = c.getString(TAG_SLOT); // serverReturn.add(slot); UserPlaces placeFroServer = new UserPlaces(); placeFroServer.setId(place.getString(TAG_PID)); placeFroServer.setName(place.getString(TAG_PNAME)); placeFroServer.setDescription(place.getString(TAG_DESC)); placeFroServer.setImg(place.getString(TAG_IMG)); placeFroServer.setLat(place.getString(TAG_LAT)); placeFroServer.setLng(place.getString(TAG_LNG)); placesList.add(placeFroServer); } UserPlaces myPlace = placesList.get(counter); pid=myPlace.getId(); lat = myPlace.getLat(); lng = myPlace.getLng(); Picasso.with(ctx).load(myPlace.getImg()).into(new Target() { @Override public void onPrepareLoad(Drawable arg0) { // TODO Auto-generated method stub } @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom arg1) { // TODO Auto-generated method stub Toast.makeText(ctx,"Loaded",Toast.LENGTH_LONG).show(); pImg.setBackgroundDrawable(new BitmapDrawable(ctx.getResources(), bitmap)); pImg.invalidate(); } @Override public void onBitmapFailed(Drawable arg0) { // TODO Auto-generated method stub Toast.makeText(ctx, "Failed Loading", Toast.LENGTH_SHORT).show(); } }); pname.setText(myPlace.getName()); pdes.setText(myPlace.getDescription()); rl.setVisibility(View.VISIBLE); counter++; } catch (JSONException e) { String ex = e.getMessage(); e.printStackTrace(); } } if (pDialog.isShowing()) pDialog.dismiss(); } private StringBuilder inputStreamToString(InputStream is) { String rLine = ""; StringBuilder answer = new StringBuilder(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); try { while ((rLine = br.readLine()) != null) { answer.append(rLine); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return answer; } } 是到太阳的距离,r就是那个角度,而theta是太阳的坐标。以(a, b)为中心绘制圆圈。

编辑: 一般椭圆轨道:

enter image description here

哪里

enter image description here

(x, y)是具有相同角动量的圆形轨道的半径,r0是椭圆的“偏心率”