Skip to content

Instantly share code, notes, and snippets.

@Bleuje
Last active January 7, 2023 15:03
Show Gist options
  • Save Bleuje/531db909a7d71e09f4505595534ba78f to your computer and use it in GitHub Desktop.
Save Bleuje/531db909a7d71e09f4505595534ba78f to your computer and use it in GitHub Desktop.
// motion blur template by beesandbombs
int[][] result;
float t, c;
void draw() {
if (!recording) {
t = mouseX*1.0/width;
c = mouseY*1.0/height;
if (mousePressed)
println(c);
draw_();
} else {
for (int i=0; i<width*height; i++)
for (int a=0; a<3; a++)
result[i][a] = 0;
c = 0;
for (int sa=0; sa<samplesPerFrame; sa++) {
t = map(frameCount-1 + sa*shutterAngle/samplesPerFrame, 0, numFrames, 0, 1);
t %= 1;
draw_();
loadPixels();
for (int i=0; i<pixels.length; i++) {
result[i][0] += pixels[i] >> 16 & 0xff;
result[i][1] += pixels[i] >> 8 & 0xff;
result[i][2] += pixels[i] & 0xff;
}
}
loadPixels();
for (int i=0; i<pixels.length; i++)
pixels[i] = 0xff << 24 |
int(result[i][0]*1.0/samplesPerFrame) << 16 |
int(result[i][1]*1.0/samplesPerFrame) << 8 |
int(result[i][2]*1.0/samplesPerFrame);
updatePixels();
if (frameCount<=numFrames)
{
saveFrame("fr###.gif");
println(frameCount,"/",numFrames);
}
if (frameCount==numFrames)
stop();
}
}
//////////////////////////////////////////////////////////////////////////////
int samplesPerFrame = 7;
int numFrames = 500;
float shutterAngle = .6;
boolean recording = true;
class Ball
{
float ballRadius = 15;
float startX = random(0.25*width,0.75*width);
float startY = height*0.7;
float startVx = random(-15,15);
float startVy = random(-15,15);
int numberOfSimulationSteps = 3200;
float timeStep = 0.1;
ArrayList<PVector> recordedPositions = new ArrayList<PVector>();
float gravity = 9.8;
int numberOfPositions;
Ball()
{
float currentX = startX;
float currentY = startY;
float currentVx = startVx;
float currentVy = startVy;
recordedPositions.add(new PVector(currentX,currentY));
for(int i=0;i<numberOfSimulationSteps;i++)
{
currentVy -= timeStep*gravity; // effect of gravity
currentX += timeStep*currentVx;
currentY += timeStep*currentVy;
if(currentX+ballRadius>=width)
{
currentX = currentX - (currentX+ballRadius-width);
currentVx = -currentVx; // wall bounce
}
if(currentX-ballRadius<0)
{
currentX = currentX - (currentX-ballRadius);
currentVx = -currentVx; // wall bounce
}
if(currentY-ballRadius<0)
{
currentY = currentY - (currentY-ballRadius);
// floor bounce with decrease in speed :
currentVy = -0.95*currentVy;
}
recordedPositions.add(new PVector(currentX,currentY));
}
numberOfPositions = recordedPositions.size();
// (equal to numberOfSimulationSteps+1)
}
void show(float p)
{
p = ((p%1)+1)%1; // code to loop p and keep it in [0,1[
float floatIndex = (numberOfPositions-1)*p;
int index1 = floor(floatIndex);
int index2 = index1+1;
float lerpParameter = floatIndex-index1;
PVector position1 = recordedPositions.get(index1);
PVector position2 = recordedPositions.get(index2);
PVector lerpedPosition = position1.copy().lerp(position2,lerpParameter);
push();
translate(lerpedPosition.x,height-lerpedPosition.y);
// (reversing y, lerpedPosition.y = 0 means it's at the bottom)
stroke(0);
fill(255);
strokeWeight(2.0);
ellipse(0,0,2*ballRadius,2*ballRadius);
pop();
}
}
Ball myBall;
void setup(){
size(600,600,P2D);
result = new int[width*height][3];
randomSeed(123456);
myBall = new Ball();
}
void draw_(){
background(255);
stroke(0);
strokeWeight(2.0);
line(0,height,width,height);
line(0,height,0,0);
line(width,height,width,0);
myBall.show(t);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment