Adapun source codenya adalah sebagai berikut:
package fjr.collision; import java.util.ArrayList; import java.util.Random; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.ButtonBuilder; import javafx.scene.shape.Circle; import javafx.scene.shape.CircleBuilder; import javafx.stage.Stage; import javafx.util.Duration; public class BilliardBallDetection extends Application { ArrayListlistParticle; ArrayList listCircle; double xwidth = 400; double ywidth = 400; double timeStep = 2.5; double numberParticle = 9; Random rand = new Random(); double dmin = 30.0; double xmax = xwidth; double xmin = 0.0; double ymax = ywidth; double ymin = 0.0; double size = 0.0; double dmax = 0.0; double vmax = 3.0; Timeline animation; Button buttonPause, buttonPlay; @Override public void start(Stage primarySrage) throws Exception { // TODO Auto-generated method stub generateParticle(); removeOverlap(listParticle); generateCircle(); Group root = new Group(); for(int i =0; i< listCircle.size(); i++){ Circle c = listCircle.get(i); root.getChildren().add(c); } animation = new Timeline(); animation.setCycleCount(Timeline.INDEFINITE); animation.setAutoReverse(false); KeyFrame kf = new KeyFrame(Duration.millis(20), new EventHandler (){ @Override public void handle(ActionEvent event) { // TODO Auto-generated method stub checkBoundary(); calculateCollision(); moveParticle(); redrawCircle(); } }); animation.getKeyFrames().add(kf); root.getChildren().addAll(buttonPlay = ButtonBuilder.create() .text("PLAY").onAction(new EventHandler () { @Override public void handle(ActionEvent arg0) { // TODO Auto-generated method stub animation.play(); } }).translateX(10).translateY(10) .build(), buttonPause = ButtonBuilder.create() .text("PAUSE").translateX(80).translateY(10) .onAction(new EventHandler () { @Override public void handle(ActionEvent arg0) { // TODO Auto-generated method stub animation.pause(); } }) .build() ); primarySrage.setScene(new Scene(root, xwidth, ywidth)); primarySrage.show(); } private void redrawCircle(){ for(int i=0; i< listCircle.size(); i++){ Circle c = listCircle.get(i); Particle p = listParticle.get(i); c.setCenterX(p.x); c.setCenterY(p.y); } } private void generateCircle(){ listCircle = new ArrayList<>(); for(int i=0; i< listParticle.size(); i++){ Particle p = listParticle.get(i); Circle c = CircleBuilder.create() .centerX(p.x).centerY(p.y).radius(dmin) .build(); listCircle.add(c); } } private void generateParticle() { listParticle = new ArrayList<>(); for (int i = 0; i < numberParticle; i++) { Particle particle = new Particle(rand.nextDouble() * xwidth, rand.nextDouble() * ywidth, rand.nextDouble() * vmax, rand.nextDouble() * vmax); listParticle.add(particle); } } private void calculateCollision(){ for(int i=0; i< listParticle.size(); i++){ Particle p1 = listParticle.get(i); for(int j= i+1; j< listParticle.size(); j++ ){ Particle p2 = listParticle.get(j); chekCollision(p1, p2); } } } public void chekCollision(Particle p1, Particle p2) { if (isOverlap(p1, p2)) { double deltaX = p1.x - p2.x; double deltaY = p1.y - p2.y; double distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); deltaX = deltaX/ distance; deltaY = deltaY/distance; double aci = p1.vx * deltaX + p1.vy * deltaY; double bci = p2.vx * deltaX + p2.vy * deltaY; double acf = bci; double bcf = aci; p1.vx = p1.vx + (acf - aci) * deltaX; p1.vy = p1.vy + (acf - aci) * deltaY; p2.vx = p2.vx + (bcf - bci) * deltaX; p2.vy = p2.vy + (bcf - bci) * deltaY; } } private void moveParticle() { for (int i = 0; i < listParticle.size(); i++) { Particle p = listParticle.get(i); p.x += p.vx * timeStep; p.y += p.vy * timeStep; } } public void removeOverlap(ArrayList list) { for (int i = 0; i < list.size(); i++) { Particle p1 = list.get(i); for (int j = list.size() - 1; j > i; j--) { Particle p2 = list.get(j); if(isOverlap(p1, p2)) list.remove(j); } } } public void checkBoundary(){ for(int i =0; i< listParticle.size() ;i++){ Particle p = listParticle.get(i); if(p.x > xmax - dmin) p.vx = -Math.abs(p.vx) ; if(p.x < xmin + dmin) p.vx = Math.abs(p.vx); if(p.y > ymax - dmin) p.vy = - Math.abs(p.vy); if(p.y < ymin + dmin) p.vy = Math.abs(p.vy); } } private boolean isOverlap(Particle p1, Particle p2){ double deltax = p1.x - p2.x; double deltay = p1.y - p2.y; if(deltax * deltax + deltay * deltay < 4 * dmin * dmin) return true; return false; } public static void main(String[] args) { launch(args); } private class Particle { double x = 0.0; double y = 0.0; double vx = 0.0; double vy = 0.0; public Particle(double x, double y , double vx , double vy ) { this.x = x; this.y = y; this.vx = vx ; this.vy = vy; } } }
No comments:
Post a Comment