title Joe McKay
This section comprises of code snippets that I use to teach and make my own work. They are complicated but useful bits of code that I constantly refer to, so why not put them up for everyone?

Collision - Processing

This is a decent way of solving ball/line collision problems. Big Props to my friend and colleague Jeanine Meyer for helping with the math.
In fact we run two collision sub routines to detect 1. is the ball touching the line and (touchingLine) 2. has the ball crossed the line (crossOverLine). Notice both these routines start with "boolean", not "void" so the line of code that called the routine is looking for a true or false return.
If either of these return true, then it calls the routine "bounce" which determines the correct angle that the ball should take. Add classes of balls and lines and this gets fun in a hurry, but this is a good start.

Your browser does not support the canvas tag.

	int xStart = 200; 
	int yStart = 200; 
	int xEnd = 300; 
	int yEnd = 300; 
	float xBall = 200; 
	float yBall = 300; 
	int balldiameter = 20; 
	float oldxball, oldyball;
	boolean linehit; 
	color ballcolor = color(100, 200, 100); 
	float r = 2.8; 
	float x;

	float speedx, speedy; 
	float speed = 6; 

	void setup() {
	  size(400, 400);
	  smooth();
	}
	void draw() {
	  background(200);  
	  xEnd = mouseX; 
	  yEnd = mouseY; 
	  float  px = xBall + cos(r)*(speed); 
	  float  py = yBall + sin(r)*(speed);
	  speedx = px - xBall; 
	  speedy = py - yBall; 
	  oldxball = xBall; 
	  oldyball = yBall;
	  xBall += speedx; 
	  yBall += speedy; 

	  if (xBall < 0 || xBall > width) { // side wall
	    x = PI - r; 
	    r = x;
	    linehit = false;
	  }
	  if (yBall < 0 || yBall > height) { // top & bottom
	    x = TWO_PI - r; 
	    r = x;
	    linehit = false;
	  }
	  if (crossOverLine(xBall, yBall, oldxball, oldyball, xStart, yStart, xEnd, yEnd)) {
	    if (linehit == false) {
	      bounce();
	    }
	  }
	  else  if (touchingLine(xStart, yStart, xEnd, yEnd, xBall, yBall, balldiameter/2)) {
	    if (linehit == false) {
	      bounce();
	    }
	  }
	  stroke(0); 
	  line (xStart, yStart, xEnd, yEnd); 
	  fill(ballcolor); 
	  ellipse (xBall, yBall, balldiameter, balldiameter);
	}

	void bounce() {

	  linehit = true; 
	  float ang  = atan2( yStart-yEnd, xStart-xEnd);
	  ang  = ang + PI; // to get a value between 0 and 2PI instead of -pi and pi
	  float ballang  = atan2( yStart-yBall, xStart-xBall);
	  ballang = ballang + PI; 

	 float d = (ang + HALF_PI) - r + PI; // get the angle between r and perpensicular
	  r =  (ang + HALF_PI) + d; // add that angle to perpendicula
	}

	boolean crossOverLine (float px, float py, float qx, float qy, float ax, float ay, float bx, float by) {
	  float s, t, w1, w2, w3, w4, w5, w6;
	  w1=ax*(qy-py);
	  w2 = (bx-ax)*(qy-py);
	  w3 = px*(qy-py);
	  w4= (qx-px)*ay;
	  w5= (by-ay)*(qx-px);
	  w6= py*(qx-px);
	  if (w2==w5) {
	    return false;
	  }
	  s = (w3-w1+w4-w6)/(w2-w5);
	  if (s<0) {
	    return false;
	  }
	  if (s>1) {
	    return false;
	  }
	  if (qx==px) {
	    return false;
	  }
	  t = (ax+s*(bx-ax)-px)/(qx-px);
	  if (t<0) {
	    return false;
	  }
	  if (t>1) {
	    return false;
	  }
	  return true;
	}

	boolean touchingLine (float px, float py, float qx, float qy, float cx, float cy, int rad ) {
	  float dx, dy, t, rt;
	  dx = qx-px;
	  dy = qy-py;
	  t =0.0-((px-cx)*dx+(py-cy)*dy)/((dx*dx)+(dy*dy));
	  if (t<0.0) {
	    t=0.0;
	  }
	  else if (t>1.0) {
	    t = 1.0;
	  }
	  //check if distance at this t is less than radius, actually compare squares
	  dx = (px+t*(qx-px))-cx;
	  dy = (py +t*(qy-py))-cy;
	  rt = (dx*dx) +(dy*dy);
	  if (rt<(rad*rad)) {
	    return true;
	  }
	  else {
	    return false;
	  }
	}