topical media & game development
#javascript-processing-example-topic-motion-reflection1.htm / htm
<!DOCTYPE html>
<html><head>
<script src="javascript-processing-example-processing.js"></script>
<script src="javascript-processing-example-init.js"></script>
<link rel="stylesheet" href="javascript-processing-example-style.css">
</head><body><h1><a href="http://ejohn.org/blog/processingjs/">Processing.js</a></h1>
<h2>Reflection1</h2>
<p>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.</p>
<p><a href="http://processing.org/learning/topics/reflection1.html"><b>Original Processing.org Example:</b> Reflection1</a><br>
<script type="application/processing">
float baseX1, baseY1, baseX2, baseY2;
float baseLength;
float[] xCoords, yCoords;
float ellipseX, ellipseY, ellipseRadius = 6;
float directionX, directionY;
float ellipseSpeed = 3.5;
float velocityX, velocityY;
void setup(){
size(200, 200);
frameRate(30);
fill(128);
smooth();
baseX1 = 0;
baseY1 = height-150;
baseX2 = width;
baseY2 = height;
// start ellipse at middle top of screen
ellipseX = width/2;
// calculate initial random direction
directionX = random(0.1, 0.99);
directionY = random(0.1, 0.99);
// normalize direction vector
float directionVectLength = sqrt(directionX*directionX +
directionY*directionY);
directionX /= directionVectLength;
directionY /= directionVectLength;
}
void draw(){
// draw background
fill(0, 12);
noStroke();
rect(0, 0, width, height);
// calculate length of base top
baseLength = dist(baseX1, baseY1, baseX2, baseY2);
xCoords = new float[ceil(baseLength)];
yCoords = new float[ceil(baseLength)];
// fill base top coordinate array
for (int i=0; i<xCoords.length; i++){
xCoords[i] = baseX1 + ((baseX2-baseX1)/baseLength)*i;
yCoords[i] = baseY1 + ((baseY2-baseY1)/baseLength)*i;
}
// draw base
fill(200);
quad(baseX1, baseY1, baseX2, baseY2, baseX2, height, 0, height);
// calculate base top normal
float baseDeltaX = (baseX2-baseX1)/baseLength;
float baseDeltaY = (baseY2-baseY1)/baseLength;
float normalX = -baseDeltaY;
float normalY = baseDeltaX;
// draw ellipse
noFill();
stroke(200);
ellipse(ellipseX, ellipseY, ellipseRadius*2, ellipseRadius*2);
// calculate ellipse velocity
velocityX = directionX * ellipseSpeed;
velocityY = directionY * ellipseSpeed;
// move elipse
ellipseX += velocityX;
ellipseY += velocityY;
// normalized incidence vector
float incidenceVectorX = -directionX;
float incidenceVectorY = -directionY;
// detect and handle collision
for (int i=0; i<xCoords.length; i++){
// check distance between ellipse and base top coordinates
if (dist(ellipseX, ellipseY, xCoords[i], yCoords[i]) < ellipseRadius){
// calculate dot product of incident vector and base top normal
float dot = incidenceVectorX*normalX + incidenceVectorY*normalY;
// calculate reflection vector
float reflectionVectorX = 2*normalX*dot - incidenceVectorX;
float reflectionVectorY = 2*normalY*dot - incidenceVectorY;
// assign reflection vector to direction vector
directionX = reflectionVectorX;
directionY = reflectionVectorY;
// draw base top normal at collision point
stroke(255, 128, 0);
line(ellipseX, ellipseY, ellipseX-normalX*100,
ellipseY-normalY*100);
}
}
// detect boundary collision
// right
if (ellipseX > width-ellipseRadius){
ellipseX = width-ellipseRadius;
directionX *= -1;
}
// left
if (ellipseX < ellipseRadius){
ellipseX = ellipseRadius;
directionX *= -1;
}
// top
if (ellipseY < ellipseRadius){
ellipseY = ellipseRadius;
directionY *= -1;
// randomize base top
baseY1 = random(height-100, height);
baseY2 = random(height-100, height);
}
}
</script><canvas width="200" height="200"></canvas></p>
<div style="overflow: hidden; height: 0px; width: 0px;"></div>
<pre><b>// All Examples Written by <a href="http://reas.com/">Casey Reas</a> and <a href="http://benfry.com/">Ben Fry</a>
// unless otherwise stated.</b>
float baseX1, baseY1, baseX2, baseY2;
float baseLength;
float[] xCoords, yCoords;
float ellipseX, ellipseY, ellipseRadius = 6;
float directionX, directionY;
float ellipseSpeed = 3.5;
float velocityX, velocityY;
void setup(){
size(200, 200);
frameRate(30);
fill(128);
smooth();
baseX1 = 0;
baseY1 = height-150;
baseX2 = width;
baseY2 = height;
// start ellipse at middle top of screen
ellipseX = width/2;
// calculate initial random direction
directionX = random(0.1, 0.99);
directionY = random(0.1, 0.99);
// normalize direction vector
float directionVectLength = sqrt(directionX*directionX +
directionY*directionY);
directionX /= directionVectLength;
directionY /= directionVectLength;
}
void draw(){
// draw background
fill(0, 12);
noStroke();
rect(0, 0, width, height);
// calculate length of base top
baseLength = dist(baseX1, baseY1, baseX2, baseY2);
xCoords = new float[ceil(baseLength)];
yCoords = new float[ceil(baseLength)];
// fill base top coordinate array
for (int i=0; i<xCoords.length; i++){
xCoords[i] = baseX1 + ((baseX2-baseX1)/baseLength)*i;
yCoords[i] = baseY1 + ((baseY2-baseY1)/baseLength)*i;
}
// draw base
fill(200);
quad(baseX1, baseY1, baseX2, baseY2, baseX2, height, 0, height);
// calculate base top normal
float baseDeltaX = (baseX2-baseX1)/baseLength;
float baseDeltaY = (baseY2-baseY1)/baseLength;
float normalX = -baseDeltaY;
float normalY = baseDeltaX;
// draw ellipse
noFill();
stroke(200);
ellipse(ellipseX, ellipseY, ellipseRadius*2, ellipseRadius*2);
// calculate ellipse velocity
velocityX = directionX * ellipseSpeed;
velocityY = directionY * ellipseSpeed;
// move elipse
ellipseX += velocityX;
ellipseY += velocityY;
// normalized incidence vector
float incidenceVectorX = -directionX;
float incidenceVectorY = -directionY;
// detect and handle collision
for (int i=0; i<xCoords.length; i++){
// check distance between ellipse and base top coordinates
if (dist(ellipseX, ellipseY, xCoords[i], yCoords[i]) < ellipseRadius){
// calculate dot product of incident vector and base top normal
float dot = incidenceVectorX*normalX + incidenceVectorY*normalY;
// calculate reflection vector
float reflectionVectorX = 2*normalX*dot - incidenceVectorX;
float reflectionVectorY = 2*normalY*dot - incidenceVectorY;
// assign reflection vector to direction vector
directionX = reflectionVectorX;
directionY = reflectionVectorY;
// draw base top normal at collision point
stroke(255, 128, 0);
line(ellipseX, ellipseY, ellipseX-normalX*100,
ellipseY-normalY*100);
}
}
// detect boundary collision
// right
if (ellipseX > width-ellipseRadius){
ellipseX = width-ellipseRadius;
directionX *= -1;
}
// left
if (ellipseX < ellipseRadius){
ellipseX = ellipseRadius;
directionX *= -1;
}
// top
if (ellipseY < ellipseRadius){
ellipseY = ellipseRadius;
directionY *= -1;
// randomize base top
baseY1 = random(height-100, height);
baseY2 = random(height-100, height);
}
}</pre>
</body></html>
(C) Æliens
20/2/2008
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.