作业链接:sp18 NBody
ac 图
1. 学到的知识点
I. 类外面的常量定义
类比 c ++ 的 const type 关键字,在类内,java 则用static final, 本次作业中用的是
private static final G =6.67e-11
II. 迷信计数法的示意
对于迷信计数法,比方 6.67×10^(-11), 前面的 x10^(-11)写成 e -11,AeN 示意 Ax10^N
正的指数 1 ×10^7, 则写成 1e7。
III. 规范输出库 Std.in
用来读取文件,
1. 构造函数初始化 In in = new In(parameter);
2.parameter 传入文件门路,比方 planets.txt
3. 初始化实现后即可调用库函数,包含:
in.readInt() 读入整数
in.readDouble() 读入 Double
in.readString() 读入 String
4. 留神读数据是从上到下一行一行顺次读,比方
5
2.50e+11
1.4960e+11 0.0000e+00 0.0000e+00 2.9800e+04 5.9740e+24 earth.gif
2.2790e+11 0.0000e+00 0.0000e+00 2.4100e+04 6.4190e+23 mars.gif
5.7900e+10 0.0000e+00 0.0000e+00 4.7900e+04 3.3020e+23 mercury.gif
0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 1.9890e+30 sun.gif
1.0820e+11 0.0000e+00 0.0000e+00 3.5000e+04 4.8690e+24 venus.gif
第一行是整数,第二行是 double,不能跳过读整数间接去读 Double,也就是你必须首先定义一个变量
int first = in.readInt();
之后能力读 Double,都是一一对应的。
IV 规范输入库 StdOut
1.println()输入换行
2.print() 输入不换行
3.printf() 外面能够加格局,相似 c 语言 printf()
4.printf() 最简略的模式有两个参数。第一个参数称为格局字符串。它蕴含一个转换标准,形容如何将第二个参数转换为字符串以供输入。
格局字符串以 % 结尾,以一个字母的转换代码结尾。下表总结了最罕用的代码:
V StdDraw 规范库
1. 具体可查看 Stanford Std Library
蕴含一些 java 的可视化绘图
比方 StdDraw.picture(x,y,img); 等等
2. 开启 Animation(动画成果)
StdDraw.enableDoubleBuffering();
之后所有画布上的内容都在 offcanvas 上进行,直到调用
StdDraw.show() 才会显示在 oncanvas 上
擦除:StdDraw.clear();
暂停:StdDraw.pause(time);time 单位为毫秒,填 number
3. 音频 StdAudio
VI 构造函数的两种定义方法
比方有一个 Dog 类
public class Dog{
public String name;
public int age;
}
第一种构造函数
public Dog(String _name,int _age){
name=_name;
age=_age;
}
main 外面调用是 Dog mydog = new dog("funny",5);
第二种构造函数
public Dog(Dog d){this(d.name,d.age);
}
第二种构造函数是间接传入一个类的实例,main 外面调用是Dog d2=new Dog(d1);
源码
1.Planet.java 代码
public class Planet{
public double xxPos;
public double yyPos;
public double xxVel;
public double yyVel;
public double mass;
public String imgFileName;
private static final double G = 6.67e-11;
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){this(p.xxPos,p.yyPos,p.xxVel,p.yyVel,p.mass,p.imgFileName);
}
public double calcDistance(Planet p){return Math.pow((Math.pow((this.xxPos-p.xxPos),2)+Math.pow((this.yyPos-p.yyPos),2)),1.0/2);
}
public double calcForceExertedBy(Planet p){return (this.mass*p.mass*G)/Math.pow(this.calcDistance(p),2);
}
public double calcForceExertedByX(Planet p){return this.calcForceExertedBy(p)*(p.xxPos-this.xxPos)/this.calcDistance(p);
}
public double calcForceExertedByY(Planet p){return this.calcForceExertedBy(p)*(p.yyPos-this.yyPos)/this.calcDistance(p);
}
public double calcNetForceExertedByX(Planet[] p){
double NetExertedByX=0;
for(int i=0;i<p.length;i++){if(!this.equals(p[i])){NetExertedByX+=this.calcForceExertedByX(p[i]);
}
}
return NetExertedByX;
}
public double calcNetForceExertedByY(Planet[] p){
double NetExertedByY=0;
for(int i=0;i<p.length;i++){if(!this.equals(p[i])){NetExertedByY+=this.calcForceExertedByY(p[i]);
}
}
return NetExertedByY;
}
public void update(double dt,double fX,double fY){
double aX=0,aY=0;
aX=fX/this.mass;
aY=fY/this.mass;
this.xxVel=this.xxVel+aX*dt;
this.yyVel=this.yyVel+aY*dt;
this.xxPos=this.xxPos+this.xxVel*dt;
this.yyPos=this.yyPos+this.yyVel*dt;
}
public void draw(){StdDraw.picture(this.xxPos,this.yyPos,"images/"+this.imgFileName);
}
}
2.NBody.java 代码
public class NBody{public static double readRadius(String path){In in =new In(path);
int firstinteger=in.readInt();
double ReadRadius=in.readDouble();
return ReadRadius;
}
public static Planet[] readPlanets(String path){In in=new In(path);
int numbersum=in.readInt();
Planet[] p =new Planet[numbersum];
double ReadRadius=in.readDouble();
for(int i=0;i<numbersum;i++){double xxPos=in.readDouble();
double yyPos=in.readDouble();
double xxVel=in.readDouble();
double yyVel=in.readDouble();
double mass=in.readDouble();
String img=in.readString();
p[i]= new Planet(xxPos,yyPos,xxVel,yyVel,mass,img);
}
return p;
}
public static void main(String[] args){double T=Double.parseDouble(args[0]);
double dt=Double.parseDouble(args[1]);
String filename=args[2];
double R=readRadius(filename);
Planet[] p=readPlanets(filename);
StdDraw.enableDoubleBuffering();
for(int t=0;t<=T;t+=dt){double xForce[]=new double[5];
double yForce[]=new double[5];
for(int i=0;i<p.length;i++){xForce[i]=p[i].calcNetForceExertedByX(p);
yForce[i]=p[i].calcNetForceExertedByY(p);
}
for(int j=0;j<p.length;j++){p[j].update(dt,xForce[j],yForce[j]);
}
String img="images/starfield.jpg";
StdDraw.setScale(-R,R);
StdDraw.clear();
StdDraw.picture(0,0,img);
for(int k=0;k<p.length;k++){p[k].draw();}
StdDraw.show();
StdDraw.pause(10);
}
StdOut.printf("%d\n", p.length);
StdOut.printf("%.2e\n", R);
for (int i = 0; i < p.length; i++) {
StdOut.printf("%11.4e %11.4e %11.4e %11.4e %11.4e %12s\n",
p[i].xxPos, p[i].yyPos, p[i].xxVel,
p[i].yyVel, p[i].mass, p[i].imgFileName);
}
}
}