yoppa.org


immediate bitwave

前橋工科大学 – デザイン演習 II 2022

第2課題演習 – The Last Clockをp5.jsで作ってみる

「時間を表現する」という第2課題の練習として、The Last Clockをp5.jsで実現してみましょう!

カメラ入力基本

画面中央にカメラ映像(640 x 480)を表示するサンプル

let capture;

function setup() {
  createCanvas(windowWidth, windowHeight);
  //Webcamキャプチャー設定
  capture = createCapture(VIDEO);
  capture.size(640, 480);
  capture.hide();
}

function draw() {
  background(0);
  //キャプチャーした映像を画面中央に描画
  imageMode(CENTER);
  image(capture, width / 2, height / 2, 640, 480);
}

スリット画像抽出

中心の縦1ピクセル分だけ抽出する (スリット)

let capture;
let slitX = 0;

function setup() {
  createCanvas(windowWidth, windowHeight);
  //Webcamキャプチャー設定
  capture = createCapture(VIDEO);
  capture.size(640, 480);
  capture.hide();
  background(0);
}

function draw() {  
  imageMode(CENTER);
  //カメラ映像の左右の中心1pixelを抽出
  let scan = capture.get(capture.width/2, 0, 1, 480);
  //抽出した画像を描画
  image(scan, width/2, height/2);
}

スリットスキャン

スリットで抽出した画像を横に並べていく(スリットスキャン)

let capture;
let slitX = 0; //スキャンするスリットの位置

function setup() {
  createCanvas(windowWidth, windowHeight);
  
  //Webカムからキャプチャー (640x480)
  capture = createCapture(VIDEO);
  capture.size(640, 480);
  capture.hide();

  background(0);
}

function draw() {
  //イメージを中央揃えで
  imageMode(CENTER);
  //カメラの左右の中心の1ピクセル幅の帯をキャプチャー
  let scan = capture.get(capture.width / 2, 0, 1, capture.height);
  //左から右に移動しながらキャプチャーした画像を描画
  image(scan, slitX, height / 2, 1, capture.height);
  //描画位置を1ピクセル右へ
  slitX = slitX + 1;
  //もし画面の右端まできたら左からくりかえし
  if(slitX > width) {
    slitX = 0;
  }
}

スキャンした画像を回転 (1分で1周)

let capture;
let slitX = 0;

function setup() {
  createCanvas(windowWidth, windowHeight);
  //Webcamキャプチャー設定
  capture = createCapture(VIDEO);
  capture.size(640, 480);
  capture.hide();
  background(0);
}

function draw() {
  imageMode(CENTER);
  //カメラ映像の左右の中心1pixelを抽出
  let scan = capture.get(capture.width / 2, 0, 1, 480);
  //ミリ秒を換算した秒を計算
  let ms = millis() / 1000.0;
  let s = second();
  s = (s / 1000.0) + ms;
  //円形にスキャンした画像の軌跡を描く
  translate(width / 2, height / 2);
  push();
  rotate(radians(s * 6.0));
  image(scan, 0, -height / 3, 4, height / 6);
  pop();
}

The Last Clockへ!

分針と時針を追加して、The Last Clockのカバーへ!

let capture;
let slitX = 0;

function setup() {
  createCanvas(windowWidth, windowHeight);
  //Webcamキャプチャー設定
  capture = createCapture(VIDEO);
  capture.size(640, 480);
  capture.hide();
  background(0);
}

function draw() {
  imageMode(CENTER);
  //カメラ映像の左右の中心1pixelを抽出
  let scan = capture.get(capture.width / 2, 0, 1, 480);
  //ミリ秒を換算した秒を計算
  let ms = millis() / 1000.0;
  let s = second();
  s = (s / 1000.0) + ms;
  let m = minute() + (second() / 60.0);
  let h = hour() + (minute() / 60.0);
  //円形にスキャンした画像の軌跡を描く
  translate(width / 2, height / 2);
  //秒針
  push();
  rotate(radians(s * 6.0));
  image(scan, 0, -height / 12 * 5, 2, height / 6);
  pop();
  //分針
  push();
  rotate(radians(m * 6.0));
  image(scan, 0, -height / 12 * 3, 1, height / 6);
  pop();
  //時針
  push();
  rotate(radians(h * 30.0));
  image(scan, 0, -height / 12, 1, height / 6);
  pop();
  //枠線
  noFill();
  stroke(127);
  strokeWeight(0.5);
  circle(0, 0, height);
  circle(0, 0, height/3*2);
  circle(0, 0, height/3);
}

応用: スリットを自由に動かしてみる!

リサジュー図形 + 回転

let capture;
let slitX = 0;
let slitY = 0;
let scanRot = 0;
 
function setup() {
  createCanvas(windowWidth, windowHeight);
  capture = createCapture(VIDEO);
  capture.size(640, 480);
  capture.hide();
  background(0);
}
 
function draw() {
  //画面の中心を減点に
  translate(width / 2, height / 2);
  imageMode(CENTER);
  //1ピクセルのスリットをキャプチャー
  let scan = capture.get(capture.width / 2, 0, 1, capture.height);
  //三角関数でリサジュー図形に
  slitX = cos(frameCount / 200.0) * width / 4;
  slitY = sin(frameCount / 230.0) * width / 4;
  scanRot = scanRot + 0.3;
  //指定した場所に画像を描く
  push();
  translate(slitX, slitY);
  rotate(radians(scanRot));
  image(scan, 0, 0, 10, capture.height);
  pop();
}

グニャグニャビデオ

The Fourth Dimension (1988) – Zbigniew Rybczynski 風エフェクト

let capture;
let div = 128.0;
let imageBuffer = [];

function setup() {
  createCanvas(windowWidth, windowHeight);
  capture = createCapture(VIDEO);
  capture.size(640, 480);
  capture.hide();
  background(0);
}

function draw() {
  translate(width / 2 - capture.width / 2, height / 2 - capture.height / 2);
  let snap = capture.get(0, 0, capture.width, capture.height);
  imageBuffer.push(snap);
  if (imageBuffer.length > div) {
    imageBuffer.shift();
  }
  for (let i = 0; i < imageBuffer.length; i++) {
    let ypos = capture.height / div * i;
    let img = imageBuffer[i].get(0, ypos, capture.width, capture.height / div + 1);
    image(img, 0, capture.height / div * i);
  }
}

次回までの課題

  • 作品にタイトルをつける
  • 本日のエスキースを踏まえて、より精緻なスケッチを作成する
  • 展示の際の方法などもざっくりと考えてくること