Java-Gaming.org Hi !
 Featured games (84) games approved by the League of Dukes Games in Showcase (575) Games in Android Showcase (154) games submitted by our members Games in WIP (623) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1]
 ignore  |  Print
 collision between a rect and a circle?  (Read 1333 times) 0 Members and 1 Guest are viewing this topic.
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();    }}`
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

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.

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.

 BurntPizza (28 views) 2015-04-23 03:42:11 theagentd (32 views) 2015-04-22 16:23:07 Riven (45 views) 2015-04-16 10:48:47 Duke0200 (57 views) 2015-04-16 01:59:01 Fairy Tailz (40 views) 2015-04-14 20:13:12 Riven (42 views) 2015-04-12 21:36:37 bus hotdog (58 views) 2015-04-10 02:39:32 CopyableCougar4 (64 views) 2015-04-10 00:51:04 BurntPizza (67 views) 2015-04-06 22:06:58 ags1 (65 views) 2015-04-02 10:58:48
 theagentd 23x BurntPizza 16x wessles 15x alwex 11x 65K 11x kingroka123 11x Rayvolution 8x kevglass 8x Roquen 7x chrislo27 7x Hanksha 7x Riven 7x Olo 7x ra4king 7x Ecumene 7x KevinWorkman 6x
 How to: JGO Wikiby Mac702015-02-17 20:56:162D Dynamic Lighting2015-01-01 20:25:42How do I start Java Game Development?by gouessej2014-12-27 19:41:21Resources for WIP gamesby kpars2014-12-18 10:26:14Understanding relations between setOrigin, setScale and setPosition in libGdx2014-10-09 22:35:00Definite guide to supporting multiple device resolutions on Android (2014)2014-10-02 22:36:02List of Learning Resources2014-08-16 10:40:00List of Learning Resources2014-08-05 19:33:27
 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