We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › classes and collisions
Page Index Toggle Pages: 1
classes and collisions (Read 2998 times)
classes and collisions
Apr 23rd, 2005, 5:21pm
 
I am porting this post from the alpha board over to the new one because I am just incapable of figuring out how  to do ball collisions.

This is the first time I've used the class menthology and I guess I just haven't figured out the innerworking of using classes.

I don't quite know how you can check the distance between 5 balls (for example). Wouldn't you need to tell the programm to check the distance to the next iteration of the ball and the one after it (and so on)?

just can't get my head around this :/

noob



mflux
Quote:
As far as ball to ball collision, simply make a function (call it "collide()" or something) inside the ball class, then have it loop through all the other instances of that class (in your case.. Ball[]). Have it test each ball's distance against itself, minus their radius.  

If they are within radius-length of each other, swap their velocities (direction of motion).


fish-face
Quote:
mflux's collision method is slightly inaccurate; it only works for head on collisions. If two balls 'glance' each other then their momentum is shared between them according to the angle at which they strike. To do collision checking simply:

Step 1: Iterate through Ball classes, check if this one is touching/covering another one
Step 2: Move the two balls apart so that they are edge to edge
Step 3: Work out the momentum to give to each ball. This can be worked out thus:

Each ball's momentum is comprised of two separate, equal momentums each at 45 degrees to its direction of motion. If the balls collide head on (collision angle of 0 degrees) then all of both momentums is given to the other. If the balls are of equal masses and velocities, this causes them both to halt.
If they collide at 45 degrees, then all of one momentum is given, but the momentum that is in a direction perpendicular to the angle of collision is retained. This causes the balls to glance of each other, at (again, only if equal masses + velocities, opposite directions) 45 degree angles compared to their original  directions.
At a collision angle of 90 degrees, there has not actually been a collision, so all momentum is retained.

This is difficult to explain, but you can have great fun sliding coins across the table to work stuff out.




Code:

import processing.opengl.*;
Ball[] ball;
int objectnumber = 500;

void setup (){

size (900,700,OPENGL);
framerate(30);
//colorMode(RGB, 100);
ball = new Ball[objectnumber];

for (int i= 0; i < objectnumber; i++){
ball[i] = new Ball(random(50,500),random(50,400),random(1,20),random(1,20), 10, 30);
}

}

void draw(){
background(#280915);

for (int i = 0; i < objectnumber; i++){

ball[i].draw ();
ball[i].move ();
// Collide Part // ball[i].collide();

}
}

class Ball {

float xpos;
float ypos;
float xspeed;
float yspeed;
float diameter;
float diameter2;
//float alpha_ = 100;
int xdirection = 1;
int ydirection = 1;

Ball (float xp, float yp,float xs, float ys, float d, float d2){
xpos = xp;
ypos = yp;
xspeed = xs;
yspeed = ys;
diameter = d;
diameter2 = d2;

}

void draw(){
//smooth();

ellipseMode(CENTER);
stroke(40);
fill (148,11,53,xspeed*5); // fill (148,11,53,alpha_)

ellipse(xpos,ypos,diameter,diameter);
if (diameter > 10){
diameter--;}
//if (alpha_<100){
//alpha_++;}
}

/* void collide(){
if (xpos == xpos - diameter*0.5){
xdirection *=-1;
}
if (ypos == ypos - diameter*0.5){
ydirection *=-1;
}

}
*/
void move(){

if (mousePressed == true){
xpos = xpos +(xspeed/5 * xdirection);
ypos = ypos +(yspeed/5 * ydirection);
}
else{
xpos = xpos +(xspeed * xdirection);
ypos = ypos +(yspeed * ydirection);}
if (xpos > width-diameter2*0.5 || xpos < diameter2*0.5){
xdirection *=-1;
diameter = diameter2;
//alpha_= 20;
}
if (ypos > height-diameter2*0.5 || ypos < diameter2*0.5){
ydirection *=-1;
diameter = diameter2;
//alpha_ = 20;
}
}

}
Re: classes and collisions
Reply #1 - Apr 25th, 2005, 5:19pm
 
anybody?
Re: classes and collisions
Reply #2 - Apr 26th, 2005, 6:16am
 
These days I'm also interested in collision models for a particle system.
So I've written some basic codes for it.
This is class definition of my particle for 2-D collision model.
It's sure that the collision time is slightly inaccurate and the code is a bit ugly, but it works anyway Smiley

There are two equations for this model
1) Momentum conservation, m(1)v(1) + m(2)v(2) = m(1)v(1)' + m(2)v(2)'
2) No change in relative velocity, v1-v2 = v2'-v1'

if you let m(1)=m(2) for simplicity,
then everything is simple such like this,
v1'=v2, v2'=v1

I hope it'll help Smiley

class Particle {
 float x, y, vx, vy, r;
 color icolor;
 
 Particle(float _x, float _y, float _vx, float _vy, float _r, color _c) {
   x = _x;
   y = _y;
   vx = _vx;
   vy = _vy;
   r = _r;
   icolor = _c;
 }
 
 void move() {
   bounceX();
   bounceY();
   for(int i=0; i<numParticles; i++) {
     collide(particles[i]);
   }
   
   x += vx;
   y += vy;
 }
 
 void bounceX() {
   if(x<r) {
     vx = -vx;
     x += (r-x);
   }
   else if(x>(width-r)) {
     vx = -vx;
     x -= (x-(width-r));
   }
 }
 
 void bounceY() {
   if(y<r) {
     vy = -vy;
     y += (r-y);
   }
   else if(y>(height-r)) {
     vy = -vy;
     y -= (y-(height-r));
   }
 }
 
 void collide(Particle p) {
   float tvx, tvy, d, R, theta;
   R = r + p.r;
   d = sqrt((p.x-x)*(p.x-x) + (p.y-y)*(p.y-y));
   theta = atan((abs(p.y-y))/(abs(p.x-x)));
   
   if(p!=this) {
     if(d<R) {
       tvx = vx;
       tvy = vy;
       vx = p.vx;
       vy = p.vy;
       p.vx = tvx;
       p.vy = tvy;
       
       x += ((R-d)*cos(theta)) * vx/abs(vx);
       p.x -= ((R-d)*cos(theta)) * vx/abs(vx);
       y += ((R-d)*sin(theta)) * vy/abs(vy);
       p.y -= ((R-d)*sin(theta)) * vy/abs(vy);
     }
   }
 }
 
 void drawMe() {
   noStroke();
   fill(icolor);
   ellipse(x, y, r, r);
 }
}
Re: classes and collisions
Reply #3 - Apr 29th, 2005, 9:50am
 
I'm working on this right now too, but I'm just starting with two balls.  I'm running into the problem of having the two objects either lock together or lock to the edge of the display.  This is what happens: the object moves into another object (or passed the edge of the screen) far enough so that it can't move back out in one frame.  My code tells it to reverse direction it it's outside the screen or inside another object, but if it's still outside the screen or inside another object after one frame, it reverses again and heads in the wrong direction.  The only solution I've found is to make a long set of IF statments like this:
 
 if(ex > width-size/2){
   ex = width-size/2;}
 if(ex < size/2){
   ex = size/2;}
 if(ey > height-size/2){
  ey = height-size/2;}
 if(ey < size/2){
   ey = size/2;}
   
 if(fx > width-size/2){
   fx = width-size/2;}
 if(fx < size/2){
   fx = size/2;}
 if(fy > height-size/2){
   fy = height-size/2;}
 if(fy < size/2){
   fy = size/2;}

but I find that when i try and apply this same method to the objects themselves like this:

if(distance < size){
   distance = size;}

where distance == the distance between the center of each ball and size == 2radius, i still get the same problem.  One ball will still move too far into the other sometimes, and they'll lock together like before.  
Anyone know why?  And does anyone know of a better way to do this than lots of IFs? I can't think of a way to iterate it...
Re: classes and collisions
Reply #4 - Apr 29th, 2005, 2:53pm
 
Zaphod,

I think what you want to do is include a nice little flag variable to keep track of whether the two objects already collided and don't need to reverse direction again (which is what would cause them to be "stuck"), i.e.:

boolean touching = false;
///////////////////////////
if (!touching) && (test for intersection)  {
 code to change direction
 touching = true;
} else if (! test for intersection ) {
 touching = false;
}

there's an old v68 example of this for 2 ellipses here:

http://stage.itp.nyu.edu/ICM/shiffman/week3/inclass/intersect/

could use a ton of improvement, but the basic idea is there. .

Hope this helps somewhat!
Dan




Re: classes and collisions
Reply #5 - Apr 30th, 2005, 3:16am
 
Thanks Dan!  Though I'm not really familiar with the usage of boolean expressions... is touching defined as a condition somewhere else in the program? or do I not need to declare it beforehand?  I'm assuming boolean touching = false defines a variable of type boolean and sets it to false, but how does the program know what is false?  In the code you reference, the condition (d < 100) && (touching == false) is very confusing to me.  Isn't it saying "if one ball is overlapping the other, and they aren't touching then do this?" or is this a double check, so that if the program changes direction once and one ball is still overlapping the other, it won't reverse direction again until there is no overlap?
Re: classes and collisions
Reply #6 - Apr 30th, 2005, 3:30am
 
>> if the program changes direction once
>> and one ball is still overlapping the other,
>> it won't reverse direction again until there
>> is no overlap

This is exactly it.  A variable of type "boolean" can only ever be true or false (1 or 0).  Here, we use it as a "double-checking" mechanism, giving us some memory (i.e. the balls were colliding a moment ago).  As soons as the two balls intersect, we set it to true.  That way we know they collided and we don't need to check again until they have separated (at which time, we set it back to false.)

Also,

if (touching == false)

can be simplied as

if (!touching)

! means "not"

Note that this works nicely with two balls, however, if you have large number of objects, the situation gets more complex (each ball would potentially need a boolean flag for every other ball in the system)

Best,
Dan



Re: classes and collisions
Reply #7 - Apr 30th, 2005, 11:17am
 
thanks, that's clear now.  but like you say: systems like this don't work as well for large numbers of objects.  I started by trying to create a system of 200 balls, and decided to start with two after i tried that for a few hours.  while it's difficult for me, I can sort of start to figure out ways to make the code more scalable (sp?), I'm wondering if there's a sort of.. i don't know... protocol to these things.  That is, if you have program A that works well with a small system, is there a good way to start down the path of creating program B that will implement program A for a larger group, timespan, whatever.  I suspect that i simply don't have a strong enough grasp of modular, object oriented programming, but is there a way to approach this problem that works more consistantly than others?
maybe I should be making a new thread for this but I don't know where...
Page Index Toggle Pages: 1