Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (540)
Games in Android Showcase (133)
games submitted by our members
Games in WIP (603)
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 1295 times)
0 Members and 1 Guest are viewing this topic.
Offline CyanPrime
« Posted 2010-05-14 03: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-14 23: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

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #2 - Posted 2010-05-15 01: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/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.

 

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

The first screenshot will be displayed as a thumbnail.

Mr.CodeIt (24 views)
2014-12-23 03:34:11

rwatson462 (53 views)
2014-12-15 09:26:44

Mr.CodeIt (45 views)
2014-12-14 19:50:38

BurntPizza (85 views)
2014-12-09 22:41:13

BurntPizza (110 views)
2014-12-08 04:46:31

JscottyBieshaar (79 views)
2014-12-05 12:39:02

SHC (89 views)
2014-12-03 16:27:13

CopyableCougar4 (96 views)
2014-11-29 21:32:03

toopeicgaming1999 (155 views)
2014-11-26 15:22:04

toopeicgaming1999 (152 views)
2014-11-26 15:20:36
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
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!