private final void enemiesMovements() {
int i, j;
float t;
boolean[] check = new boolean[enemies.length*enemies.length];
Arrays.fill(check, false);
for(i = 0; i < enemies.length; i++) {
if(enemies[i].pos[0] + enemies[i].d >= arenaWidth) {
enemies[i].vel[0] *= -1;
enemies[i].pos[0] = arenaWidth - enemies[i].d;
} else if(enemies[i].pos[0] - enemies[i].d <= -arenaWidth) {
enemies[i].vel[0] *= -1;
enemies[i].pos[0] = -arenaWidth + enemies[i].d;
}
if(enemies[i].pos[2] + enemies[i].d >= arenaDepth) {
enemies[i].vel[2] *= -1;
enemies[i].pos[2] = arenaDepth - enemies[i].d;
} else if( enemies[i].pos[2] - enemies[i].d <= -arenaDepth) {
enemies[i].vel[2] *= -1;
enemies[i].pos[2] = -arenaDepth + enemies[i].d;
}
}
for(i = 0; i < enemies.length; i++) {
for(j = 0; j < enemies.length; j++) {
if(i != j && !check[i*enemies.length+j]) {
check[i*enemies.length+j] = true;
check[j*enemies.length+i] = true;
if(doHit(enemies[i], enemies[j])) {
float[] cn = Math3D.normalize(Math3D.minus(enemies[i].pos, enemies[j].pos));
float imag = Math3D.magnitudo(enemies[i].vel),
jmag = Math3D.magnitudo(enemies[j].vel);
float idot = Math3D.dot(enemies[i].vel, cn),
jdot = Math3D.dot(enemies[j].vel, cn);
enemies[i].vel = Math3D.sum(enemies[i].vel, Math3D.scale(cn, jdot));
enemies[j].vel = Math3D.sum(enemies[j].vel, Math3D.scale(cn, idot));
}
}
}
}
for(i = 0; i < enemies.length; i++)
enemies[i].pos = Math3D.sum(enemies[i].pos, enemies[i].vel);
}
private final boolean doHit(Enemy A, Enemy B) {
float[] movevec = Math3D.minus(A.vel, B.vel);
double dist = Math3D.distance(B.pos, A.pos);
double sumRadii = B.d + A.d;
dist -= sumRadii;
if(Math3D.magnitudo(movevec) < dist) return false;
float[] N = Math3D.normalize(movevec);
float[] C = Math3D.minus(B.pos, A.pos);
double D = Math3D.dot(N, C);
if(D <= 0) return false;
double lengthC = Math3D.magnitudo(C);
double F = (lengthC * lengthC) - (D * D);
double sumRadiiSquared = sumRadii * sumRadii;
if(F >= sumRadiiSquared) return false;
double T = sumRadiiSquared - F;
if(T < 0){
return false;
}
double distance = D - Math.sqrt(T);
double mag = Math3D.magnitudo(movevec);
if(mag < distance) return false;
if(distance != 0)
A.pos = Math3D.sum(A.pos, Math3D.scale(Math3D.normalize(movevec), (float)distance));
return true;
}
Sphere collision & bounce
Hi all,
I''ve a problem implementing in java spehere collision &
bounce. This is my routine:
Enemy is just a sphere with 3 attributes: pos (position), vel
(velocity) and d (diameter).
My 2 BIG problems are:
1- how can I test if, after the 3rd loop in enemiesMovements,
there are 2 balls that overlap?
2- When the velocity vectors are parallel, strange thing occour
like division by zero!
Can anyone help me ?
Thanks
A
Well, to find if two spheres are colliding is is sufficent to evaluate whether the distance between their centers is less than or equal to the sum of their radii. So if you have two spheres with radii r1 and r2 with their centers at p1 and p2 at time zero and velocity vectors v1 and v2 then the position of their centers, c1 and c2, are time t is given by c1(t)=v1*t+p1 and c2(t)=v2*t+p2. They collide when |c1(t)-c2(t)|=r1+r2 where |v| is the magnitude of the vector v. This can be rewriten as (c1(t)-c2(t)).(c1(t)-c2(t))=(r1+r2)^2 since v.v=|v|^2. Expanding that equation, collecting terms of t and simplifying produces |d1-d2|^2*t^2+(d1-d2).(c1-c2)*t+|c1-c2|^2=(r1+r2)^2. This is a quadradic equation, i.e. A*t^2+B*t+C=0, where A=|d1-d2|^2, B=(d1-d2).(c1-c2) and C=|c1-c2|^2-(r1+r2)^2. You can use the quadradic equation, (-b+/-sqrt(b^2-4ac))/(2a), to find the time t when the spheres first collide.
A quadradic equation has two roots which can either be two distinct real roots, two duplicate real roots or two distinct complex roots. I can''t say for certain whether two duplicate complex roots are possible, but it is irrelevant here since you are only interested in the real roots. The determinant, b^2-4ac, determines if the roots are real or complex. If the determinant is negative the roots are complex and the spheres do not collide. If the determinant is positive then the spheres collide or are colliding and the roots provide the time that the spheres collided and parted.
You have three possibilities with the real roots: A) both are positive; B) both are negative; or C) one is positive and negative. If both are negative then if the spheres had always been on this path they collide in the past assuming t=0 is the start of the frame. If one is positive and one is negative then they are currently colliding. If both are positive then if they continue on this path they the smaller of the two is when they will collide. If the smaller of the two is less the the time delta for the frame then they will collide between the start and end of the frame.
If the roots are complex then you have two possiblities that matter. One is that they are not currently colliding and the other is that they will never collide. If they are currently colliding then the distance between the centers is constant at all points in time. So basically you either generated a new sphere or altered the path/velocity of an existing one. If they are not currently colliding then they may or may not stay a fixed distance apart, but they will never get close enough to collide while they remain on the same path at the same velocity.
A quadradic equation has two roots which can either be two distinct real roots, two duplicate real roots or two distinct complex roots. I can''t say for certain whether two duplicate complex roots are possible, but it is irrelevant here since you are only interested in the real roots. The determinant, b^2-4ac, determines if the roots are real or complex. If the determinant is negative the roots are complex and the spheres do not collide. If the determinant is positive then the spheres collide or are colliding and the roots provide the time that the spheres collided and parted.
You have three possibilities with the real roots: A) both are positive; B) both are negative; or C) one is positive and negative. If both are negative then if the spheres had always been on this path they collide in the past assuming t=0 is the start of the frame. If one is positive and one is negative then they are currently colliding. If both are positive then if they continue on this path they the smaller of the two is when they will collide. If the smaller of the two is less the the time delta for the frame then they will collide between the start and end of the frame.
If the roots are complex then you have two possiblities that matter. One is that they are not currently colliding and the other is that they will never collide. If they are currently colliding then the distance between the centers is constant at all points in time. So basically you either generated a new sphere or altered the path/velocity of an existing one. If they are not currently colliding then they may or may not stay a fixed distance apart, but they will never get close enough to collide while they remain on the same path at the same velocity.
Keys to success: Ability, ambition and opportunity.
Thanks LilBudyWizer for your reply, I''ll try your
suggestion...
But, I think I''ve wrong expressed my problems with that code.
I try to explain it better:
I have 2 balls moving on xz plane. These balls are represented
by the Enemy class. When a collision occours, I need
to compute the new velocity vectors of the 2 balls. I want
to make the things easy, so I think to an ideal system (no
friction, no gravity, ...). I''ve tried to implement
the "energy conservation" principle in that code, but:
1- if the balls collide then, after the computation of
the new velocities, I''ve to move these balls and sometimes
this movement causes the balls to overlap
2- if the balls collide and the vectors are parallel (think
to a slow ball hitted by the faster one) the new velocity
of the faster one grows because of the sum with a positive
velocity contribution by the slower sphere.
Now, how can I sove these problems ?
Thanks for the patience...
suggestion...
But, I think I''ve wrong expressed my problems with that code.
I try to explain it better:
I have 2 balls moving on xz plane. These balls are represented
by the Enemy class. When a collision occours, I need
to compute the new velocity vectors of the 2 balls. I want
to make the things easy, so I think to an ideal system (no
friction, no gravity, ...). I''ve tried to implement
the "energy conservation" principle in that code, but:
1- if the balls collide then, after the computation of
the new velocities, I''ve to move these balls and sometimes
this movement causes the balls to overlap
2- if the balls collide and the vectors are parallel (think
to a slow ball hitted by the faster one) the new velocity
of the faster one grows because of the sum with a positive
velocity contribution by the slower sphere.
Now, how can I sove these problems ?
Thanks for the patience...
A
Ok, here''s a link that helped me A LOT when i was making a simple 2d ball collision. However there''s an error in the vector calculations. They put in a y instead of an x or something:
http://groups.google.ca/groups?q=balls+collision+group:sci.*&hl=en&lr=&selm=8kun8p%243bam4%241%40ID-37212.news.cis.dfn.de&rnum=4
I could also post the code from my program if needed...
Massif - "It means mountain."
http://groups.google.ca/groups?q=balls+collision+group:sci.*&hl=en&lr=&selm=8kun8p%243bam4%241%40ID-37212.news.cis.dfn.de&rnum=4
I could also post the code from my program if needed...
Massif - "It means mountain."
Massif - "It means mountain."
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement