1

I want to know how I can make collision happen between the two circles. One of them is movable, as you can see, and I want to make it so that the movable circle can actually push the smaller one. However, I don't want simple rectangle collision. I'm trying to make it so that the circles direction of push depends on the positions of the two circles.

package haex;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class haex extends Applet implements Runnable, KeyListener{
    private static final long serialVersionUID = 1L;
    int x = 0, y = 0, footballX = 100, footballY = 100;
    double angle, xVel, yVel;
    Image dbImage;
    Graphics dbg;
    boolean up, down, left, right, kick;
    public void init(){
        addKeyListener(this);
    }
    public void start(){
        Thread th = new Thread(this);
        th.start();
    }
    public void run(){
        while(true){
            angle = Math.atan2((footballX + 12) - (x + 25), (footballY + 12) - (y + 25));
            if(Math.sqrt(Math.pow((footballX + 12) - (x + 25), 2) + Math.pow((footballY + 12) - (y + 25), 2)) <= 37){
                xVel = Math.cos(angle);
                yVel = Math.sin(angle);
                footballX += xVel;
                footballY += yVel;
            }
            if(up) y--;
            if(down) y++;
            if(left) x--;
            if(right) x++;
            try{Thread.sleep(1000/60);}catch(InterruptedException x){}
            repaint();
        }
    }
    public void stop(){}
    public void destroy(){}
    public void paint(Graphics g){
        if(kick){
            g.setColor(Color.lightGray);
        }else{
            g.setColor(Color.black);
        }
        g.fillOval(x, y, 50, 50);
        g.setColor(Color.blue);
        g.fillOval(x + 5, y + 5, 40, 40);
        g.setColor(Color.black);
        g.fillOval(footballX, footballY, 24, 24);
        g.setColor(Color.white);
        g.fillOval(footballX + 2, footballY + 2, 20, 20);
        g.setColor(Color.black);
        g.drawLine(x + 25, y + 25, footballX + 12, footballY + 12);
    }
    public void keyPressed(KeyEvent e){
        if(e.getKeyCode() == KeyEvent.VK_UP) up = true;
        if(e.getKeyCode() == KeyEvent.VK_DOWN) down = true;
        if(e.getKeyCode() == KeyEvent.VK_LEFT) left = true;
        if(e.getKeyCode() == KeyEvent.VK_RIGHT) right = true;
        if(e.getKeyCode() == KeyEvent.VK_X) kick = true;
    }
    public void keyReleased(KeyEvent e){
        if(e.getKeyCode() == KeyEvent.VK_UP) up = false;
        if(e.getKeyCode() == KeyEvent.VK_DOWN) down = false;
        if(e.getKeyCode() == KeyEvent.VK_LEFT) left = false;
        if(e.getKeyCode() == KeyEvent.VK_RIGHT) right = false;
        if(e.getKeyCode() == KeyEvent.VK_X) kick = false;
    }
    public void update(Graphics g){
        if(dbImage == null){
            dbImage = createImage(this.getSize().width, this.getSize().height);
            dbg = dbImage.getGraphics();
        }
        dbg.setColor(getBackground());
        dbg.fillRect(0, 0, this.getSize().width, this.getSize().height);
        dbg.setColor(getForeground());
        paint(dbg);
        g.drawImage(dbImage, 0, 0, this);
    }
    @Override
    public void keyTyped(KeyEvent e){}
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • https://code.google.com/p/dyn4j/ – Jason Jan 08 '14 at 21:21
  • Collision of circles happens when the distance of centers is lower then sum of the radii. The direction of the kinetic impulse should be the vector constructed from the centers of both circles. Also you should only post the relevant pieces of code. Key detection and painting have no relevance to your question. P.S. Please follow basic java conventions - classess should be uppercase. – NeplatnyUdaj Jan 08 '14 at 21:40
  • What do you mean circles push depends upon position? How is that different than rectangle collision? Rectangles depend upon position too. This question is very badly worded. What do you want? – SpacePrez Jan 08 '14 at 22:11
  • Java-2D provides collision detection 'built-in'. See [this answer](http://stackoverflow.com/a/14575043/418556) for tips. – Andrew Thompson Jan 09 '14 at 01:24
  • 1) Why code an applet? If it is due to spec. by teacher, please refer them to [Why CS teachers should stop teaching Java applets](http://programmers.blogoverflow.com/2013/05/why-cs-teachers-should-stop-teaching-java-applets/). 2) Why AWT rather than Swing? See my answer on [Swing extras over AWT](http://stackoverflow.com/a/6255978/418556) for many good reasons to abandon using AWT components. If you need to support older AWT based APIs, see [Mixing Heavyweight and Lightweight Components](http://www.oracle.com/technetwork/articles/java/mixing-components-433992.html). – Andrew Thompson Jan 09 '14 at 01:24
  • @NeplatnyUdaj, I'm a beginner, please keep that in mind. I'm learning day by day. Nevertheless, you phrased my question the way I wanted to. The direction of the kinetic impulse should be the vector constructed from the centers of both circles. This is exactly what I'm trying to do but I keep failing. – John McTavish Jan 09 '14 at 09:31
  • Okay, nevermind, the problem wasn't really obvious. I solved it by experimenting, really. I found out that switching Math.sin() and Math.cos() in the xVel and yVel calculations works perfectly. I don't, however, know why. – John McTavish Jan 09 '14 at 11:36

1 Answers1

0

Doing circular collision should be even easier than rectangular, just use a single radius for each instead of seperate x and y dimensions. Just calculate if the distance between their center points is less than the radius of both. If so, they're touching, if not, they aren't.

EDIT:

So the problem is calculating the resultant velocities and directions of the balls AFTER collision, not calculating the collision itself? Learn to explain the problem accurately if you want accurate help.

In that case, compare the X values of the two center points and the Y values of the two center points. Collisions should be largely elastic, so if a ball is hit on the left side, it should go to the right side, and vise versa. Then you just have to combine the X and Y components into a vector to get the direction and magnitude of the reaction.

SpacePrez
  • 1,086
  • 7
  • 15
  • 1
    You can see that's exactly what I do in my code. I can get the the collision to be 'checked' but I cannot make the wanted reaction. I want to make the big ball push the smaller one when collision happens. – John McTavish Jan 09 '14 at 09:33