# Non orthogonal collision

These days I been solving the problem of the non orthogonal collision.
I needed to find a system that would let some balls bounce inside an irregular shape, and finally I found it in the book Processing Creative Coding and Computational Art written by Ira Greenberg, where Ira explains how to deal when we want to know the boundaries of a irregular shape (At the same time, Ira explanation and code is based on Keith Peter”s Solution in Foundation Actionscript Animation: Making Things Move!).

The code he explains can be seen here:
http://processing.org/learning/topics/reflection2.html

I modified the code a little bit, because I wanted a ball bouncing inside an irregular surface instead on top of a irregular surface. Moreover, I adapt that code to openframeworks.
Here is a video with both programs running (First processing and then openframeworks):

This is the processing code, that as I said, it is based on Ira Greenberg one:
There are 4 files:

bounceInsideShape.pde (Main document):

` `PVector velocity;  float ptsx[] = {172, 209, 290, 380, 418, 409, 366, 303, 238, 190}; float ptsy[] = {162, 96, 58, 83, 154, 218, 274, 296, 279, 228}; Segment segments[] = new Segment[ptsx.length]; float pt1X = 100; float pt1Y = 200; float pt2X = 200; float pt2Y = 100; float mx = (pt1X + pt2X) / 2; float my = (pt1Y + pt2Y) / 2;  float rot = atan2((pt2Y-pt1Y), (pt2X-pt1X));  Ball ball;  void setup(){ size(600, 350); smooth(); ball = new Ball(220, 150, 3); velocity = new PVector(2, -4);  for(int i=0; i if(i < ptsx.length-1){ segments[i] = new Segment(ptsx[i], ptsy[i], ptsx[i+1], ptsy[i+1]); }else{ segments[i] = new Segment(ptsx[i], ptsy[i], ptsx, ptsy);  } } }  void draw(){ noStroke(); fill(0, 15); rect(0, 0, width, height);  ball.x += velocity.x; ball.y += velocity.y; checkWallCollision();  // ************************ // ** Check shape collision // ************************ for(int i=0; i float deltax = ball.x - segments[i].x; float deltay = ball.y - segments[i].y;  float cosine = cos(segments[i].rot); float sine = sin(segments[i].rot);   float groundXTemp = cosine * deltax + sine * deltay; float groundYTemp = cosine * deltay - sine * deltax; float velocityXTemp = cosine * velocity.x + sine * velocity.y; float velocityYTemp = cosine * velocity.y - sine * velocity.x;  if(segments[i].isOnTop()){ if(groundYTemp < ball.r &&  ball.x > segments[i].x1 &&  ball.x < segments[i].x2){  groundYTemp = ball.r; velocityYTemp *= -1.0; }  }else{ if(groundYTemp < ball.r &&  ball.x < segments[i].x1 &&  ball.x > segments[i].x2){  groundYTemp = ball.r; velocityYTemp *= -1.0; }  }  deltax = cosine * groundXTemp - sine * groundYTemp; deltay = cosine * groundYTemp + sine * groundXTemp; velocity.x = cosine * velocityXTemp - sine * velocityYTemp; velocity.y = cosine * velocityYTemp + sine * velocityXTemp; ball.x = segments[i].x + deltax;  ball.y = segments[i].y + deltay;   }  stroke(255); for(int i=0; i line(segments[i].x1, segments[i].y1, segments[i].x2, segments[i].y2); } ellipse(ball.x, ball.y, ball.r*2, ball.r*2); }` `

Ball.pde (Class):

` `class Ball{ float x, y, r;  Ball() { }  Ball(float x, float y, float r){ this.x = x; this.y = y; this.r = r; } }` `

Segment.pde (Class):

` `class Segment{ float x, y; float x1, y1, x2, y2; float rot;  Segment(float _x1, float _y1, float _x2, float _y2){ x1 = _x1; y1 = _y1; x2 = _x2; y2 = _y2; x = (x1 + x2) / 2; y = (y1 + y2) / 2;  rot = atan2((y2 - y1), (x2 - x1)); }  boolean isOnTop(){ if(x2 > x1){ return true; }else{ return false; } }  }` `

checkWalls.pde (Functions):

` `void checkWallCollision(){ if (ball.x > width-ball.r){ ball.x = width-ball.r; velocity.x *= -1; // velocity.x *= damping; }  else if (ball.x < ball.r){ ball.x = ball.r; velocity.x *= -1; // velocity.x *= damping; } else if(ball.y < ball.r){ ball.y = ball.r; velocity.y *= -1; } else if(ball.y > height-ball.r){ ball.y = height-ball.r; velocity.y *= -1; } }` `