Почему мои яйца продолжают ускоряться после того, как отскочили от стены? [Интеграция Verlet] - PullRequest
0 голосов
/ 16 марта 2019

Я пробую симуляцию с Verlet Integration, но после двух или около того столкновений шары ускоряются. Нужен совет, как это реализовать, и, возможно, объяснение, почему это происходит. Спасибо!

BouncingPane.java - обрабатывает поведение шаров.

import java.util.ArrayList;
import java.util.Iterator;
import javafx.scene.layout.Pane; 



public class BouncingPane extends Pane{

private ArrayList<Ball> balls;

public BouncingPane() {
    super();
    balls = new ArrayList<Ball>();
    this.setPrefSize(300, 300);
}

public void addBall(Ball b) {
    balls.add(b);
}

public ArrayList<Ball> getBallsCollection() {
    return balls;
}

public void render() {
    this.getChildren().addAll(balls);
}

public void updatePos() {
    Iterator<Ball> it = this.getBallsCollection().listIterator();
    Ball b;
    double x_new, y_new;
    while(it.hasNext()) {
        b = it.next();

        x_new = b.getCenterX();
        x_new += b.getCenterX() - b.getPX();

        if(x_new - b.getRadius() < 0) {
            x_new  = b.getRadius();
            b.setPX(b.getRadius() - (b.getPX() - b.getCenterX()));
            x_new = b.getRadius();
        }
        else if(x_new + b.getRadius() >= getWidth()) {
            x_new = getWidth() - b.getRadius();
            b.setPX(getWidth() - b.getRadius() + (b.getCenterX() - b.getPX()));
            x_new = getWidth() - b.getRadius();
        }
        else {
            b.setPX(b.getCenterX());
            b.setCenterX(x_new);
        }


        y_new = b.getCenterY();
        y_new += b.getCenterY() - b.getPY();

        if(y_new - b.getRadius() < 0) {
            y_new  = b.getRadius();
            b.setPY(b.getRadius() - (b.getPY() - b.getCenterY()));
            y_new = b.getRadius();
        }
        else if(y_new + b.getRadius() >= getHeight()) {
            y_new = getHeight() - b.getRadius();
            b.setPY(getHeight() - b.getRadius() + (b.getCenterY() - b.getPY()));
            y_new = getHeight() - b.getRadius();
        }
        else {
            b.setPY(b.getCenterY());
            b.setCenterY(y_new);
        }
    }
}
}

Ball.java - просто класс Circle, который отслеживает предыдущую позицию

import javafx.scene.shape.Circle;
import javafx.scene.paint.Color;

public class Ball extends Circle{
    private double prevX;
    private double prevY;

    public Ball(double x, double y, double rad, Color col) {
        super(x, y, rad, col);
        prevX = 0;
        prevY = 0;
    }

    public void setPX(double x) {prevX = x;}
    public void setPY(double y) {prevY = y;}

    public double getPX() {return prevX;}
    public double getPY() {return prevY;}
}

Main.java - Где инициализируется пользовательский интерфейс. Некоторые операции импорта не использовались (я просто скопировал из моих предыдущих кодов)

import java.util.Iterator;

import javafx.animation.AnimationTimer;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Main extends Application{

    public static void main(String[] args) {
        launch();

    }

    public void start(Stage stage) {
        BouncingPane canvas = new BouncingPane();
        Pane main = new Pane(canvas);
        Scene scene = new Scene(main, 300, 300);
        Ball ball = new Ball(100, 100, 5, Color.RED);
        Ball ball1 = new Ball(50, 50, 5, Color.YELLOW);


        canvas.addBall(ball);
        canvas.addBall(ball1);

        ball.setPX(99.0);
        ball.setPY(98.0);

        ball1.setPX(49.0);
        ball1.setPY(51.0);

        canvas.render();

        stage.setTitle("Moving Ball");
        stage.setScene(scene);
        stage.show();


        startAnimation(canvas);
    }

    public void startAnimation(final BouncingPane canvas) {
        final AnimationTimer timer = new AnimationTimer() {
        long lastTime = 0;
            public void handle(long now) {
                if(lastTime > 0) {
                    canvas.updatePos();
                }
                lastTime = now;
            }
        };

        timer.start();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...