0

Hi

I have a program where you drag and drop circles on a scene using JavaFX. I don't want circles to collide to each other so I added a collision algorithm to check that, which now works. What puzzles me is what I want to do afterwards.

If two circles overlap I want to make a vector between the middle of the two and transform the moved circle in the direction of the vector until they no longer overlap.

Mouse dropped. Detected collision and transform second circle.

            for (Stone stn:getCurrentScenario().getStones()) {
                if (stn.circle == circle) continue;

                double x1 = stn.circle.getTranslateX();
                double y1 = stn.circle.getTranslateY();
                double r1 = stn.circle.getRadius()+stn.circle.getStrokeWidth();

                double x2 = circle.getTranslateX();
                double y2 = circle.getTranslateY();
                double r2 = circle.getRadius();

                double distSq = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
                double radSumSq = (r1 + r2) * (r1 + r2);


                if (!(distSq != radSumSq && distSq > radSumSq)) {
                    System.out.println("Collision.");
                    // Transform "circle".

                }

            }
Simon
  • 95
  • 1
  • 11
  • See also [*Ball to Ball Collision—Detection and Handling*](https://stackoverflow.com/q/345838/230513) – trashgod Mar 22 '19 at 16:53

1 Answers1

0

I ended up skipping the vector idea and went by angle instead. Going to keep the title if someone else runs into a similar issue:

    double newX = circle.getTranslateX();
    double newY = circle.getTranslateY();


    for (Stone stn:getCurrentScenario().getStones()) {
        if (stn.circle == circle) continue;

        double x1 = stn.circle.getTranslateX();
        double y1 = stn.circle.getTranslateY();
        double r1 = stn.circle.getRadius()+stn.circle.getStrokeWidth();

        double x2 = newX;
        double y2 = newY;
        double r2 = circle.getRadius();

        double distSq = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
        double radSumSq = (r1 + r2) * (r1 + r2);


        if (!(distSq != radSumSq && distSq > radSumSq)) {
            double angle = Math.atan2(x1-x2,y1-y2);
            newX = x1 - Math.sin(angle) * (circle.getRadius() + circle.getStrokeWidth() + stn.circle.getRadius() + .01);
            newY = y1 - Math.cos(angle) * (circle.getRadius() + circle.getStrokeWidth() + stn.circle.getRadius() + .01);



        }
    }
    for (Stone stn:getCurrentScenario().getStones()) {
        if (stn.circle == circle) continue;
        double x1 = stn.circle.getTranslateX();
        double y1 = stn.circle.getTranslateY();
        double r1 = stn.circle.getRadius()+stn.circle.getStrokeWidth();

        double x2 = newX;
        double y2 = newY;
        double r2 = circle.getRadius();

        double distSq = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
        double radSumSq = (r1 + r2) * (r1 + r2);

        if (!(distSq != radSumSq && distSq > radSumSq)) {
            newX = oldX;
            newY = oldY;
            break;
        }
    }

    circle.setTranslateX(newX);
    circle.setTranslateY(newY);

I made that piece of code just to make sure that it works as intended. Going to improve it now.

Simon
  • 95
  • 1
  • 11