stdDraw绘制背景Java

时间:2019-02-03 04:39:29

标签: java image project draw

我正在做一个使用java的stdDraw模拟太阳系的项目。我想进行更改以显示玉米的痕迹,因为我的最终目标是使玉米以心形飞行,如果我可以画出玉米的痕迹,那么我可以展现心脏。目前,我一直在尝试执行此操作,但似乎背景图像阻止了跟踪。如果我注释掉背景图像,所有行星将显示其踪迹。我不知道该怎么办,帮忙!!! 这是对象类:

public class BodyExtreme{
    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 BodyExtreme(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 BodyExtreme(BodyExtreme b){
    xxPos = b.xxPos;
    yyPos = b.yyPos;
    xxVel = b.xxVel;
    yyVel = b.yyVel;
    mass = b.mass;
    imgFileName = b.imgFileName;
}

public double calcDistance(BodyExtreme b) {
    double dx = b.xxPos - this.xxPos;
    double dy = b.yyPos - this.yyPos;
    return Math.sqrt(dx * dx + dy * dy);
}

public double calcForceExertedBy(BodyExtreme b) {
    if (this.calcDistance(b) == 0) {
        return 0;
    } else {
        return (G * b.mass * this.mass)/(this.calcDistance(b) * this.calcDistance(b));
    }
}

public double calcForceExertedByX(BodyExtreme b) {
    return (this.calcForceExertedBy(b) * (b.xxPos - this.xxPos) / this.calcDistance(b));
}

public double calcForceExertedByY(BodyExtreme b) {
    return (this.calcForceExertedBy(b) * (b.yyPos - this.yyPos) / this.calcDistance(b));
}

public double calcNetForceExertedByX(BodyExtreme[] b) {
    int i = 0;
    double sum = 0;
    while (i < b.length) {
        if (this.equals(b[i])) {
            sum += 0;
            i += 1;
        } else {
            sum = sum + this.calcForceExertedByX(b[i]);
            i += 1;
        }
    } return sum;
}

public double calcNetForceExertedByY(BodyExtreme[] b) {
    int i = 0;
    double sum = 0;
    while (i < b.length) {
        if (this.equals(b[i])) {
            sum += 0;
            i += 1;
        } else {
            sum = sum + this.calcForceExertedByY(b[i]);
            i += 1;
        }
    } return sum;
}

public void update(double dt, double fX, double fY) {
    double ax = fX / this.mass;
    double ay = fY / this.mass;
    double vx = this.xxVel + dt * ax;
    double vy = this.yyVel + dt * ay;
    double px = this.xxPos + dt * vx;
    double py = this.yyPos + dt * vy;
    this.xxPos = px;
    this.yyPos = py;
    this.xxVel = vx;
    this.yyVel = vy;
}

public void draw() {
    StdDraw.picture(this.xxPos, this.yyPos, "images/" + this.imgFileName);
}

public void lonelyplanet_update1(){
    this.xxPos = this.xxPos + 45000000; 
    this.yyPos = this.yyPos + 100000000;
    this.draw();
}

}

这是Main方法类:

import java.util.Scanner; 
public class NBodyExtreme{
    public static double readRadius(String name) {
        In in = new In(name);
        int NumPlanets = in.readInt();
        double Size = in.readDouble();
        return Size;
    }

public static BodyExtreme[] readBodies(String name) {
    In in = new In(name);
    int NumPlanets = in.readInt();
    double Size = in.readDouble();
    BodyExtreme[] bodies = new BodyExtreme[NumPlanets];
    int i = 0;
    while (i < NumPlanets) {
        bodies[i] = new BodyExtreme(in.readDouble(), in.readDouble(), in.readDouble(), in.readDouble(), in.readDouble(), in.readString());
        i += 1;
    }
    return bodies;
}

public static void main(String[] args) {
    double T = Double.parseDouble(args[0]);         /** Stoping Time */
    double dt = Double.parseDouble(args[1]);        /** Time Step */
    String filename = args[2];
    BodyExtreme[] bodies = readBodies(filename);            /** Array of Bodies */
    double radius = readRadius(filename);               /** Canvas Radius */
    In in = new In(filename);
    int NumPlanets = in.readInt();                  /** Number of Planets */
    String imageToDraw = "images/starfield.jpg";    /** Background */
    StdDraw.enableDoubleBuffering();
    StdDraw.setScale(-2*radius, 2*radius);
    StdDraw.clear();
    StdDraw.picture(0, 0, imageToDraw);             /** Draw Initial Background */
    StdDraw.show();
    int k = 0;
    while (k < NumPlanets-1) {                      /** Draw Planets */
        bodies[k].draw();
        k += 1;
    }

    StdDraw.enableDoubleBuffering();
    double time = 0.0;
    while (time < T) {
        double[] xForces = new double[NumPlanets-1];
        double[] yForces = new double[NumPlanets-1];
        int i = 0;
        while (i < NumPlanets-1) {
            xForces[i] = bodies[i].calcNetForceExertedByX(bodies);
            yForces[i] = bodies[i].calcNetForceExertedByY(bodies);
            i += 1;
        }
        i = 0;
        while (i < NumPlanets-1) {
            bodies[i].update(dt, xForces[i], yForces[i]);
            i += 1;
        }
        bodies[NumPlanets-1].lonelyplanet_update1();
        bodies[NumPlanets-1].draw();
        StdDraw.show();
        StdDraw.picture(0, 0, imageToDraw);
        int j = 0;
        while (j < NumPlanets) {
            bodies[j].draw();
            j += 1;
        }
        StdDraw.show();
        StdDraw.pause(10);
        }
        time += dt;
}

}

This is what happens when the trace of route is blocked with the background image:

This is what happens when the trace is not blocked, but I only want the corn's trace not to be blokcekd.

1 个答案:

答案 0 :(得分:0)

您的动画逻辑存在缺陷:

要为屏幕制作动画,您必须

  1. 更新模型(每个元素,例如backgroud或bodY)
  2. 然后使用StdDraw.picture(..)
  3. 绘制每个模型
  4. 最后使该内容可见(通过使用StdDraw.show();

对于动画中的每个时间步(while (time < T){..}),您都必须执行所有三个步骤。

public static void main(String[] args) {
    ...
    StdDraw.enableDoubleBuffering(); //it's enough to call this only once!
    double time = 0.0;
    while (time < T) {
        //do all the update stuff first, as shown in your code above

        //then draw ONCE the BackGround:
        StdDraw.picture(0, 0, imageToDraw);

        //then draw all the planets (yes, i missed one)
        while (j < NumPlanets) {
            bodies[j].draw();
            j += 1;
        }

        //finally make all the previous drawing visible  
        StdDraw.show();

        //wait a bit for the next animation step
        StdDraw.pause(10);
        time += dt;
    }

}