Trying to do circle-on-circle collision detection, but I can't make it work. Where is the bug?
in
Programming Questions
•
1 year ago
So I'm making a game. I have a class called Oid, which in the game is a perfect circle with center, radius, speed, color etc. attributes. The following code, a method of Oid, is supposed to detect when the oid has touched another indicated oid. But it doesn't work, it detects the collision when the other oid is still some distance away!
- boolean oidCollision(Oid other) {
float combinedradius = rad+other.rad;
println(combinedradius);
float dx = other.pos.x - pos.x;
float dy = other.pos.y - pos.y;
line(pos.x,pos.y,other.pos.x,other.pos.y);
float dsquared = (dx*dx)+(dy*dy);
println(sqrt(dsquared));
return (combinedradius > sqrt(dsquared));
}
Can anyone find this bug? the full program code is below:
- import processing.opengl.*;
final int windowX = 1024;
final int windowY = 600;
ArrayList<Oid> oids;
void setup() {
size(windowX,windowY,OPENGL);
oids = new ArrayList<Oid>();
oids.add(new Oid(new PVector(400,100),new PVector(0 ,.1),50,color(255,255,0),color(255,0,0)));
oids.add(new Oid(new PVector(400,300),new PVector(0 ,-.1),90,color(255,255,0),color(255,0,0)));
}
void draw() {
background(0);
for(int iii=0;iii<oids.size();iii++) {
Oid foo = (Oid)oids.get(iii);
foo.render();
foo.update();
for(int jjj=0;jjj<oids.size();jjj++) {
if(jjj!=iii) {
Oid other = (Oid)oids.get(jjj);
//foo.gravitate(other);
foo.collisionCode(other);
}
}
if(foo.dead) oids.remove(iii);
}
} - class Oid {
PVector pos;
PVector speed;
float rad; //radius
color col;
color edgecol;
boolean dead;
Oid(PVector inpos, PVector inspd, float inrad, color incol, color inedgecol) {
pos = inpos.get();
speed = inspd.get();
rad = inrad;
col = incol;
edgecol = inedgecol;
dead = false;
}
void render() {
fill(col);
stroke(edgecol);
ellipseMode(CENTER);
ellipse(pos.x,pos.y,rad,rad);
}
void update() {
pos.add(speed);
//death check code:
if(rad <= 0) dead = true;
}
boolean isOffSides(float windowX,float windowY) {
if(pos.x < 0 || pos.x > windowX || pos.y < 0 || pos.y > windowY)
return true;
return false;
}
void gravitate(Oid target) {
if(target.equals(this)) return; //don't gravitate yourself.
// the distance on the x-axis
float dx = pos.x - target.pos.x;
// the distance on the y-axis
float dy = pos.y - target.pos.y;
// the distance between the 2 objects
float dsquared = (dx*dx)+(dy*dy);
// the acceleration - inversely proportional to the square of the distance
float acc = getMass() / ( dsquared );
float d = sqrt( dsquared );
float sinAngle = dy / d;
float cosAngle = dx / d;
// the acceleration on the x-axis
float accX = acc * cosAngle;
// the acceleration on the y-axis
float accY = acc * sinAngle;
PVector effect = new PVector( accX, accY);
target.speed.add(effect);
}
boolean oidCollision(Oid other) {
float combinedradius = rad+other.rad;
println(combinedradius);
float dx = other.pos.x - pos.x;
float dy = other.pos.y - pos.y;
line(pos.x,pos.y,other.pos.x,other.pos.y);
float dsquared = (dx*dx)+(dy*dy);
println(sqrt(dsquared));
return (combinedradius > sqrt(dsquared));
}
boolean isInsideMe(Oid other) {
float dx = pos.x - other.pos.x;
float dy = pos.y - other.pos.y;
float dsquared = (dx*dx)+(dy*dy);
return ( dsquared<rad*rad );
}
void collisionCode(Oid target) {
if(target.rad<rad) {//smaller than me, we can proceed.
if(oidCollision(target)) {
//if(isInsideMe(target)) {
// rad += target.rad;
// target.rad = 0;
//} else {
//rad++;
//target.rad--;
//}
target.col = color(255,255,255);
}
}
}
float getMass() {
return rad*rad;
}
}
1