Processing: 動画上に連続した線分を描く

Processing(2.2.1)で、カメラから取り込んだ動画上に連続して線分を描く。右クリックでクリア。

import processing.video.*;

Capture camera;
Point[] points = {}; //線分の端点を保持する配列

void setup() {
  size(640, 480);
  smooth();

  String[] cameras = Capture.list(); //利用可能な動画入力の配列を取得
  
  if (cameras.length == 0) {
    println("There are no cameras available for capture.");
    exit();
  } else {
    println("Available cameras:");
    for (int i = 0; i < cameras.length; i++) {
      println(cameras[i]);
    }
    
    camera = new Capture(this, cameras[0]); //MacのFaceTimeカメラの場合0番目
    camera.start();
  }
}

void draw() {
  if (camera.available() == true) {
    camera.read();
  }
  image(camera, 0, 0); //カメラ入力を表示

  stroke(255, 0, 0); //赤線
  strokeWeight(5); //太さ5
  for (int i = 1; i < points.length; i++) {
    line(points[i-1].x, points[i-1].y, points[i].x, points[i].y); //線分の描画
  }
}

void mouseClicked() {
  if(mouseButton == LEFT) { //左クリックで線分(端点)の追加
    Point point = new Point(mouseX, mouseY);
    points = (Point[])append(points, point);
  } else if(mouseButton == RIGHT) { //右クリックで線のクリア
    points = new Point[0];
  }
}

/**
 * 線の端点のクラス
 */
class Point {
  int x, y;
  
  Point(int ex, int ey) {
    x = ex;
    y = ey;
  }
}

Processing: 3次元に動き回る四角形にカメラ動画を表示

Processing(2.2.1)で、カメラから取り込んだ動画をマウスの動きに合わせて3次元に動き回る四角形に表示。

import processing.video.*;

Capture camera;

void setup() {
  size(640, 480, P3D);
  
  String[] cameras = Capture.list(); //利用可能な動画入力の配列を取得
  if (cameras.length == 0) {
    println("There are no cameras available for capture.");
    exit();
  } else {
    println("Available cameras:");
    camera = new Capture(this, cameras[0]); //MacのFaceTimeカメラの場合0番目
    camera.start();
  }
  
  noStroke(); //枠線なし
}

void draw() {
  if (camera.available()) {
    camera.read();
  }
  
  background(255, 0, 0); //背景はとりあえず赤
  
  translate(width/2, height/2, 0); //描画原点を中心に移動
  rotateX(mouseY / 200.0); //マウスの縦位置に応じてX軸を中心に回転
  rotateY(mouseX / 100.0); //マウスの横位置に応じてY軸を中心に回転

  int i = 100;
  int j = 100;
  int dim = 100;
  //正方形を頂点の集合として描く
  textureMode(IMAGE);
  beginShape();
  texture(camera); //カメラ入力をテクスチャとする。500x500の領域を使用
  vertex(i, j, 0, 0, 0);
  vertex(i+dim, j, 0, 500, 0);
  vertex(i+dim, j+dim, 0, 500, 500);
  vertex(i, j+dim, 0, 0, 500);
  endShape();
}

Processing: 動画上を3次元に動き回る四角形

Processing(2.2.1)で、カメラから取り込んだ動画上を四角形がマウスの動きに合わせて3次元に動き回る。

import processing.video.*;

Capture camera;

void setup() {
  size(640, 480, P3D);
  
  String[] cameras = Capture.list(); //利用可能な動画入力の配列を取得
  if (cameras.length == 0) {
    println("There are no cameras available for capture.");
    exit();
  } else {
    println("Available cameras:");
    camera = new Capture(this, cameras[0]); //MacのFaceTimeカメラの場合0番目
    camera.start();
  }
  
  noStroke(); //枠線なし
  fill(128, 128); //グレー、半透明
}

void draw() {
  if (camera.available()) {
    camera.read();
  }
  image(camera, 0, 0); //カメラ画像を表示
  
  translate(width/2, height/2, 0); //描画原点を中心に移動
  rotateX(mouseY / 200.0); //マウスの縦位置に応じてX軸を中心に回転
  rotateY(mouseX / 100.0); //マウスの横位置に応じてY軸を中心に回転

  int i = 100;
  int j = 100;
  int dim = 100;
  //正方形を頂点の集合として描く
  beginShape();
  vertex(i, j, 0);
  vertex(i+dim, j, 0);
  vertex(i+dim, j+dim, 0);
  vertex(i, j+dim, 0);
  endShape();
}

Processing: 静止画上にマウスの軌跡を描く

Processing(2.2.1)で、カメラから取り込んだ静止画上にマウスで絵(軌跡)を描く。

import processing.video.*;

Capture camera;

void setup() {
  size(640, 480); //ウィンドウサイズの指定
  String[] cameras = Capture.list();
  camera = new Capture(this, cameras[0]); //MacBook PROのFaceTimeカメラの場合配列の0番目
  camera.start();
}

void draw() {
  //draw()で描画するとリフレッシュレート毎に書き換わってしまうため、ここでは何もしない
}

void mouseClicked() {
  //マウス右クリックで静止画像を読み込み
  if(mouseButton == RIGHT) {
    camera.read();
    image(camera, 0, 0);
  }
}

void mouseDragged() {
  //マウス左ドラッグでマウスの位置に円を描く
  if(mouseButton == LEFT) {
      fill(256, 0, 0, 256);  //塗りつぶし色を指定。引数はR, G, B, α
      ellipse(mouseX, mouseY, 5.0, 5.0); //マウスの位置に円を描く
  }
}

Processing: サトクリフ五角形サンプルのリファクタリング

マット・ピアソン著『ジェネラティブ・アート Processingによる実践ガイド』「Chapter 8 フラクタル」に出てくる「サトクリフ五角形」のサンプルコードがどうも冗長なのでリファクタリングしてみた。特に、数学的に無意味な条件分岐を整理したら随分すっきりした。
f:id:soutoku:20140825101358j:plain
サトクリフ五角形

int _maxlevels = 5;
float _strutFactor = 0.2;

void setup() {
  size(800, 800); //オリジナルはsize(1000, 1000);
  smooth();
  FractalRoot pentagon = new FractalRoot();
  pentagon.drawShape();
}

class PointObj {
  float x, y;
  
  PointObj(float ex, float ey) {
    x = ex;
    y = ey;
  }
}

class FractalRoot {
  Branch rootBranch;
  
  FractalRoot() {
    float centerX = width/2;
    float centerY = height/2;
    PointObj[] points = new PointObj[5];
    int radius = 400;
    int apex = 0;
    for (int angle = 0; angle < 360; angle += 72) {
      float x = centerX + (radius * cos(radians(angle)));
      float y = centerY + (radius * sin(radians(angle)));
      points[apex] = new PointObj(x, y);
      apex++;
    }
    rootBranch = new Branch(0, 0, points);
  }
  
   void drawShape() {
     rootBranch.drawMe();
   }
}

class Branch {
  int level, num;
  PointObj[] outerPoints = {};
  PointObj[] midPoints = {};
  PointObj[] projPoints = {};
  Branch[] myBranches = {};
   
  Branch(int lev, int n, PointObj[] points) {
    level = lev;
    num = n;
    outerPoints = points;
    midPoints = calcMidPoints();
    projPoints = calcStrutPoints();
    
    if ((level + 1) < _maxlevels) {
      Branch childBranch = new Branch(level + 1, 0, projPoints);
      myBranches = (Branch[])append(myBranches, childBranch);
      
      for (int apex = 0; apex < outerPoints.length; apex++) {
        int nextApex = apex - 1;
        if (nextApex < 0) {
          nextApex += outerPoints.length;
        }
        PointObj[] newPoints = { projPoints[apex], midPoints[apex],
                              outerPoints[apex], midPoints[nextApex],
                              projPoints[nextApex] };
        childBranch = new Branch(level + 1, apex + 1, newPoints);
        myBranches = (Branch[])append(myBranches, childBranch);
      }
    }
  }
    
  void drawMe() {
    strokeWeight(5 - level);
    drawOuter();
    strokeWeight(0.5);
    drawMid();
    drawBranch();
  }

  void drawOuter() {
    for (int apex = 0; apex < outerPoints.length; apex++) {
      int nextApex = apex + 1;
      if (nextApex == outerPoints.length) {
        nextApex = 0;
      }
      line(outerPoints[apex].x, outerPoints[apex].y,
           outerPoints[nextApex].x, outerPoints[nextApex].y);
    }
  }
  
  void drawMid() {
    for (int apex = 0; apex < midPoints.length; apex++) {
      line(midPoints[apex].x, midPoints[apex].y,
           projPoints[apex].x, projPoints[apex].y);
    }
  }

  void drawBranch() {
    for (int apex = 0; apex < myBranches.length; apex++) {
      myBranches[apex].drawMe();
    }
  }
  
  PointObj[] calcMidPoints() {
    PointObj[] points = new PointObj[outerPoints.length];
    for (int apex = 0; apex < outerPoints.length; apex++) {
      int nextApex = apex + 1;
      if (nextApex == outerPoints.length) {
        nextApex = 0;
      }
      PointObj midPoint = calcMidPoint(outerPoints[apex],
                                       outerPoints[nextApex]);
      points[apex] = midPoint;
    }
    return points;
  }
      
  PointObj calcMidPoint(PointObj point1, PointObj point2) {
    float mx, my;
    mx = calcMid(point1.x, point2.x);
    my = calcMid(point1.y, point2.y);
    return new PointObj(mx, my);
  }
  
  float calcMid(float a, float b) {
    return a + ((b - a) / 2);
  }
  
  PointObj[] calcStrutPoints() {
    PointObj[] points = new PointObj[midPoints.length];
    for (int point = 0; point < midPoints.length; point++) {
      int nextPoint = point + 3;
      if (nextPoint >= midPoints.length) {
        nextPoint -= midPoints.length;
      }
      PointObj strPoint = calcProjPoint(midPoints[point],
                                        outerPoints[nextPoint]);
      points[point] = strPoint;
    }
    return points;
  }
  
  PointObj calcProjPoint(PointObj mp, PointObj op) {
    float px, py;
    px = mp.x - ((mp.x - op.x) * _strutFactor);
    py = mp.y - ((mp.y - op.y) * _strutFactor);
    return new PointObj(px, py);
  }
}

Processing: カメラ動画表示

Processing(2.2.1)で、カメラから入力した動画を画面表示する基本的なコード。

import processing.video.*;

Capture camera;

void setup() {
  size(640, 480); //表示するウィンドウのサイズ

  String[] cameras = Capture.list(); //利用可能な動画入力の配列を取得
  if (cameras.length == 0) {
    println("There are no cameras available for capture.");
    exit();
  } else {
    println("Available cameras:");
    camera = new Capture(this, cameras[0]); //MacのFaceTimeカメラの場合0番目
    camera.start();
  }
}

void draw() {
  if (camera.available()) {
    camera.read();
  }
  image(camera, 0, 0); //描画
}