一亩三分地论坛

 找回密码
 获取更多干货,去instant注册!

扫码关注一亩三分地公众号
查看: 2007|回复: 30
收起左侧

[CS61B_Spring 2015] HW1 加分讨论帖

[复制链接] |试试Instant~ |关注本帖
hurricane_e 发表于 2015-5-28 04:06:46 | 显示全部楼层 |阅读模式

[其他]CS61B Data Structure #14 - 2015-05-25@Berkeley

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看,没有帐号?获取更多干货,去instant注册!

x
HW1: NBody Simulation
baiery 发表于 2015-6-3 00:56:07 | 显示全部楼层
楼楼我卡在Update这个方法上了,你做了嘛?我感觉目前只有咱们俩在坚持了。。。
回复 支持 反对

使用道具 举报

karte_polo 发表于 2015-6-3 19:42:34 | 显示全部楼层
Planet.java



public class Planet {
        public static double g = 6.67/Math.pow(10,11);
        public double x;
        public double y;
        public double xVelocity;
        public double yVelocity;
        public double mass;
        public String img;
        public double xNetForce;
        public double yNetForce;
        public double xAccel;
        public double yAccel;
        public Planet(double xp,double yp,double xv,double yv, double m, String s){
                this.x = xp;
                this.y = yp;
                this.xVelocity = xv;
                this.yVelocity = yv;
                this.mass = m;
                this.img = s;
        }
        public double calcDistance(Planet p){
                double xdis = this.x - p.x;
                double ydis = this.y - p.y;
                return Math.sqrt(xdis*xdis+ydis*ydis);
        }
        public double calcPairwiseForce(Planet p){
                double dis = this.calcDistance(p);
                return g*this.mass*p.mass/(dis*dis);
        }
        public double calcPairwiseForceX(Planet p){
                double dis = this.calcDistance(p);
                return calcPairwiseForce(p)*(p.x-this.x)/dis;
        }
        public double calcPairwiseForceY(Planet p){
                double dis = this.calcDistance(p);
                return calcPairwiseForce(p)*(p.y-this.y)/dis;
        }
        public void setNetForce(Planet[] ps){
                int l = ps.length;
                this.xNetForce = 0;
                this.yNetForce = 0;
                for (int n=0; n<l;n++){
                        if (this != ps[n]){
                                this.xNetForce+= calcPairwiseForceX(ps[n]);
                                this.yNetForce+= calcPairwiseForceY(ps[n]);
                        }       
                }
        }
        public void draw(){
                StdDraw.picture(this.x,this.y,"images/"+this.img);
        }
        public void update(double dt){
                xAccel = xNetForce/mass;
                yAccel = yNetForce/mass;
                xVelocity +=dt*xAccel;
                yVelocity +=dt*yAccel;
                x +=dt*xVelocity;
                y +=dt*yVelocity;
        }
       

}



NBody.java:

import java.io.*;
import java.util.Scanner;
public class NBody {

        public static void main(String[] args) {
                // TODO Auto-generated method stub
                double T,dt,R,time;
                String filename;
                int num;
                Planet p;
                Scanner s = new Scanner(System.in);
                T = s.nextDouble();
                dt =s.nextDouble();
                filename = s.next();
                In in = new In(filename);
                num = in.readInt();
                R = in.readDouble();
                Planet[] ps = new Planet[num];
                StdDraw.setScale(-R,R);
                for (int n=0;n<num;n++){
                        ps[n] = getPlanet(in);
                }
                time= 0.0;
                StdAudio.play("audio/2001.mid");
                while (time<T){
                StdDraw.picture(0.0,0.0,"images/starfield.jpg",R*2.0,R*2.0);
                        for (int n=0;n<num;n++){
                                ps[n].setNetForce(ps);
                                ps[n].update(dt);
                                ps[n].draw();
                        }
                        StdDraw.show(5);
                        time+=dt;
                }
                System.out.println(num);
                System.out.println(R);
                for (int n=0;n<num;n++){
                        p = ps[n];
                        System.out.println(p.x+"  "+p.y+"  "+p.xVelocity+"  "+p.yVelocity+"  "+p.mass+"  "+p.img);
                }

        }
        public static Planet getPlanet(In i){
                double d1 = i.readDouble();
                double d2 = i.readDouble();
                double d3 = i.readDouble();
                double d4 = i.readDouble();
                double d5 = i.readDouble();
                String imgs = i.readString();
                Planet p = new Planet(d1,d2,d3,d4,d5,imgs);
                return p;
        }

}

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

baiery 发表于 2015-6-4 00:34:34 | 显示全部楼层
public class Planet{
        public  double x, y, xVelocity, yVelocity, mass;
        public  String img;
        public  double xNetForce, yNetForce, xAccel, yAccel;

        public Planet(double xp, double yp, double xVp, double yVp, double massp, String imgp){
                x = xp;
                y = yp;
                xVelocity = xVp;
                yVelocity = yVp;
                mass = massp;
                img = imgp;
        }

        public  double calcDistance(Planet a){
                double disx = Math.abs(a.x-this.x);
                double disy = Math.abs(a.y-this.x);

                return Math.sqrt(disx*disx+disy*disy);
        }

        public  double calcPairwiseForce(Planet a){
                return (6.67e-11*this.mass*a.mass/(calcDistance(a)*calcDistance(a)));
        }

        public  double calcPairwiseForceX(Planet a){
                return (calcPairwiseForce(a)*(a.x-this.x)/calcDistance(a));
        }

        public double calcPairwiseForceY(Planet a){
                return (calcPairwiseForce(a)*(a.y-this.y)/calcDistance(a));
        }

        public  void setNetForce(Planet[] a){
               
                for (int i = 0; i < a.length;i++){
                        if (!(a[i].x == this.x && a[i].y == this.y) ){
                                xNetForce = calcPairwiseForceX(a[i])+xNetForce ;
                                yNetForce = calcPairwiseForceY(a[i])+yNetForce;
                        }
                }

        }

        public  void draw(){
                StdDraw.setXscale(0.0,10.0);
                StdDraw.setYscale(0.0,10.0);
                StdDraw.point(x,y);
        }

        public  void update(double dt){
                xAccel = this.xNetForce/ mass;

                yAccel = this.yNetForce / mass;
               
                xVelocity = xVelocity + dt*xAccel;
               
                yVelocity = yVelocity + dt*yAccel;
               
                x = x + dt*xVelocity;
               
                y = y + dt*yVelocity;
        }

       
}

先把Planet.java放上来,至于NBody.java实在不太会写,根本不知道该用什么方法。。。。求助
回复 支持 反对

使用道具 举报

baiery 发表于 2015-6-4 12:00:12 | 显示全部楼层

可不可以问你一下,如何知道import什么文件,另外从txt里读数据我看到一个Bufferreader的库,说是把每行的一个数存入数组,你是怎么知道用这个scanner的?谢谢!
回复 支持 反对

使用道具 举报

karte_polo 发表于 2015-6-4 16:05:19 | 显示全部楼层
baiery 发表于 2015-6-4 12:00
可不可以问你一下,如何知道import什么文件,另外从txt里读数据我看到一个Bufferreader的库,说是把每行 ...

Scanner是我之前在网上找“JAVA如何读入控制台输入”时候找到的,这是JAVA IO库里一个比较简单的类,使用的时候只需要事先import java.util.scanner就可以了。至于使用什么库需要IMPORT什么文件,可以去百度查一下;
BuffetReader和Scanner都可以用来读控制台上的输入,但SCANNER相对更简单些,但也很容易出错- -
回复 支持 反对

使用道具 举报

baiery 发表于 2015-6-4 16:12:22 | 显示全部楼层
karte_polo 发表于 2015-6-4 16:05
Scanner是我之前在网上找“JAVA如何读入控制台输入”时候找到的,这是JAVA IO库里一个比较简单的类,使用 ...

好的,看来的确是要自己研究方法,我还以为课程网站上要要用什么方法的提示,谢谢啦!
回复 支持 反对

使用道具 举报

zhugejun 发表于 2015-6-6 11:44:21 | 显示全部楼层
baiery 发表于 2015-6-4 03:12
好的,看来的确是要自己研究方法,我还以为课程网站上要要用什么方法的提示,谢谢啦!

不需要用Scanner也可以的
args本身就是一个string数组,所以直接读取就可以了

T = Double.parseDouble(args[0]);
dt = Double.parseDouble(args[1]);
filename = args[2];
回复 支持 反对

使用道具 举报

zhugejun 发表于 2015-6-6 12:45:33 | 显示全部楼层
NBody.java

import java.io.*;
import java.util.Scanner;

public class NBody{
    public static Planet getPlanet(In in){
        double x = in.readDouble();
        double y = in.readDouble();
        double xVelocity = in.readDouble();
        double yVelocity = in.readDouble();
        double mass = in.readDouble();
        String img = in.readString();
        Planet planet = new Planet(x, y, xVelocity, yVelocity, mass, img);
        return planet;
    }

    public static void main(String[] args){
        double T, dt, radius;
        double time = 0.0;
        int num;
        String filename;
        
        T = Double.parseDouble(args[0]);
        dt = Double.parseDouble(args[1]);
        filename = args[2];

        In in  = new In(filename);
        num = in.readInt();
        radius = in.readDouble();
        StdDraw.setScale(-radius, radius);

        Planet[] planets = new Planet[num];
        for (int i = 0; i < num; i++){
            planets = getPlanet(in);
        }

        StdAudio.play("audio/2001.mid");

        while (time < T){
            StdDraw.picture(0.0, 0.0, "images/starfield.jpg");
            for (int i = 0; i < num; i++){
                planets.update(dt);
                planets.draw();
            }
            StdDraw.show(10);
            time += dt;
        }
StdOut.printf("%d\n", num);
        StdOut.printf("%.2e\n", radius);
        for (int i = 0; i < num; i++) {
            StdOut.printf("%11.4e %11.4e %11.4e %11.4e %11.4e %12s\n",
            planets.x, planets.y, planets.xVelocity, planets.yVelocity, planets.mass, planets.img);
        }
    }
}


Planet.java

/* homework from cs61b spring 2015
* https://berkeley-cs61b.github.io ... als/hw/hw1/hw1.html */

public class Planet{
    double x;
    double y;
    double xVelocity;
    double yVelocity;
    double mass;
    String img;

    double xNetForce = 0.0;
    double yNetForce = 0.0;
   
    double xAccel = 0.0;
    double yAccel = 0.0;

    /* constructor for Planet*/
    public Planet(double x, double y, double xVelocity, double yVelocity, double mass, String img){
        this.x = x;
        this.y = y;
        this.xVelocity = xVelocity;
        this.yVelocity = yVelocity;
        this.mass = mass;
        this.img = img;
    } //close constructor

    /* calculate the distance between two Planets */
    public double calcDistance(Planet planet){
        return (Math.sqrt(Math.pow((x - planet.x), 2) + (Math.pow((y - planet.y), 2))));
    } //close calcDistance

    /* calculate pairwise Force */  
    public double calcPairwiseForce(Planet planet){
        return (6.67*Math.pow(10, -11) * mass * planet.mass / Math.pow(this.calcDistance(planet), 2));
    }// close calcPairwiseForce

    /* calculate the force on x dirction */
    public double calcPairwiseForceX(Planet planet){
        return this.calcPairwiseForce(planet) * Math.abs(planet.x - this.x) / this.calcDistance(planet);
    } // close calcPairwiseForceX

    /* calculate the force on y dirction */
    public double calcPairwiseForceY(Planet planet){
        return this.calcPairwiseForce(planet) * Math.abs(planet.y - this.y) / this.calcDistance(planet);
    } // close calcPairwiseForceY

    /* Net Force: The principle of superposition says that
     * the net force acting on a particle in the x- or y-direction
     * is the sum of the pairwise forces acting on the particle
     * in that direction.*/
    public void setNetForce(Planet[] planets){
        for (int i=0; i < planets.length; i++){
            xNetForce += this.calcPairwiseForceX(planets);
            yNetForce += this.calcPairwiseForceY(planets);
        }
    } // close setNetForce

    /* We also want a planet to be able to draw itself at its appropriate position. */
    public void draw(){
        StdDraw.picture(this.x, this.y, "images/" + this.img);
    } // close draw

    /* update the planet */
    public void update(double dt){
        //this.setNetForce();
         this.xAccel = this.xNetForce/ this.mass;
         this.yAccel = this.yNetForce/ this.mass;

        this.xVelocity = this.xVelocity + this.xAccel * dt;
        this.yVelocity = this.yVelocity + this.yAccel * dt;

        this.x = this.x + dt * this.xVelocity;
        this.y = this.y + dt * this.yVelocity;

    } // close update
}


结果出来是个动画,还有下面的输出
5
2.50e+11
1.4960e+11  4.7024e+12  0.0000e+00  2.9800e+04  5.9740e+24    earth.gif
2.2790e+11  3.8030e+12  0.0000e+00  2.4100e+04  6.4190e+23     mars.gif
5.7900e+10  7.5586e+12  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  5.5230e+12  0.0000e+00  3.5000e+04  4.8690e+24    venus.gif

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

zhugejun 发表于 2015-6-6 12:46:22 | 显示全部楼层

楼主你的结果是动画吗?想确认一下
回复 支持 反对

使用道具 举报

karte_polo 发表于 2015-6-6 13:43:29 | 显示全部楼层
zhugejun 发表于 2015-6-6 12:46
楼主你的结果是动画吗?想确认一下

是啊,不过我这个是在ECLIPSE下运行的,在TERMINAL里运行的话要先javac NBody.java,然后再输入那三参数
回复 支持 反对

使用道具 举报

karte_polo 发表于 2015-6-6 13:45:24 | 显示全部楼层
zhugejun 发表于 2015-6-6 11:44
不需要用Scanner也可以的
args本身就是一个string数组,所以直接读取就可以了

原来直接读ARGS数组就行了,受教!
回复 支持 反对

使用道具 举报

wowmomsos 发表于 2015-6-11 00:35:49 | 显示全部楼层
zhugejun 发表于 2015-6-6 12:45
NBody.java

import java.io.*;

你的程序有bug啊
主要有两个:
1. 应该是planets
2. 你在update之前没有算合力的各个方向的分量。
回复 支持 反对

使用道具 举报

zhugejun 发表于 2015-6-11 01:03:38 | 显示全部楼层
wowmomsos 发表于 2015-6-10 11:35
你的程序有bug啊
主要有两个:
1. 应该是planets

我运行没问题啊,没明白你说的bug在哪里
update中哪个setNetForce不需要运行,如果运行了就是个静态图,不是动画了
回复 支持 反对

使用道具 举报

wowmomsos 发表于 2015-6-11 01:16:09 | 显示全部楼层
zhugejun 发表于 2015-6-11 01:03
我运行没问题啊,没明白你说的bug在哪里
update中哪个setNetForce不需要运行,如果运行了就是个静态图, ...

1.很明显啊,你的代码:
  1. for (int i = 0; i < num; i++){
  2.             planets = getPlanet(in);
  3.         }
复制代码
一看就没加啊.
2. 这是因为你在update里面有setNetForce()了,但是你给注释掉了
我添加了setNetForce()后是动态图啊。
buhuo.PNG
回复 支持 反对

使用道具 举报

zhugejun 发表于 2015-6-11 01:58:36 | 显示全部楼层
本帖最后由 zhugejun 于 2015-6-10 12:59 编辑
wowmomsos 发表于 2015-6-10 12:16
1.很明显啊,你的代码:一看就没加啊.
2. 这是因为你在update里面有setNetForce()了,但是你给注释掉了
...

我知道了,第一个是论坛格式的原因,html把【i】斜体设置了,难怪下面的code是斜体的,汗!!!

第二个还是不太明白,那个setNetForece应该加在

for (int i = 0; i < num; i++){
                planets【i】.setNetForce(planets);
                planets【i】.update(dt);
                planets【i】.draw();
            }

但是这样的话我的结果就是一个静态图了,不知道为什么。请指教!
回复 支持 反对

使用道具 举报

whosays 发表于 2015-6-11 11:25:11 | 显示全部楼层
karte_polo 发表于 2015-6-6 13:43
是啊,不过我这个是在ECLIPSE下运行的,在TERMINAL里运行的话要先javac NBody.java,然后再输入那三参数

我用terminal运行的,compile后运行时输入了完整的三个参数,进入类似死循环的状态没有反应。。。左右查不出错来。。。
请教一下,运行后simulation是会跳出一个单独的窗口么?
回复 支持 反对

使用道具 举报

wowmomsos 发表于 2015-6-11 12:42:12 | 显示全部楼层
zhugejun 发表于 2015-6-11 01:58
我知道了,第一个是论坛格式的原因,html把【i】斜体设置了,难怪下面的code是斜体的,汗!!!

第二 ...

好吧,第二个问题,我像你这样写就是动态图,你却是静态的
应该是你的setNetForce的问题,我一看,还真是:
你应该在每次计算xNetForce与yNetForce之前都应该把它们置零,而不是现在这样在原有值上继续加。
还有,你计算xNetForce与yNetForce不应计算星球与自己产生的力啊,这个home work 1 instruction 已经指明了。
我想,这就是你的bug所在。。。。。。。
回复 支持 反对

使用道具 举报

a0106660 发表于 2015-6-11 13:48:26 | 显示全部楼层
刚刚开始上,之前卡在如何使用Git 这,后来发现用不用这个对我这个**没多大影响。果断先不管。
我也把作业交了吧。
class Planet{
                public static double G = 6.67e-11;
                public double x;
                public double y;
                public double xVelocity;
                public double yVelocity;
                public double mass;
                public String img;
                public double xNetForce;
                public double yNetForce;
                public double xAccel;
                public double yAccel;
        public Planet(double x_position, double y_position, double x_velocity,
                double y_velocity, double mass, String img){
                this.x = x_position;
                this.y = y_position;
                this.xVelocity = x_velocity;
                this.yVelocity = y_velocity;
                this.mass = mass;
                this.img = img;
        }

        public double calcDistance(Planet p){
                return Math.sqrt((this.x-p.x)*(this.x-p.x)+
                        (this.y-p.y)*(this.y-p.y));
        }

        public double calcPairwiseForce(Planet p){
                double distance = this.calcDistance(p);
                return G*this.mass*p.mass/(distance*distance);
        }

        public double calcPairwiseForceX(Planet p){
                double pairwiseForce = this.calcPairwiseForce(p);
                double distance = this.calcDistance(p);
                return (p.x-this.x)/distance*pairwiseForce;
        }

        public double calcPairwiseForceY(Planet p){
                double pairwiseForce = this.calcPairwiseForce(p);
                double distance = this.calcDistance(p);
                return (p.y-this.y)/distance*pairwiseForce;
        }

        public void setNetForce(Planet[] planets){
                this.xNetForce=0;
                this.yNetForce=0;
                for(int i =0;i<planets.length;i++){
                        if(planets[i]!=this){
                                this.xNetForce+=calcPairwiseForceX(planets[i]);
                                this.yNetForce+=calcPairwiseForceY(planets[i]);
                        }
                }
        }

        public void draw(){
                StdDraw.picture(this.x,this.y,"images/"+this.img);
        }
       
        public void update(double dt){
                this.xAccel = this.xNetForce/this.mass;
                this.yAccel = this.yNetForce/this.mass;
                this.xVelocity += this.xAccel*dt;
                this.yVelocity += this.yAccel*dt;
                this.x +=this.xVelocity*dt;
                this.y +=this.yVelocity*dt;

        }
}

class NBody{

        public static void main(String[] args) {
                double T;
                double dt;
                String filename;
                int num;
                double radius;
                Planet[] planets;
                double time =0 ;

                T = Double.parseDouble(args[0]);
                dt =Double.parseDouble(args[1]);
                filename = args[2];
                In in = new In(filename);
                num = in.readInt();
                radius = in.readDouble();
                planets = new Planet[num];
                StdDraw.setScale(-radius,radius);
                StdDraw.picture(0,0,"images/starfield.jpg");
                StdAudio.play("audio/2001.mid");
                for(int i =0;i<num;i++){
                        planets[i] = getPlanet(in);
                }
                while(time<T){
                        StdDraw.picture(0,0,"images/starfield.jpg");
                        for(int j =0;j<num;j++){
                                planets[j].setNetForce(planets);
                                planets[j].update(dt);
                                planets[j].draw();
                        }
                        StdDraw.show(10);
                        time+=dt;
                }
                StdOut.printf("%d\n",num);
                StdOut.printf("%.2e\n",radius);
                for(int k=0;k<num;k++){
                        StdOut.printf("%11.4e %11.4e %11.4e %11.4e %11.4e %12s\n",
                                planets[k].x,planets[k].y,planets[k].xVelocity,
                                planets[k].yVelocity,planets[k].mass,planets[k].img);
                }

        }
        public static Planet getPlanet(In input){
                double x = input.readDouble();
                double y = input.readDouble();
                double xVelocity = input.readDouble();
                double yVelocity = input.readDouble();
                double mass = input.readDouble();
                String img = input.readString();
                Planet p = new Planet(x,y,xVelocity,yVelocity,mass,img);
                return p;
        }
}

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

zhugejun 发表于 2015-6-11 21:01:06 | 显示全部楼层
whosays 发表于 2015-6-10 22:25
我用terminal运行的,compile后运行时输入了完整的三个参数,进入类似死循环的状态没有反应。。。左右查 ...

是的,会出现一个星体运动的动画
回复 支持 反对

使用道具 举报

本版积分规则

请点这里访问我们的新网站:一亩三分地Instant.

Instant搜索更强大,不扣积分,内容组织的更好更整洁!目前仍在beta版本,努力完善中!反馈请点这里

关闭

一亩三分地推荐上一条 /5 下一条

手机版|小黑屋|一亩三分地论坛声明 ( 沪ICP备11015994号 )

custom counter

GMT+8, 2016-12-6 16:33

Powered by Discuz! X3

© 2001-2013 Comsenz Inc. Design By HUXTeam

快速回复 返回顶部 返回列表