CARVIEW |
Select Language
HTTP/2 200
date: Sat, 11 Oct 2025 10:30:57 GMT
content-type: text/html
server: cloudflare
last-modified: Thu, 28 Oct 2010 14:02:44 GMT
cf-cache-status: DYNAMIC
vary: Accept-Encoding
nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}
report-to: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=ZHoV%2B0YlI2APsihkDTFcaQ1xwtfKjUelgyycYUOqJiHl00y6bjtuTHw89iMY4Fu%2BVd%2FotS%2BkbrencAScEDg6umC5y7zbKUY7E26%2BIS8%3D"}]}
content-encoding: gzip
cf-ray: 98cdaf628dc3ff67-BOM
alt-svc: h3=":443"; ma=86400
Processing.js
Reflection1
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.
Original Processing.org Example: Reflection1
// All Examples Written by Casey Reas and Ben Fry // unless otherwise stated. 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); } }