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 & HelpOther Libraries › Ball simulation with constrain
Page Index Toggle Pages: 1
Ball simulation with constrain (Read 1257 times)
Ball simulation with constrain
Jul 21st, 2009, 12:34pm
 
Hi, i'm working with a class done for the colleague st33d with TUIO protocol,  but I am not obtaining a collision of the small balls with the extremities of the window, as they were inside of a box.

I'm working with tbeta software (or Community Core Vision);

I put the code in different messages:

some light?

//Main:
import oscP5.*;
import netP5.*;
import TUIO.*;

TuioProcessing tuioClient;
BallParticle[] finger;
BallParticle[] balls;
OscP5 oscP5;
NetAddress netAddress;
OscMessage[] oscBall, oscFinger;


float cursor_size = 15;
float object_size = 60;
float table_size = 760;
float scale_factor = 1;
String ip = "127.0.0.1";
int port = 57120;
int nFingers = 100;

void setup()
{
size( 640, 640 );
frameRate( 30 );
smooth();
ellipseMode( CENTER );
noStroke();
noCursor();
initBalls();
finger = new BallParticle[nFingers];
tuioClient  = new TuioProcessing(this);
setupOSC();
}

void draw(){

background( 255 ,200,00);
callFingers();
updateBalls();
}




Re: Ball simulation with constrain
Reply #1 - Jul 21st, 2009, 12:44pm
 

// called when an object is added to the scene
void addTuioObject(TuioObject tobj) {
println("add object "+tobj.getSymbolID()+" ("+tobj.getSessionID()+") "+tobj.getX()+" "+tobj.getY()+" "+tobj.getAngle());
}

// called when an object is removed from the scene
void removeTuioObject(TuioObject tobj) {
println("remove object "+tobj.getSymbolID()+" ("+tobj.getSessionID()+")");
}

// called when an object is moved
void updateTuioObject (TuioObject tobj) {
println("update object "+tobj.getSymbolID()+" ("+tobj.getSessionID()+") "+tobj.getX()+" "+tobj.getY()+" "+tobj.getAngle()
        +" "+tobj.getMotionSpeed()+" "+tobj.getRotationSpeed()+" "+tobj.getMotionAccel()+" "+tobj.getRotationAccel());
}

// called when a cursor is added to the scene
void addTuioCursor(TuioCursor tcur) {
println("add cursor "+tcur.getCursorID()+" ("+tcur.getSessionID()+ ") " +tcur.getX()+" "+tcur.getY());

 int id = tcur.getCursorID();
 int idS = int(tcur.getSessionID());
 float speed=tcur.getMotionSpeed();  
 float px = convertX(tcur.getY());
 float py = convertY(tcur.getX());
 finger[id]=new BallParticle(px,py,25);
 finger[id].col = finger[id].init_col = color(234,0,0);
 fill(finger[id].col);
 ellipse(finger[id].x, finger[id].y, finger[id].radius*2, finger[id].radius*2);


}

// called when a cursor is moved
void updateTuioCursor (TuioCursor tcur) {
println("update cursor "+tcur.getCursorID()+" ("+tcur.getSessionID()+ ") " +tcur.getX()+" "+tcur.getY()
        +" "+tcur.getMotionSpeed()+" "+tcur.getMotionAccel());
}

// called when a cursor is removed from the scene
void removeTuioCursor(TuioCursor tcur) {
println("remove cursor "+tcur.getCursorID()+" ("+tcur.getSessionID()+")");
int id = tcur.getCursorID();
int idS = int(tcur.getSessionID());
}

// called after each message bundle
// representing the end of an image frame
void refresh(TuioTime bundleTime) {
redraw();
}

void callFingers(){
Vector tuioCursorList = tuioClient.getTuioCursors();
for (int i=0;i<tuioCursorList.size();i++) {
  TuioCursor tcur = (TuioCursor)tuioCursorList.elementAt(i);
  Vector pointList = tcur.getPath();
  if (pointList.size()>0) {
    int id=tcur.getCursorID();
    float px = convertX(tcur.getY());
    float py = convertY(tcur.getX());  
    float oscX = px/width;
    float oscY = py/height;  
    finger[id].x=px;
    finger[id].y=py;
   
   
    //appears in screen
    fill(finger[id].col);
    ellipse(finger[id].x, finger[id].y, finger[id].radius*2, finger[id].radius*2);
   
    //interaction with each ball
    for(int j=0; j<balls.length; j++){
      if(finger[id].intersects(balls[j])){
        finger[id].col = balls[j].col = color(0);
        resolveBallCollision(finger[id], balls[j]);
      }
    }
   
    // send OSC message
    oscFinger[id] = new OscMessage("/system/finger/"+id);
    oscFinger[id].add(new float[] {oscX, oscY});
    oscP5.send (oscFinger[id], netAddress);
  }
}
}


float convertX(float x){
return (1-x)*width;
}


float convertY(float y){
return (1-y)*height;
}

void initBalls(){
balls = new BallParticle[10];
for(int i=0; i<balls.length; i++)
  balls[i] = new BallParticle(50+(i%5)*100, 100+(i/5)*100, 25);
}

void updateBalls(){
for(int i=0; i<balls.length; i++){
  balls[i].verlet(0,0,0.97);
  balls[i].col=lerpColor(balls[i].col, balls[i].init_col, 0.1);
}
for(int i=1; i<balls.length; i++){
  for(int j=0; j<i; j++){
  if(balls[i].intersects(balls[j])){
    balls[i].col = balls[j].col = color(0);
    resolveBallCollision(balls[i], balls[j]);
  }
  constrainBalls(balls[i]);
}
}
for(int i=0; i<balls.length; i++){
  fill(balls[i].col);
  //sendOSC
 
  oscBall[i] = new OscMessage("/system/sound/"+i);
  oscBall[i].add(new float[] {1-(balls[i].x/width), 1-(balls[i].y/height)});
  oscP5.send(oscBall[i], netAddress);
  ellipse(balls[i].x, balls[i].y, balls[i].radius*2, balls[i].radius*2);
}
}

void setupOSC(){
oscP5 = new OscP5(this, port);
netAddress = new NetAddress(ip, port);
oscBall = new OscMessage[balls.length];
oscFinger = new OscMessage[nFingers];
}
Re: Ball simulation with constrain
Reply #2 - Jul 21st, 2009, 12:45pm
 

class BallParticle extends Point{
int init_col, col;
float px,py,ix,iy,temp_x,temp_y;
float radius, elasticity = 1.0;
BallParticle(float x, float y, float radius){
  super(x, y);
  this.ix = px = temp_x = x;
  this.iy = py = temp_y = y;
  this.radius = radius;
  elasticity = 0.3;
  col = init_col = color(255);
}
// Movement by verlet integration - a personal preference
void verlet(float gravity_x, float gravity_y, float damping){
  temp_x = x;
  temp_y = y;
  x += damping * (x - px) + gravity_x;
  y += damping * (y - py) + gravity_y;
  px = temp_x;
  py = temp_y;
}
// Fast test for intersection - no sqrts here chum
boolean intersects(BallParticle o){
  return (o.x-x)*(o.x-x)+(o.y-y)*(o.y-y) <= (radius+o.radius)*(radius+o.radius);
}
}
// A quick point class to make measuring lines easier
static class Point{
float x,y;
Point(float x, float y){
  this.x = x;
  this.y = y;
}
}
// Reusable line class I use for vector math
static class Line{
Point a, b;
float vx, vy, len, dx, dy, rx, ry, lx, ly;
Line(Point a, Point b){
  this.a = a;
  this.b = b;
  updateLine();
}
void updateLine(){
  vx = b.x - a.x;
  vy = b.y - a.y;
  // length of vector
  len = sqrt(vx * vx + vy * vy);
  // normalized unit-sized components
  if (len > 0) {
  dx = vx / len;
  dy = vy / len;
  } else {
  dx = 0.0;
  dy = 0.0;
  }
  // right hand normal
  rx = -dy;
  ry = dx;
  // left hand normal
  lx = dy;
  ly = -dx;
}
}
// Ball collision is a transcript of code from the following url:
// Resolve a collision between Balls
void resolveBallCollision(BallParticle a, BallParticle b){
// Save velocities
float avx = a.x-a.px;
float avy = a.y-a.py;
float bvx = b.x-b.px;
float bvy = b.y-b.py;
// get the current line between the balls
Line ball_to_ball = new Line(a, b);
// do we have to wind back time?
float penetration = a.radius+b.radius-ball_to_ball.len;
float time_of_collision = 0;
if(penetration > 0){
  // take the speed of the overlap and use that as a measurement to reverse time
  float a_velocity_towards = avx*ball_to_ball.dx+avy*ball_to_ball.dy;
  float b_velocity_towards = bvx*ball_to_ball.dx+bvy*ball_to_ball.dy;
  time_of_collision = penetration/(a_velocity_towards-b_velocity_towards);
  a.x -= avx*time_of_collision;
  a.y -= avy*time_of_collision;
  b.x -= bvx*time_of_collision;
  b.y -= bvy*time_of_collision;
  // ball 2 ball needs to be updated for the reflection to work
  ball_to_ball.updateLine();
}
// the balls need to be reflected along their trajectories
// velocity projections
float a_velocity_dot = avx*ball_to_ball.dx+avy*ball_to_ball.dy;
float a_perp_velocity_dot = -avx*ball_to_ball.dy+avy*ball_to_ball.dx;
float b_velocity_dot = bvx*ball_to_ball.dx+bvy*ball_to_ball.dy;
float b_perp_velocity_dot = -bvx*ball_to_ball.dy+bvy*ball_to_ball.dx;
// new velocity projections
float a_new_velocity_dot = a_velocity_dot+a.elasticity+(b_velocity_dot-a_velocity_dot);
float b_new_velocity_dot = b_velocity_dot+b.elasticity+(a_velocity_dot-b_velocity_dot);
// calculate new velocities
avx = a_new_velocity_dot*ball_to_ball.dx-a_perp_velocity_dot*ball_to_ball.dy;
avy = a_new_velocity_dot*ball_to_ball.dy+a_perp_velocity_dot*ball_to_ball.dx;
bvx = b_new_velocity_dot*ball_to_ball.dx-b_perp_velocity_dot*ball_to_ball.dy;
bvy = b_new_velocity_dot*ball_to_ball.dy+b_perp_velocity_dot*ball_to_ball.dx;
// do we have to wind forward time?
if(penetration > 0){
  // wind forward time to avoid balls sticking
  // I've found that ommiting this part generally adds stability -
  // the balls become less logical so you're not surprised when they skip ahead
  a.x += avx*time_of_collision;
  a.y += avy*time_of_collision;
  b.x += bvx*time_of_collision;
  b.y += bvy*time_of_collision;
}
// apply new velocity
a.px = a.x-avx;
a.py = a.y-avy;
b.px = b.x-bvx;
b.py = b.y-bvy;
}

//This is th PROBLEM!!!!!!!
// i desire constrain Balls in the window, like a box
void constrainBalls(BallParticle a){
if (a.x + a.radius < 0 || a.x + a.radius >width){
  a.px = a.px*-1;
}
if (a.y - a.radius < 0 || a.x + a.radius >height){
  a.py = a.py*-1;
}
}
Re: Ball simulation with constrain
Reply #3 - Jul 21st, 2009, 12:46pm
 
The based code is in:
http://processing.org/discourse/yabb2/num_1201461240.html#7
Re: Ball simulation with constrain
Reply #4 - Jul 21st, 2009, 12:56pm
 
I don't see the point of making a duplicate post, posting twice this long message, while I already answered in the previous thread. It only duplicate efforts and dilutes answers. Unless you plan to delete the messages in the other thread, in this case it is no longer duplicate and fine here.
Re: Ball simulation with constrain
Reply #5 - Jul 22nd, 2009, 12:22pm
 
sorry, I had given a problem in my connection when it had sent the previous message
Page Index Toggle Pages: 1