java - Recursive Collision Detection for Rectangles not quite working -


i have bunch of variable sized rectangles, laid out randomly in area.

i attempting (recursive) collision detection ensures not collide, shifting positions.

but, still wrong (some of rectangles still collide), , can't figure out what.. inability recursion right. grateful if checked out.

here's code, copy & paste & run it, , you'll see result instantly. requires javafx:

import javafx.application.application; import javafx.geometry.point2d; import javafx.geometry.rectangle2d; import javafx.scene.scene; import javafx.scene.layout.pane; import javafx.scene.paint.color; import javafx.scene.shape.rectangle; import javafx.stage.stage;  import java.util.*;  public class example extends application {      public static void main(string[] args) {         launch(args);     }      private pane root = new pane();      @override     public void start(stage stage) throws exception {          scene scene = new scene(root, 800, 600);          stage.settitle("collision problem");         stage.setscene(scene);         stage.setoncloserequest(e -> system.exit(0));         stage.show();          run();     }      private static class node2d {          private double x, y, w, h;          public node2d() {             w = randint(40, 80);             h = randint(20, 40);         }          public void setposition(double x, double y) {             this.x = x;             this.y = y;         }          public double getwidth() {             return w;         }          public double getheight() {             return h;         }     }      private static class layoutentity {          private node2d obj = new node2d();          private double x, y;          public void setlocationinlayout(double x, double y) {             this.x = x;             this.y = y;         }          public double getxinlayout() {             return x;         }          public double getyinlayout() {             return y;         }     }      public void run() {          layoutentity[] entitiestolayout = new layoutentity[100];         (int = 0; < entitiestolayout.length; i++)             entitiestolayout[i] = new layoutentity();          randomizepositions(entitiestolayout);          collisiondetection(entitiestolayout);          (layoutentity entity : entitiestolayout) {             node2d node = entity.obj;             node.setposition(entity.getxinlayout(), entity.getyinlayout());         }          // print possible collisions         displaynodes(entitiestolayout);     }      private void displaynodes(layoutentity[] all) {         (layoutentity entity : all) {             node2d node = entity.obj;              rectangle rect = new rectangle(node.x, node.y, node.w, node.h);             rect.setstroke(color.black);             rect.setfill(null);              root.getchildren().add(rect);         }     }      private void randomizepositions(layoutentity[] entities) {         (layoutentity entity : entities) {             entity.setlocationinlayout(randint(0, 512), randint(0, 512));         }     }      private void collisiondetection(layoutentity[] entities) {         collisiondetection(arrays.aslist(entities));     }      private void collisiondetection(collection<layoutentity> c) {          list<layoutentity> collisions = new arraylist<>();          (layoutentity e1 : c) {             (layoutentity e2 : c) {                 if (e1 == e2)                     continue;                 boolean collides = checkandresolvecollision(e1, e2);                 if (collides)                     collisions.add(e1);             }         }          checkrecursively(collisions, c);     }      private void checkrecursively(list<layoutentity> collisions,             collection<layoutentity> all) {          if (collisions.isempty())             return;          (layoutentity e1 : all) {              (int = 0; < collisions.size(); i++) {                  layoutentity e2 = collisions.get(i);                  if (e2 == e1)                     continue;                  boolean collides = checkandresolvecollision(e1, e2);                 if (collides) {                      if (collisions.contains(e1))                         continue;                      collisions.add(e1);                      checkrecursively(collisions, all);                 }             }         }     }      private boolean checkandresolvecollision(layoutentity e1, layoutentity e2) {          node2d n1 = e1.obj;          // ideally, want add gap around boxes         double extraspace = 0;          double w1 = n1.getwidth() + extraspace * 2;         double h1 = n1.getheight() + extraspace * 2;          rectangle2d b1 = new rectangle2d(e1.getxinlayout() - extraspace,                 e1.getyinlayout() - extraspace, w1, h1);          node2d n2 = e2.obj;          double w2 = n2.getwidth() + extraspace * 2;         double h2 = n2.getheight() + extraspace * 2;          rectangle2d b2 = new rectangle2d(e2.getxinlayout() - extraspace,                 e2.getyinlayout() - extraspace, w2, h2);          if (b1.intersects(b2)) {              point2d trans = getminimumtranslation(b1, b2);              double x = e1.getxinlayout() + trans.getx();             double y = e1.getyinlayout() + trans.gety();              e1.setlocationinlayout(x, y);              return true;         }         return false;     }      private point2d getminimumtranslation(rectangle2d source, rectangle2d target) {          double mtdx, mtdy;          point2d amin = new point2d(source.getminx(), source.getminy());         point2d amax = new point2d(source.getmaxx(), source.getmaxy());         point2d bmin = new point2d(target.getminx(), target.getminy());         point2d bmax = new point2d(target.getmaxx(), target.getmaxy());          double left = (bmin.getx() - amax.getx());         double right = (bmax.getx() - amin.getx());         double top = (bmin.gety() - amax.gety());         double bottom = (bmax.gety() - amin.gety());          if (left > 0 || right < 0)             return point2d.zero;          if (top > 0 || bottom < 0)             return point2d.zero;          if (math.abs(left) < right)             mtdx = left;         else             mtdx = right;          if (math.abs(top) < bottom)             mtdy = top;         else             mtdy = bottom;          // 0 axis largest mtd value.         if (math.abs(mtdx) < math.abs(mtdy))             mtdy = 0;         else             mtdx = 0;          return new point2d(mtdx, mtdy);     }      private static random rand = new random();      public static int randint(int min, int max) {         return rand.nextint((max - min) + 1) + min;     } } 

from reading code, can predict is, problem in logic. inside checkandresolvecollision(), when assigning new co-ordinate node using

e1.setlocationinlayout(x, y); 

you miss check whether new co-ordinate have assigned node, overlaps of other node's have checked against one.

you have generate logic, whenever changing co-ordinate of node, must again checked against every other node

hope helps


Comments

Popular posts from this blog

php - Submit Form Data without Reloading page -

linux - Rails running on virtual machine in Windows -