-
-
Save XD1729/725d47f3ce780242b75dfaf1fe9386fd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Processing code by Etienne JACOB | |
| // motion blur template by beesandbombs | |
| int[][] result; | |
| float t, c; | |
| float ease(float p, float g) { | |
| if (p < 0.5) | |
| return 0.5 * pow(2*p, g); | |
| else | |
| return 1 - 0.5 * pow(2*(1 - p), g); | |
| } | |
| void push() { | |
| pushMatrix(); | |
| pushStyle(); | |
| } | |
| void pop() { | |
| popStyle(); | |
| popMatrix(); | |
| } | |
| 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); | |
| 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(); | |
| } | |
| } | |
| // It's probably stupid to use this. I don't know Java and its equivalent of C++'s std::pair<int,int> | |
| class IntegerPair | |
| { | |
| int x,y; | |
| IntegerPair(int x_,int y_) | |
| { | |
| x = x_; | |
| y = y_; | |
| } | |
| } | |
| ////////////////////////////////////////////////////////////////////////////// | |
| int samplesPerFrame = 5; | |
| int numFrames = 275; | |
| float shutterAngle = .6; | |
| boolean recording = true; // set to false for time with mouse position, set to true to render frames | |
| // Hilbert curve algo from wikipedia (https://en.wikipedia.org/wiki/Hilbert_curve) | |
| //convert d to (x,y) | |
| IntegerPair d2xy(int n, int d) { | |
| int rx, ry, s, t=d; | |
| int x,y; | |
| x = 0; | |
| y = 0; | |
| for (s=1; s<n; s*=2) { | |
| rx = 1 & (t/2); | |
| ry = 1 & (t ^ rx); | |
| IntegerPair res = rot(s, new IntegerPair(x,y), rx, ry); | |
| x = res.x; | |
| y = res.y; | |
| x += s * rx; | |
| y += s * ry; | |
| t /= 4; | |
| } | |
| return new IntegerPair(x,y); | |
| } | |
| //rotate/flip a quadrant appropriately | |
| IntegerPair rot(int n, IntegerPair input, int rx, int ry) { | |
| int x = input.x; | |
| int y = input.y; | |
| if (ry == 0) { | |
| if (rx == 1) { | |
| x = n-1 - x; | |
| y = n-1 - y; | |
| } | |
| //Swap x and y | |
| int t = x; | |
| x = y; | |
| y = t; | |
| } | |
| return new IntegerPair(x,y); | |
| } | |
| int N = 6; | |
| int n = (int)pow(4,N); | |
| class Point | |
| { | |
| int i; | |
| PVector [] positions = new PVector[N]; // position of point at each level | |
| Point(int i_) | |
| { | |
| i = i_; | |
| for(int j=1;j<=N;j++) | |
| { | |
| int n2 = (int)pow(4,j); | |
| float fi = map(i,0,n-1,0,n2-1)*0.999999; | |
| IntegerPair pair1 = d2xy(n2,floor(fi)); | |
| IntegerPair pair2 = d2xy(n2,floor(fi+1)); | |
| float lp = fi - floor(fi); | |
| PVector v1 = new PVector(pair1.x,pair1.y); | |
| PVector v2 = new PVector(pair2.x,pair2.y); | |
| float f = 0.77; | |
| float x1 = map(v1.x + 0.5,0,pow(2,j),-f*width/2,f*width/2); | |
| float y1 = map(v1.y + 0.5,0,pow(2,j),-f*height/2,f*height/2); | |
| float x2 = map(v2.x + 0.5,0,pow(2,j),-f*width/2,f*width/2); | |
| float y2 = map(v2.y + 0.5,0,pow(2,j),-f*height/2,f*height/2); | |
| positions[j-1] = new PVector(lerp(x1,x2,lp),lerp(y1,y2,lp)); | |
| if(j%2==0) positions[j-1] = new PVector(positions[j-1].y,positions[j-1].x); | |
| } | |
| } | |
| } | |
| Point [] array = new Point[n]; | |
| // go from v1 to v2 with rotation arround their middle | |
| PVector rotater(PVector v1,PVector v2,float p,boolean orientation) | |
| { | |
| PVector mid = v1.copy().add(v2).mult(0.5); | |
| PVector midToV1 = v1.copy().sub(mid); | |
| float angle = atan2(midToV1.y,midToV1.x); | |
| float o = (orientation?-1:1); | |
| float r = midToV1.mag(); | |
| return new PVector(mid.x+r*cos(angle+o*PI*p),mid.y+r*sin(angle+o*PI*p)); | |
| } | |
| // https://easings.net/#easeOutElastic | |
| float easeOutElastic(float x) | |
| { | |
| float c4 = (2*PI)/3; | |
| if(x<=0) return 0; | |
| if(x>=1) return 1; | |
| return pow(2, -10 * x) * sin((x * 10 - 0.75) * c4) + 1; | |
| } | |
| void drawCurve(float p) | |
| { | |
| p = (p+12345-0.05)%1; | |
| p = constrain(map(p,0,0.88,0,1),0,1); | |
| stroke(255); | |
| strokeWeight(1.4); | |
| noFill(); | |
| beginShape(); | |
| for(int i=0;i<n;i++) | |
| { | |
| PVector deepPos = array[i].positions[N-1]; // position on last hilbert curve | |
| float delay = 0.001*deepPos.mag()*sin(PI*p); | |
| float pp = 1-pow(1-p,1.5); | |
| float delayedP = (12345+pp-delay)%1; | |
| float finishedLastCurveTime = 0.57; | |
| float floatIndex; | |
| if(delayedP<finishedLastCurveTime) | |
| floatIndex = map(delayedP,0,finishedLastCurveTime,0,N-1); | |
| else | |
| floatIndex = map(delayedP,finishedLastCurveTime,1.0,N-1,N); | |
| int ind1 = floor(floatIndex); | |
| int ind2 = (ind1+1)%N; | |
| float frac = floatIndex - ind1; | |
| PVector v1 = array[i].positions[ind1]; | |
| PVector v2 = array[i].positions[ind2]; | |
| float easing; | |
| if(ind1==N-1) | |
| { | |
| float aux = constrain(map(frac,0.25,1,0,1),0,1); | |
| easing = easeOutElastic(pow(aux,2.2)); | |
| } | |
| else | |
| easing = ease(frac,2.2); | |
| PVector v = rotater(v1,v2,easing,ind1%2==0); | |
| vertex(v.x,v.y); | |
| } | |
| endShape(); | |
| } | |
| void setup(){ | |
| size(600,600,P3D); | |
| result = new int[width*height][3]; | |
| for(int i=0;i<n;i++) | |
| { | |
| array[i] = new Point(i); | |
| } | |
| smooth(8); | |
| } | |
| void draw_(){ | |
| background(0); | |
| push(); | |
| translate(width/2,height/2); | |
| rotate(-HALF_PI); | |
| drawCurve(t); | |
| pop(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment