Java-Gaming.org
Play Revenge of the Titans! The situation is critical. We need fancy commanders to defend Earth, the moon, Mars!
Featured games (78)
games approved by the League of Dukes
Games in Showcase (406)
games submitted by our members
Games in WIP (290)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  collision between a rect and a circle?  (Read 1146 times)
0 Members and 1 Guest are viewing this topic.
Offline CyanPrime
« Posted 2010-05-14 05:36:12 »

Okay, I'm trying to create a method to handle collisions between a rect and a circle. this is how far I've gotten, but now I'm stumped. It only works properly if px and py < the circles center.

Here's the method
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
    public boolean col(){
       float planeAngle = (float) Math.toDegrees(Math.atan2(px - (px + pwidth), -(py - py)));
       float planeWidth = rotate(px + pwidth,py + pheight, px,py,planeAngle,true);
       float planeHeight = rotate(px + pwidth,py + pheight, px,py,planeAngle,false);
       float planeCentX = (planeWidth/2);
       float planeCentY = (planeHeight/2);
       
       float dist = (float) Math.sqrt(Math.pow((bx + (bsize/2)) - planeCentX, 2) + Math.pow(-((by + (bsize/2)) - planeCentY), 2));

       if(dist <= (bx + (bsize/2)))
          return true;
         
       else
          return false;
    }


and here is the full source: (requires slick)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;

public class ColTest extends BasicGame{

   
   float px = 50;
   float py = 50;
   float pheight = 50;
   float pwidth = 50;
   
   float bx = 200;
   float by = 200;
   float bsize = 200;
   
   float pspeed = 3;
    Input input;
   
    public ColTest()
    {
        super("ColTest");
    }
 
    @Override
    public void init(GameContainer gc)
         throws SlickException {
         
    }

    @Override
    public void update(GameContainer gc, int delta)
         throws SlickException
   {
       input = gc.getInput();
       
       try{  
          if(input.isKeyDown(Input.KEY_UP))  
              py-=pspeed;
         
          if(input.isKeyDown(Input.KEY_DOWN))  
              py+=pspeed;
         
          if(input.isKeyDown(Input.KEY_LEFT))  
              px-=pspeed;
         
          if(input.isKeyDown(Input.KEY_RIGHT))  
              px+=pspeed;
       }
       
       catch(Exception e){}
   }
 
    public void render(GameContainer gc, Graphics g)
         throws SlickException
    {  
          g.drawString("col: " + col(), 10, 10);
          g.fillRect(px, py, 50, 50);
          g.fillOval(200, 200, 200, 200);
    }
   
    public boolean col(){
       float planeAngle = (float) Math.toDegrees(Math.atan2(px - (px + pwidth), -(py - py)));
       float planeWidth = rotate(px + pwidth,py + pheight, px,py,planeAngle,true);
       float planeHeight = rotate(px + pwidth,py + pheight, px,py,planeAngle,false);
       float planeCentX = (planeWidth/2);
       float planeCentY = (planeHeight/2);
       
       float dist = (float) Math.sqrt(Math.pow((bx + (bsize/2)) - planeCentX, 2) + Math.pow(-((by + (bsize/2)) - planeCentY), 2));

       if(dist <= (bx + (bsize/2)))
          return true;
         
       else
          return false;
    }
   
    public float rotate(float x, float y, float ox, float oy, float a, boolean b)
    {
         float dst = (float) Math.sqrt(Math.pow(x-ox,2.0)+ Math.pow(y-oy,2.0));

         float oa = (float) Math.atan2(y-oy,x-ox);

         if(b)
            return (float) Math.cos(oa + Math.toRadians(a))*dst+ox;

         else
            return (float) Math.sin(oa + Math.toRadians(a))*dst+oy;

    }
   
    public static void main(String[] args)
         throws SlickException
    {
         AppGameContainer app =
         new AppGameContainer( new ColTest() );
 
         app.setShowFPS(false);
         app.setAlwaysRender(true);
         app.setTargetFrameRate(60);
         app.setDisplayMode(800, 600, false);
         app.start();
    }
}
Offline lhkbob

JGO Knight


Medals: 32



« Reply #1 - Posted 2010-05-15 01:02:12 »

Note, I did not really read your code, I stopped when I realized you were using
1  
-(py - py)

as a clever form of 0  Wink

However, you can problem take an approach similar to this:
1. Start off assuming that the circle is completely inside the rectangle
2. For each side of the rectangle calculate the 2d line that represents its edge.
3. Compute the signed distance from the center of the circle to the edge's line, where a positive distance is towards the inside of the box and a negative distance is outside the box (this can be found online somewhere easily enough).
4. If the distance is < -radius, you know the circle is completely outside of the box (because its not on the inside of all edges).
5. If the distance is between [-radius, radius], the circle intersects the edge so you can change your assumption to just an intersection
6. After you've checked all planes, you're either inside or intersecting (since outside would have returned early).

I think this should work pretty well, but there may be some corner cases where it's possible to get a true intersection when it's not actually intersecting.

Offline Eli Delventhal
« League of Dukes »

JGO Kernel


Medals: 39
Projects: 12


Game Engineer


« Reply #2 - Posted 2010-05-15 03:06:39 »

You should know better than double posting.

[LOCKED]

Refer to this topic:
http://www.java-gaming.org/topics/collision-between-a-rect-and-a-circle-2/22432/msg/185673/view.html#msg185673

See my work:
OTC Software
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

Play Revenge of the Titans! The situation is critical. We need fancy commanders to defend Earth, the moon, Mars!
 
Browse for soundtracks for your game!

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

The invasion has landed! On Mars! And you're there to beat 'em!
cubemaster21 (61 views)
2013-05-17 21:29:12

alaslipknot (70 views)
2013-05-16 21:24:48

gouessej (100 views)
2013-05-16 00:53:38

gouessej (98 views)
2013-05-16 00:17:58

theagentd (107 views)
2013-05-15 15:01:13

theagentd (98 views)
2013-05-15 15:00:54

StreetDoggy (144 views)
2013-05-14 15:56:26

kutucuk (167 views)
2013-05-12 17:10:36

kutucuk (166 views)
2013-05-12 15:36:09

UnluckyDevil (175 views)
2013-05-12 05:09:57
Complex number cookbook
by Roquen
2013-04-24 12:47:31

2D Dynamic Lighting
by Oskuro
2013-04-17 16:46:12

2D Dynamic Lighting
by Oskuro
2013-04-17 16:45:57

2D Dynamic Lighting
by Oskuro
2013-04-17 16:23:20

Noise (bandpassed white)
by Roquen
2013-04-05 17:36:01

Noise (bandpassed white)
by Roquen
2013-04-03 16:17:38

Java Data structures
by Roquen
2013-03-29 13:21:12

Topic Request
by kutucuk
2013-03-22 21:42:01
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!
Page created in 0.265 seconds with 20 queries.