Skip to content

Instantly share code, notes, and snippets.

@Bleuje
Created December 10, 2021 19:12
Show Gist options
  • Select an option

  • Save Bleuje/a09b0acdf8dc0f6caeaf850216a9700d to your computer and use it in GitHub Desktop.

Select an option

Save Bleuje/a09b0acdf8dc0f6caeaf850216a9700d to your computer and use it in GitHub Desktop.

Revisions

  1. Bleuje created this gist Dec 10, 2021.
    265 changes: 265 additions & 0 deletions hilbertcurve3.pde
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,265 @@
    // Processing code by Etienne JACOB
    // motion blur template by beesandbombs

    int[][] result;
    float t, c;

    float ease(float p) {
    return 3*p*p - 2*p*p*p;
    }

    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);
    }

    float softplus(float q,float p){
    float qq = q+p;
    if(qq<=0){
    return 0;
    }
    if(qq>=2*p){
    return qq-p;
    }
    return 1/(4*p)*qq*qq;
    }

    float mn = .5*sqrt(3), ia = atan(sqrt(.5));

    void push() {
    pushMatrix();
    pushStyle();
    }

    void pop() {
    popStyle();
    popMatrix();
    }

    void draw() {

    if (!recording) {
    t = (mouseX*1.3/width)%1;
    //t = map(mouseX,0,width,0.95,1.05)%1;
    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();
    }
    }

    //////////////////////////////////////////////////////////////////////////////

    int samplesPerFrame = 6;
    int numFrames = 300;
    float shutterAngle = 1.7;

    boolean recording = true;

    int n = 32;

    class IntegerPair
    {
    int x,y;
    IntegerPair(int x_,int y_)
    {
    x = x_;
    y = y_;
    }
    }

    // Hilbert curve algo from wikipedia

    //convert d to (x,y)
    IntegerPair d2xy(int n, int d) {
    if(d<0) return new IntegerPair(0,d);
    if(d>=n*n) return new IntegerPair(n-1,-(d-n*n)-1);
    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);
    }



    PVector perEase(float param)
    {
    float frac = param-floor(param);
    float speed = 2.8;
    float cs = constrain(speed*frac,0,1);
    float res = floor(param)+ease(cs,2.8);
    float res2 = sin(PI*cs);
    return new PVector(res,res2);
    }

    PVector pixelpos(int ix,int iy)
    {
    float w = 130;
    float x = map(ix,0,n-1,w,width-w)-width/2;
    float y = map(iy,0,n-1,w,height-w)-height/2;
    return new PVector(x,y);
    }

    PVector position(float p)
    {
    int ind1 = floor(p);
    int ind2 = ind1+1;

    IntegerPair ipos1 = d2xy(n,ind1);
    IntegerPair ipos2 = d2xy(n,ind2);

    PVector v1 = pixelpos(ipos1.x,ipos1.y);
    PVector v2 = pixelpos(ipos2.x,ipos2.y);

    PVector res = v1.copy().lerp(v2,p-ind1);
    return res;
    }

    PVector position2(float q,float offset)
    {
    float p = map(q,0,1,0,n*n);
    return position(p+offset);
    }

    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 showDots(float tt,float offset)
    {
    int K = n*n/4;

    for(int i=-10;i<K+10;i++)
    {
    float p = (i+tt)/K;

    float delay = 7*(1-p);

    PVector movement = perEase(tt-delay);

    float q = (i + movement.x)/K;

    float intensity = pow(movement.y,5.0);

    PVector pos = position2(q,offset);

    float sz = 10;

    intensity = easeOutElastic(intensity);

    push();
    translate(pos.x,pos.y);
    stroke(255);
    strokeWeight(1.0);
    fill(0);
    ellipse(0,0,sz-5*intensity,sz-5*intensity);

    strokeWeight(1.5+(sz-5)*intensity);
    if(offset==0)point(0,0);
    pop();
    }
    }

    void setup(){
    size(600,600,P3D);
    result = new int[width*height][3];
    }


    void draw_(){
    background(0);
    push();
    translate(width/2,height/2);

    scale(1.3);

    translate(0,0,-1);

    stroke(180);
    strokeWeight(0.8);
    noFill();
    beginShape();
    for(int i=-10;i<n*n+10;i++)
    {
    IntegerPair ipos = d2xy(n,i);
    PVector pos = pixelpos(ipos.x,ipos.y);
    vertex(pos.x,pos.y);
    }
    endShape();

    translate(0,0,1);

    showDots(t,0);
    showDots(t+8.0/(n*n),2);

    pop();
    }