速度マップによるブラー

http://tpot.jpn.ph/t-pot/program/26_blur/blur.html

int numblur = 10; // ブラーの数
int sizbox = 40; // 箱のサイズ
void setup() {
  size(200, 200);
  framerate(10);
  
  ax = floor(random(10))+1; 
  ay = floor(random(10))+1;
  
  for (int i = 0; i< 4; i++) {
    for (int j = 0; j< numblur; j++) {
      oldPos[j][i] = new Vec(x, y);
    }
    resPos[i] = new Vec();
  }
}

class Vec{
public int x, y;
Vec(){x = y = 0;}
Vec(int ax, int ay){ x = ax; y = ay;}
};

Vec[] v = {new Vec(-1, -1), new Vec(1, -1), new Vec(1, 1), new Vec(-1, 1)}; // 頂点の法線
Vec[] p = {new Vec(0, 0), new Vec(sizbox, 0), new Vec(sizbox, sizbox), new Vec(0, sizbox)}; // 頂点座標
int x, y; // チューブの位置
int ax, ay; // チューブの速度

Vec[][] oldPos = new Vec[numblur][4]; // 古い座標
Vec[] resPos = new Vec[4]; // 速度マップされた座標
int idxOldPos;


// 内積
int Vec2dDotProduct(Vec iVec1, Vec iVec2 ){
  return ((iVec1.x * iVec2.x) + (iVec1.y * iVec2.y));
}

void draw() {
  background(0,0,255);

  // 新しい座標を求める
  for (int i = 0; i< 4; i++) {
    oldPos[idxOldPos][i].x = p[i].x + x;
    oldPos[idxOldPos][i].y = p[i].y + y;
  }

  for (int j = 0; j< numblur-1; j++) {
    // 新しい点のインデクス
    int k = idxOldPos - j;
    if (k < 0) k += numblur;

    // ひとつ古い点のインデクス
    int m = k - 1;
    if (m < 0) m += numblur;

    // 速度ベクトル
    Vec spd = new Vec();
    spd.x = oldPos[k][0].x - oldPos[m][0].x;
    spd.y = oldPos[k][0].y - oldPos[m][0].y;

    // 速度マップを作成
    for (int i = 0; i< 4; i++) {
      // 速度と頂点の法線のない積を求める
      if (Vec2dDotProduct(spd, v[i]) <= 0) { // 向きが異なるので古い点を使う
        resPos[i] = oldPos[m][i];
      } else { // 向きが同じなので新しい点を使う
        resPos[i] = oldPos[k][i];
      }
    }

    // ブラーイメージを描く
    stroke(255 * (numblur-1-j)/ (numblur-1), 0, 0);
    strokeWeight(1);  
    for (int i = 0; i< 3; i++) {
      line(resPos[i].x, resPos[i].y, resPos[i+1].x, resPos[i+1].y);
    }
    line(resPos[3].x, resPos[3].y, resPos[0].x, resPos[0].y);
  }

  // 元画像を画面に転送
  noStroke(); 
  fill(0, 255, 0, 100); 
  rect( x, y, sizbox, sizbox);

  // 毎フレームの移動
  x += ax;
  if (x > width-sizbox) ax = -floor(random(10))+1;
  if (x < 0) ax = floor(random(10))+1;
  y += ay;
  if (y > height-sizbox) ay = -floor(random(10))+1;
  if (y < 0) ay = floor(random(10))+1;
  idxOldPos = (1 + idxOldPos) % numblur;
}
  • 結果