/* Reflect a 2D vector around another vector. Returns a "mirror image" of the input vector. _ _ |\ | /| \ | / \|/ */ PVector reflectVector(final PVector source, final PVector mirrorNormal){ PVector reflection = PVector.mult( mirrorNormal, 2 * source.dot(mirrorNormal) ); reflection.sub(source); return reflection; } /* "Bounce" a 2D vector against a surface specified by another vector. This is exactly the same as reflecting the vector, except that the resulting vector points in the opposite direction. _ \ | /| \ | / \|/ */ PVector bounceVector(final PVector source, final PVector surfaceNormal){ PVector bounce = reflectVector(source, surfaceNormal); bounce.mult(-1); return bounce; } //Rotate a 2D vector around the origin. The angle of rotation should be specified in radians. //Positive values will produce clockwise rotation, negative - counter-clockwise. PVector rotateVector(PVector vector, float angle){ float sin_a = sin(angle), cos_a = cos(angle); return new PVector( cos_a * vector.x - sin_a * vector.y, sin_a * vector.x + cos_a * vector.y ); } //An utility function for drawing vectors. void drawVector(PVector vector, PVector origin, color clr){ float startX = 0, startY = 0; if ( origin != null ) { startX = origin.x; startY = origin.y; } stroke(clr); line(startX, startY, startX + vector.x, startY + vector.y); //Draw an arrow on the end final int arrowAngle = 25; //degrees final int arrowLength = 5; //pixels pushMatrix(); translate(startX + vector.x, startY + vector.y); PVector opposite = vector.get(); opposite.normalize(); opposite.mult(-1 * arrowLength); //One edge rotate(radians(arrowAngle)); line(0, 0, opposite.x, opposite.y); //Other edge rotate(radians(-2 * arrowAngle)); line(0, 0, opposite.x, opposite.y); popMatrix(); }