CS61B 学习笔记 proj0:NBody Simulation
作者:互联网
proj0介绍
Planet类构造器
public class Planet {
public double xxPos;
public double yyPos;
public double xxVel;
public double yyVel;
public double mass;
public String imgFileName;
public Planet(double xP, double yP, double xV, double yV, double m, String img) {
xxPos = xP;
yyPos = yP;
xxVel = xV;
yyVel = yV;
mass = m;
imgFileName = img;
}
public Planet(Planet p) {
xxPos = p.xxPos;
yyPos = p.yyPos;
xxVel = p.xxVel;
yyVel = p.yyVel;
mass = p.mass;
imgFileName = p.imgFileName;
}
}
物理理解
引力常数:
\[G = 6.67·10^{-11} \frac {Nm^2}{kg^2} \]引力:
\[F = \frac {G·m_1·m_2} {r^2} \]编写Planet类
-
计算行星之间的距离
calcDistance
public double calcDistance(Planet p) { double distanceX = p.xxPos - xxPos; double distanceY = p.yyPos - yyPos; double r = Math.sqrt(distanceX * distanceX + distanceY * distanceY); return r; }
开方:
Math.sqrt()
-
计算行星之间的引力
calcForceExertedBy
-
计算x方向和y方向的引力
calcForceExertedByX
和calcForceExertedByY
-
计算x方向和y方向的合力
calcNetForceExertedByX
和calcNetForceExertedByY
public double calcNetForceExertedByX(Planet[] allPlanets) { double netForceX = 0.0; for (Planet planet : allPlanets) { if (!(this.equals(planet))) { netForceX += this.calcForceExertedByX(planet); } } return netForceX; } public double calcNetForceExertedByY(Planet[] allPlanets) { double netForceY = 0.0; for (Planet planet : allPlanets) { if (!(this.equals(planet))) { netForceY += this.calcForceExertedByY(planet); } } return netForceY; }
-
更新 传入时间dt、x方向的力、y方向的力
计算加速度、新速度、新位置
public void update(double dt, double fX, double fY) { double accX = fX / mass; double accY = fY / mass; xxVel += dt * accX; yyVel += dt * accY; xxPos += dt * xxVel; yyPos += dt * yyVel; }
模拟器NBody.java
-
readRadius 返回半径
-
readPlanets 返回对象列表
返回类型:
Planet[]
创建对象列表:
Planet[] planets = new Planet[number]
创建对象:
planets[i] = new Planet(xP, yP, xV, yV, m, img)
public static Planet[] readPlanets(String fileName) { In in = new In(fileName); int number = in.readInt(); double radius = in.readDouble(); Planet[] planets = new Planet[number]; for (int i = 0; i < number; i++) { double xP = in.readDouble(); double yP = in.readDouble(); double xV = in.readDouble(); double yV = in.readDouble(); double m = in.readDouble(); String img = in.readString(); planets[i] = new Planet(xP, yP, xV, yV, m, img); } return planets; }
Checking readPlanets... PASS: readPlanets(); Congrats! This was the hardest test!
绘制宇宙初始状态 (main)
类型转换:double x = Double.parseDouble()
-
收集输入
-
绘制背景
将
starfield.jpg
传入StdDraw.picture()
-
绘制一个行星
在
Planet.java
中添加draw
方法 -
绘制所有行星
通过for循环调用
draw
方法,可以得到下图
创建动画
- 创建时间变量time,默认为0,while循环直到time达到T
- 创建
xForces
数组和yForces
数组 - 计算每个行星受到的引力合力
- 调用update方法更新每个行星的位置速度和加速度
- 绘制背景图
- 绘制所有行星
- 调用
StdDraw.show()
- 调用
StdDraw.pause(10)
- 将时间变量增加dt
动态截图:
打印最终状态
用于打分(provided):
StdOut.printf("%d\n", planets.length);
StdOut.printf("%.2e\n", radius);
for (int i = 0; i < planets.length; i++) {
StdOut.printf("%11.4e %11.4e %11.4e %11.4e %11.4e %12s\n",
planets[i].xxPos, planets[i].yyPos, planets[i].xxVel,
planets[i].yyVel, planets[i].mass, planets[i].imgFileName);
}
提交
问题:引力常数需要设置为private
修改后通过:
github: https://github.com/ikventure/cs61b-sp18-logs/tree/master/proj0
标签:yyPos,proj0,double,CS61B,Simulation,Planet,planets,xxPos,public 来源: https://www.cnblogs.com/ikventure/p/15430718.html