# Non-orthogonal Reflection

Non-orthogonal Reflection by Ira Greenberg.

Based on the equation (R = 2N(N*L)-L) where R is the reflection vector, N is the normal, and L is the incident vector.

```
// Position of left hand side of floor
PVector base1;
// Position of right hand side of floor
PVector base2;
// Length of floor
float baseLength;

// An array of subpoints along the floor path
PVector[] coords;

// Variables related to moving ball
PVector position;
PVector velocity;
float r = 6;
float speed = 3.5;

void setup() {
size(640, 360);

fill(128);
base1 = new PVector(0, height-150);
base2 = new PVector(width, height);
createGround();

// start ellipse at middle top of screen
position = new PVector(width/2, 0);

// calculate initial random velocity
velocity = PVector.random2D();
velocity.mult(speed);
}

void draw() {
// draw background
fill(0, 12);
noStroke();
rect(0, 0, width, height);

// draw base
fill(200);
quad(base1.x, base1.y, base2.x, base2.y, base2.x, height, 0, height);

// calculate base top normal
PVector baseDelta = PVector.sub(base2, base1);
baseDelta.normalize();
PVector normal = new PVector(-baseDelta.y, baseDelta.x);

// draw ellipse
noStroke();
fill(255);
ellipse(position.x, position.y, r*2, r*2);

// move elipse
position.add(velocity);

// normalized incidence vector
PVector incidence = PVector.mult(velocity, -1);
incidence.normalize();

// detect and handle collision
for (int i=0; i<coords.length; i++) {
// check distance between ellipse and base top coordinates
if (PVector.dist(position, coords[i]) < r) {

// calculate dot product of incident vector and base top normal
float dot = incidence.dot(normal);

// calculate reflection vector
// assign reflection vector to direction vector
velocity.set(2*normal.x*dot - incidence.x, 2*normal.y*dot - incidence.y, 0);
velocity.mult(speed);

// draw base top normal at collision point
stroke(255, 128, 0);
line(position.x, position.y, position.x-normal.x*100, position.y-normal.y*100);
}
}

// detect boundary collision
// right
if (position.x > width-r) {
position.x = width-r;
velocity.x *= -1;
}
// left
if (position.x < r) {
position.x = r;
velocity.x *= -1;
}
// top
if (position.y < r) {
position.y = r;
velocity.y *= -1;
// randomize base top
base1.y = random(height-100, height);
base2.y = random(height-100, height);
createGround();
}
}

// Calculate variables for the ground
void createGround() {
// calculate length of base top
baseLength = PVector.dist(base1, base2);

// fill base top coordinate array
coords = new PVector[ceil(baseLength)];
for (int i=0; i<coords.length; i++) {
coords[i] = new PVector();
coords[i].x = base1.x + ((base2.x-base1.x)/baseLength)*i;
coords[i].y = base1.y + ((base2.y-base1.y)/baseLength)*i;
}
}

```

## Functions Used

ellipse()

Draws an ellipse (oval) to the screen

Learn More
set()

Changes the color of any pixel, or writes an image directly to the display window

Learn More
fill()

Sets the color used to fill shapes

Learn More
size()

Defines the dimension of the display window width and height in units of pixels

Learn More
rect()

Draws a rectangle to the screen

Learn More
random()

Generates random numbers

Learn More
. (dot)

Provides access to an object's methods and data

Learn More
line()

Draws a line (a direct path between two points) to the screen

Learn More
stroke()

Sets the color used to draw lines and borders around shapes

Learn More
setup()

The setup() function is run once, when the program starts

Learn More
draw()

Called directly after setup(), the draw() function continuously executes the lines of code contained inside its block until the program is stopped or noLoop() is called

Learn More
ceil()

Calculates the closest int value that is greater than or equal to the value of the parameter

Learn More
quad()

A quad is a quadrilateral, a four sided polygon

Learn More
noStroke()

Disables drawing the stroke (outline)

Learn More
PVector

A class to describe a two or three dimensional vector, specifically a Euclidean (also known as geometric) vector

Learn More
dist()

Calculates the distance between two points

Learn More