スケーラブルアート論
(→Processingサンプル集) |
(→ベクトル) |
||
| 106行: | 106行: | ||
=== ベクトル === | === ベクトル === | ||
「Nature of Code」第1章の「1.1-1.6」[https://wtf.tw/ref/shiffman.pdf pdf] | 「Nature of Code」第1章の「1.1-1.6」[https://wtf.tw/ref/shiffman.pdf pdf] | ||
| + | [高校数学II ベクトルの定義 https://www.youtube.com/playlist?list=PLiRy47VSZM635-b9NzlvebaOzI6m9zzvG] | ||
=== 位置・速度・加速度 === | === 位置・速度・加速度 === | ||
2021年11月4日 (木) 21:14時点における版
目次 |
概要
- 前提スキル
メディアプログラミング演習Iを履修したのと同等のプログラミングスキルがあるものとして、授業を進めます。
- 成績評価
確認テスト、課題で評価します。
- 授業概要及び到達目標
- インタラクティブアートは芸術を基盤として科学や工学を統合する新しい領域である。生物科学に関連した分野として、人工生命、ライフゲーム、フラクタル、オートマトン、遺伝的アルゴリズム、ニューラルネットワークなど応用範囲の広いものが数多く存在する。
そういった生物に見られる特徴をアートに応用したジェネラティブアートの作品をC++のプログラミングを使用して、実際に作成してみる。
本講義の目標は以下の通り。
- 生物の特徴と生物的なシステムについて理解する。
- 複雑系システムについて理解し、応用例を作成できる。
- openFrameworksを使って作品のプログラミングができる。
- 参考書
- 「数学から創るジェネラティブアート ―Processingで学ぶかたちのデザイン」(Generative Art with Math)
- 「The Nature of Code: Simulating Natural Systems with Processing」pdf / git-hub
- The Nature of Codeの日本語版(Processingではじめる自然現象のシミュレーション) PDF版
- Web
開発環境
開発環境としてopenFrameworks/MacOS XCode, Processing, p5.jsを使用します。
テキストや開発環境については、以下を参照してください。
- openframeworks https://openframeworks.cc/ja/
- http://www.kuhalabo.net/kxoops/modules/d3blog/details.php?bid=141
- https://processing.org/
- p5.js http://p5js.org
- ドットインストールp5.js入門 http://dotinstall.com/lessons/basic_p5js
- Generative Design with p5.js http://www.generative-gestaltung.de/
- Generative Art with Math https://www.openprocessing.org/user/57914
- Generative Design
Contents
- Scalable art, Generative art, Mathematical art, Artificial Intelligence, Artificial Life, Complext sysytem
- openFrameworks C++ / Xcode MacOSX
- Logic circuit
- 完全情報ゲーム:チェッカー、オセロ、チェス、将棋、囲碁
- Cell auttomaton
- Conway's game of life
- Wire world
- Random walk
- Langton's ant
- Boid
- Box2D
- Fractal, Self-similar
- Recursive call
- Complex square
- Mandelbrot
- Neural network
- Genetic algorithm
- Code, Chyper, Encript
- Space X
- Robotics
- Expert system
- Fourier transform, spectrum
- Fibonacci number
- Belousov-Zhabotinsky reaction
- Gray-Scott model
- Turing pattern
生物と情報とアート
- 生物とは? 生物の特徴とは?
- 例:小石と貝殻
- 「生物と無生物の違いは何か?」説明してみよう。
- ゲノムのDNAマップ NCBI Genome Map Viewer
- ヒト一人を再生するのに必要な情報量は?
- 自己相似性、フラクタル
- 雪の結晶(0:25)
- 樹木(1:17)
- オウム貝(1:30)
- らせん、渦巻き状パターン
- 黄金角とフィボナッチ数列(3:00)
- ジェネラティブアート
- 自律性
- 予測不可能性
- パラメータ変形
- 偶発性
- 自己相似性
- 再帰性
- 対称性
- 周期性
- 双対性
- 抽象化と具体化
数学と力学の基礎
Nature of Code Chapter 1 Vector Git Processing
ベクトル
「Nature of Code」第1章の「1.1-1.6」pdf [高校数学II ベクトルの定義 https://www.youtube.com/playlist?list=PLiRy47VSZM635-b9NzlvebaOzI6m9zzvG]
位置・速度・加速度
「Nature of Code」第1章の「1.7-1.10」pdf
- 動くボールの位置、速度、加速度はベクトルとして表すことができます。
- 速度は、位置の変化の割合、すなわち「次の位置=現在位置+速度」
- 秒速10m/sのボールの1秒後の位置=現在位置+10
- 加速度は、速度の変化の割合、すなわち「次の速度=現在速度+加速度」
- 自然落下運動の加速度は、重力加速度といい、9.8m/s2(秒の2乗)
- したがって、自然落下するボールの1秒後の速度=現在速度+9.8
- 重力加速度 国土地理院 「重力を知る」https://www.gsi.go.jp/buturisokuchi/grageo_gravity.html
トポロジー
- パックマン型2次元世界は、3次元ではトーラス(ドーナツ型)
- https://wakara.co.jp/mathlog/20200204
数学アート
矩形分割
フィボナッチ数列
らせん
整数の合同
コラッツ予想
人工生命(ALife)
セルオートマトン
ラングトンのアリ
レイノルズのボイド
反応拡散系
フラクタル
人工知能(AI)
Genetic Algorithm
Neural Networks
Processing Samples
音に反応する円
minimライブラリーをインストールする。
/**
* Circles responding Sound Level
*/
import ddf.minim.spi.*;
import ddf.minim.signals.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
import ddf.minim.ugens.*;
import ddf.minim.effects.*;
Minim minim;
AudioInput in;
void setup(){
size(500, 500);
minim = new Minim(this);
in = minim.getLineIn(Minim.STEREO, 512);
background(0);
}
void draw(){
colorMode(RGB, 255);
fill(0, 150);
rect(-1, -1, width, height);
colorMode(HSB, 360, 100, 100);
float brightness = 50 + map(in.mix.level(), 0, 0.5, 0, 50);
float hue = map(in.mix.level(), 0, 0.7, 0, 360);
fill(hue, 100, brightness);
float radious = 50 + map(in.mix.level(), 0, 0.5, 0, 100);
int x = 250;
int y = 250;
ellipse( x, y, radious *2, radious * 2);
}
void stop(){
in.close();
minim.stop();
super.stop();
}
カメラ入力
Video|GStreamer-based video library for Processingライブラリをインストール。
- 使用可能なカメラのリスト出力
import processing.video.*;
void setup(){
size(320, 240);
String[] cameras = Capture.list();
for(int i=0; i<cameras.length; i++){
println("[" + i + "] " + cameras[i]);
}
}
- カメラ画像の出力
import processing.video.*;
Capture cam;
void setup(){
size(640, 480);
String[] cameras = Capture.list();
for(int i=0; i<cameras.length; i++){
println("[" + i + "] " + cameras[i]);
}
cam = new Capture(this, cameras[1]);
cam.start();
}
void draw(){
if(cam.available() == true){
cam.read();
}
image(cam, 0, 0);
}
- 差分から動きを検出
import processing.video.*;
int numPixels;
int[] previousFrame;
int noiseFilter = 50;
Capture video;
void setup() {
size(640, 480);
video = new Capture(this, width, height, 30);
video.start();
numPixels = video.width * video.height;
previousFrame = new int[numPixels];
loadPixels();
}
void draw() {
if (video.available()) {
video.read();
video.loadPixels();
int movementSum = 0;
for (int i = 0; i < numPixels; i++) {
color currColor = video.pixels[i];
color prevColor = previousFrame[i];
//R, G, B
int currR = (currColor >> 16) & 0xFF;
int currG = (currColor >> 8) & 0xFF;
int currB = currColor & 0xFF;
//
int prevR = (prevColor >> 16) & 0xFF;
int prevG = (prevColor >> 8) & 0xFF;
int prevB = prevColor & 0xFF;
//
int diffR = abs(currR - prevR);
int diffG = abs(currG - prevG);
int diffB = abs(currB - prevB);
//noiseFilter
if (diffR + diffG + diffB > noiseFilter) {
movementSum ++;
pixels[i] = color(currR, currG, currB);
//
//pixels[i] = 0xFF000000 | (currR << 16) | (currG << 8) | currB;
} else {
pixels[i] = color(0);
}
//
previousFrame[i] = currColor;
}
updatePixels(); //
println(movementSum); //
}
}
引力と加速度
「Nature of Code」第1章の「1.10 Interactivity with Acceleration」(p57)より。(一部改変)pdf
- 粒子はマウスポインタに引力で引き付けられれ、軌跡を残しながらマウスに近づく。
- 引力は、距離が近いほど、強くなる(反比例)。
- 速度には上限(topspeed)があり、引力と粒子の運動量(速度)が釣り合うと、マウスのまわりを回る惑星のような動きになる。
- Moverクラスの作成
- ベクトルPVectorを使い、location(位置)、velocity(速度)、acceleration(加速度)定義し、力学運動を記述している。
- 速度は、現在速度に加速度を加算 velocity.add(acceleration);
- 位置は、現在位置に速を加算 location.add(velocity);
Mover[] movers = new Mover[1000];//An array of objects
void setup() {
size(1000, 1000);
smooth();
background(0);
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover();// Initialize each object in the array.
}
}
void draw() {
// background(0);
fill(0,40);
rect(0,0,width,height);
for (int i = 0; i < movers.length; i++) {
//Calling functions on all the objects in the array
movers[i].update();
movers[i].checkEdges();
movers[i].display();
}
}
class Mover {
PVector location;
PVector velocity;
PVector acceleration;
float topspeed;
Mover() {
location = new PVector(random(width), random(height));
velocity = new PVector(0, 0);
topspeed = 4.5;
}
void update() {
//Our algorithm for calculating acceleration:
//Find the vector pointing towards the mouse.
PVector mouse = new PVector(mouseX, mouseY);
PVector dir = PVector.sub(mouse, location);
float magn = dir.mag();
dir.normalize();// Normalize.
dir.mult(13 / magn );
// dir.mult(0.5);// Scale.
acceleration = dir;// Set to acceleration.
//Motion 101! Velocity changes by acceleration. Location changes by velocity.
velocity.add(acceleration);
velocity.limit(topspeed);
location.add(velocity);
}
void display() {// Display the Mover
// stroke(0);
noStroke();
fill(250,255,100);
ellipse(location.x, location.y, 10, 10);
}
void checkEdges() {// What to do at the edges
if (location.x > width) {
location.x = 0;
} else if (location.x < 0) {
location.x = width;
}
if (location.y > height) {
location.y = 0;
} else if (location.y < 0) {
location.y = height;
}
}
}
画像ファイルの結合
imagesフォルダにある画像_i000.pngから_i007.png(640*480)を縦2列、横4行に並べて結合する。
| 000 | 004 |
| 001 | 005 |
| 002 | 006 |
| 003 | 007 |
String folderName = "images";
String filePrefix = "_i";
int imageWidth = 640;
int imageHeight = 480;
int margin = 0;
int imageNumX = 2;
int imageNumY = 4;
int imageNum = imageNumX * imageNumY;
// X*Y
int canvasWidth = imageNumX * imageWidth;
int canvasHeight = imageNumY * imageHeight;
PImage images[] = new PImage[imageNum];
void setup() {
for (int i = 0; i < imageNum; i++) {
images[i] = loadImage(folderName + "/" + filePrefix + nf(i, 3) + ".png");
}
surface.setSize(canvasWidth, canvasHeight);
noLoop();
}
void draw() {
background(255);
for (int i = 0; i < imageNumX; i++) {
for(int j = 0; j < imageNumY; j++){
image(images[i*imageNumY + j], imageWidth * i, imageHeight * j, imageWidth, imageHeight);
}
}
save(folderName + "_combine.png");
exit();
}
リンク
素数のグラフィック http://www.datapointed.net/visualizations/math/factorization/animated-diagrams/?infinity