我想用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)
这是我认为可行的,但我不知道该怎么做。此外,我已经考虑过删除这个古老的星球,并在它旁边画一个新的星球,但问题是我使用随机特征(如颜色,到太阳的距离,系统中的行星数量等) 。)它必须保持这些相同的功能。有任何想法吗?
提前致谢!
答案 0 :(得分:1)
你可以用牛顿万有引力定律和牛顿第二定律来实现引力,以获得行星的加速度。给每个行星一个初始位置,速度和质量。加速度是速度a = v * dt
的变化,速度是位置v = r * dt
的变化,因此我们可以整合以找到速度和位置。
万有引力:F = G * m1 * m2 / r ** 2
其中F
是物体上力的大小,G
是引力常数m1
和m2
是对象的质量,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轴绕太阳旋转一定角度的行星的坐标是,其中 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)
为中心绘制圆圈。
编辑: 一般椭圆轨道:
哪里
(x, y)
是具有相同角动量的圆形轨道的半径,r0
是椭圆的“偏心率”