StdDraw рисовать на фоне Java - PullRequest
       21

StdDraw рисовать на фоне Java

0 голосов
/ 03 февраля 2019

Я делаю этот проект, который имитирует солнечную систему с использованием 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;
}

}

Эточто происходит, когда трасса маршрута блокируется фоновым изображением:

Это то, что происходит, когда трасса не заблокирована, но я только хочу, чтобы трасса кукурузы не была blokcekd.

1 Ответ

0 голосов
/ 06 февраля 2019

у вас есть недостаток в логике анимации:

для анимации экрана вы должны

  1. обновить модель (каждый элемент, например, backgroud или bodY),
  2. затем нарисуйте каждую модель с помощью StdDraw.picture(..) и
  3. , наконец, сделайте это содержимое видимым (с помощью 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;
    }

}

...