スケーラブルアート論

提供:kuhalaboWiki
(版間での差分)
移動: 案内, 検索
(概要)
(概要)
20行: 20行:
 
;参考書
 
;参考書
 
*「数学から創るジェネラティブアート ―Processingで学ぶかたちのデザイン」([https://www.openprocessing.org/user/57914 Generative Art with Math])
 
*「数学から創るジェネラティブアート ―Processingで学ぶかたちのデザイン」([https://www.openprocessing.org/user/57914 Generative Art with Math])
*「The Nature of Code: Simulating Natural Systems with Processing」[https://wtf.tw/ref/shiffman.pdf pdf]
+
*「The Nature of Code: Simulating Natural Systems with Processing」[https://wtf.tw/ref/shiffman.pdf pdf] / [https://github.com/nature-of-code/noc-book git-hub]
  
 
== 開発環境 ==
 
== 開発環境 ==

2020年10月29日 (木) 22:06時点における版

目次

概要

前提スキル

一年生の時にメディアプログラミング演習Iを履修したのと同等のプログラミングスキルがあるものとして、授業を進めます。 もし、プログラミングに不安があるなら、上記テキストを使って、自分で予習や自習をしてください。 openFrameworksはProcessingと似ているため、Processingを知っていると、理解が早いです。

成績評価

確認テスト、課題で評価します。

授業概要及び到達目標
インタラクティブアートは芸術を基盤として科学や工学を統合する新しい領域である。生物科学に関連した分野として、人工生命、ライフゲーム、フラクタル、オートマトン、遺伝的アルゴリズム、ニューラルネットワークなど応用範囲の広いものが数多く存在する。

そういった生物に見られる特徴をアートに応用したジェネラティブアートの作品をC++のプログラミングを使用して、実際に作成してみる。

本講義の目標は以下の通り。

  1. 生物の特徴と生物的なシステムについて理解する。
  2. 複雑系システムについて理解し、応用例を作成できる。
  3. openFrameworksを使って作品のプログラミングができる。
参考書
  • 「数学から創るジェネラティブアート ―Processingで学ぶかたちのデザイン」(Generative Art with Math)
  • 「The Nature of Code: Simulating Natural Systems with Processing」pdf / git-hub

開発環境

開発環境としてopenFrameworks/MacOS XCode, Processing, p5.jsを使用します。

テキストや開発環境については、以下を参照してください。

予定

2020年度
  1. 9/25(金) ガイダンス,
    • Processingの準備
    • 生物と情報とアート
  2. 10/2(金) 最大公約数と矩形分割
    • ユークリッドの互除法(最大公約数)
    • 長方形を正方形で分割
    • 正方形の分割
    • 矩形の再帰的分割
  3. 10/9(金) 矩形分割とフィボナッチ数列
    • 無理数比の矩形分割
    • モンドリアンのCompositionの再現
    • フィボナッチ数列の可視化
    • フィボナッチらせん
    • 再帰的描画のらせん
  4. 10/16(金) フィボナッチ数列とらせん
    • フェルマーらせん
    • 離散的らせん
  5. 10/23(金) プログラミング課題制作1、遺伝的アルゴリズム(講義)
  6. 10/30(金)1次元セルオートマトン
    • パスカルの3角形
    • 基本セルオートマトン
  7. 11/6(金) 2次元セルオートマトン
    • 正方格子
    • ライフゲーム
    • 正6角形ライフゲーム
  8. 11/13(金) ラングトンのアリ
  9. 11/20(金) Boid https://processing.org/examples/flocking.html
  10. 11/27(金)反応拡散系モデル
  11. 12/4(金) フラクタル http://ariga.dwcmedia.jp/ProcessingWeb/Trail8Fractal.html
  12. 12/11(金) プログラミング課題制作2 、ニューラルネットワーク(講義)
  13. 12/18(金) まとめ確認テスト
2019年度
  1. 9/13(金) ガイダンス, 生物と情報とアート,openFrameworksプログラミング体験
  2. 9/20(金) 生物と情報とアート,XCodeを使用したopenFrameworksプログラミング実習
  3. 9/27(金) 幾何学図形の描画
    • (oF実習)
      • 教科書 1章 読み物として読む。
      • 教科書 2章 実際にプログラムを作ってみる。
      •  2-4「数値の記憶と計算」までをやり終えて、自作プログラムの実行ファイルを提出。
      • 幾何学図形の描画、色の設定、変数
      •  プロジェクトフォルダーのbinフォルダーの中にあります。
        • ファイル名 番号_名前のローマ字 例 1724000_suzukiichiro
    • 講義: ディープラーニングによる色の芸術的表現1
      • 完全情報確定ゼロサムゲーム、アルゴリズムとヒューリスティック、エキスパートシステム
  4. 10/4(金) 幾何学図形の描画
  5. 10/11(金)
    • (oF実習)
    •  2-11「より高度な表現」までを学習し、自作プログラムの実行ファイルを提出。
    • マウスアクション、摩擦、重力、軌跡のフェード
    • この日の授業までに2章を終えてください。2章までに学んで、制作したプログラムを提出してもらいます。
    • 講義:最大公約数と矩形分割
  6. 10/18(金)
    • (P5実習)
    •  Generative Art with MathのCh1, Ch2を学ぶ。
    • (oF実習)
    •  3-1,2,3を学習する。
      • 3-1 は、読んで理解してください。プログラム例は作らなくてもよいです。
      • 3-2 は、3-2-7「画像ファイルを扱う」だけでもよい。余裕がれば、他の単元を勉強してもよいです。、
      • 3-3 は、実際に新たにクラスを作成し、プログラムを作りながら、学習を進めてください。
    •  3-4「アドオンの利用」以降は学習しなくてもよい。関心に応じて学習してください。
    • 講義:らせん
  7. 10/25(金)
  8. 11/8(金)
    • (実習)離散的らせん
    • 講義:1次元セルオートマトン
  9. 11/15(金)
  10. 11/22(金)
    • (実習)2次元セルオートマトン、ライフゲーム
    • 講義:ラングトンのアリ
  11. 11/29(金)
    • (実習)ラングトンのアリ
    • 講義:Boid,Gray-Scott反応拡散系モデル
  12. 12/6(金)
    • (実習)
    • 講義:物理エンジン Box2D,フラクタルと自己相似形と再帰呼び出し
  13. 12/13(金)
    • (実習)Box2D,自己相似形と再帰呼び出し
    • 講義:ニューラルネットワーク、遺伝的アルゴリズム
  14. 12/20(金) 小テスト ,課題講評
    • 授業で扱った内容すべてが含まれます。
  15. 1/10(金) 予備日(出席は取りません)
  • 課題「創発ジェネラティブアートのプログラム」
    • 提出締切日 12/19(木) 
    • 授業で扱ったプログラムを土台として、自分のオリジナリティを加えた創発的なプログラムを提出してください。
    • 言語は、ProcessingかopenFrameworksのいずれかです。
    • ソースプログラムも採点の対象としますので、プロジェクトのフォルダー全体をzip圧縮して、提出して下さい。


Contents
  1. Scalable art, Generative art, Mathematical art, Artificial Intelligence, Artificial Life, Complext sysytem
  2. openFrameworks C++ / Xcode MacOSX
  3. Logic circuit
  4. 完全情報ゲーム:チェッカー、オセロ、チェス、将棋、囲碁
  5. Cell auttomaton
  6. Conway's game of life
  7. Wire world
  8. Random walk
  9. Langton's ant
  10. Boid
  11. Box2D
  12. Fractal, Self-similar
  13. Recursive call
  14. Complex square
  15. Mandelbrot
  16. Neural network
  17. Genetic algorithm
  18. Code, Chyper, Encript
  19. Space X
  20. Robotics
  21. Expert system
  22. Fourier transform, spectrum
  23. Fibonacci number
  24. Belousov-Zhabotinsky reaction
  25. Gray-Scott model
  26. Turing pattern

生物と情報とアート

自然界の興味深いパターン
  • 自己相似性、フラクタル
    • 雪の結晶(0:25)
    • 樹木(1:17)
    • オウム貝(1:30)
  • らせん、渦巻き状パターン
  • 黄金角とフィボナッチ数列(3:00)

論理回路

https://wwws.kobe-c.ac.jp/deguchi/sc180/logic/gate.html

矩形分割

フィボナッチ数列

らせん

セルオートマトン

人工生命

ラングトンのアリ

レイノルズのボイド

反応拡散系

フラクタル

Neural Networks

Genetic Algorithm

oFサンプル集

ランダムウォーク

1次元セルオートマトン

ライフゲーム

ラングトンのアリ

Boid

物理エンジン Box2D

自己相似形

資料

  • new ⇐  old
    • ofDrawLine ⇐ ofLine
    • ofDrawCurve ⇐  ofCurve
    • ofDrawBezier ⇐  ofBezier
    • ofDrawCircle ⇐  ofCircle
    • ofDrawEllipse ⇐  ofEllipse
    • ofDrawTriangle ⇐  ofTriangle
    • ofDrawRectangle ⇐  ofRect
    • ofDrawRectRounded ⇐  ofRectRounded
    • ofDrawSphere ⇐  ofSphere
    • ofDrawCone ⇐  ofCone
    • ofBox ⇐  ofDrawBox

oF新規プロジェクトの作成

  1. oFフォルイダー内のprojectGeneratorフォルダー内のprojectGeneratorを実行する。
  2. Project Path:にoFのあるフォルダーを指定する。
  3. Project Name:に、プロジェクトの名前を入れる。
  4. Addons:に、使用する追加機能(アドオン)を入れる。通常は、なしでよい。
  5. Generateをクリックする。
  6. Apps内のMyAppsにマイプロジェクトが作成されている。
  7. Open IDEをクリックした場合
    • XCodeが立ち上がることを確認する。
  8. Closeをクリックした場合
    • Apps内のMyAppsに作成したプロジェクトフォルダーを開く。
    • プロジェクト名.xcodeprojファイルをクリックして、XCodeを起動する。
  9. 作成したプロジェクトを起動し、srcを見てみる。
    • ofApp.cppのメソッドの中身が空っぽ。
    • ここにプログラムを書いていく。

oFクラスの作成

XCode

  1. 新しくクラスを作るには、「Fileメニュー > New > File」 を開く。
  2. 「macOS」タブの「Source」から、「C++ File」を選び、「Next」ボタンを押す。
  3. Nameにはクラス名を入れます。その際、「Also create a header file」のチェックを入れておきます。そして「Next」ボタンを押します。
    • 名前を それぞれXxx.cppXxx.hとし、場所はともに ..\src とする。
  4. srcの中にXxx.cppXxx.h が新規作成される。

Visual Studio

  1. 新しくクラスを作るには、「プロジェクト > 新しい項目の追加...」 を開き,「C++ファイル」「ヘッダーファイル」を一つずつ作る。
    • 名前を それぞれXxx.cppXxx.hとし、場所はともに ..\src とする
    • (注)「クラスの追加」や「クラスウィザード」は使えない。
  2. マウスカーソルをソリューションエクスプローラー上のsrcに置き、ハイライトさせる。
  3. ソリューションエクスプローラー上のsrcの中にXxx.cppXxx.h が新規作成される。

ヘッダファイル Xxx.h は,

#pragma once
#include "ofMain.h"

class Xxx {
private:
	ofPoint pos;
	float radius;

public:
	Xxx();
	void hogehoge();
};

などと、記述する。

  • ofMain.h をインクルードし、クラスの定義の最後にセミコロンがつくことに注意する。
  • #pragma once は,このヘッダファイルを複数回読み込まないようにするためのもの。
  • 括弧で囲まれた部分 {...} には,変数の宣言やメソッド(関数)の宣言を書く
  • private: に続く部分には,クラス内部のみで利用する変数、メソッドを宣言する。
  • public: に続く部分には,クラス外部からアクセスできる変数、メソッドを宣言する。
  • Xxx(): はコンストラクターといい、クラスと同じ名前のメソッドである。クラスのインスタンスを生成するときの初期化処理などを記述する。

C++ファイル Xxx.cpp は,

#include "Xxx.h" // クラスのヘッダーを読み込む

Xxx::Xxx(){
	pos = ofPoint(ofGetWidth()/2, ofGetHeight()/2);
	radius = 100.0;
}

void Xxx::hogehoge(){
	ofSetColor(31, 63, 255, 100);
	ofCircle(pos.x, pos.y, radius);

	ofSetColor(255, 0, 0, 200);
	ofCircle(pos.x, pos.y, radius);
}

などと、メソッドの本体を記述する。

  • メソッドの定義の最後にセミコロンがつかないことに注意する。


もとのcppファイルodApp.cppのヘッダーファイルofApp.hに、Xxx.hをincludeする。 例えば、ofApp.hは、以下のとおり。

#pragma once

#include "ofMain.h"
#include "Ball.h"

class ofApp : public ofBaseApp{
public:
	bool mouse_pressed;

public:
	void setup();
	void update();
	void draw();

	void keyPressed(int key);
	void keyReleased(int key);
	void mouseMoved(int x, int y );
	void mouseDragged(int x, int y, int button);
	void mousePressed(int x, int y, int button);
	void mouseReleased(int x, int y, int button);
	void windowResized(int w, int h);
	void dragEvent(ofDragInfo dragInfo);
	void gotMessage(ofMessage msg);

	Xxx myCbj;
};

publicの領域にXxxクラスのインスタンスmyObjを宣言している。

P5サンプル集

音に反応する円

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

リンク

http://gushwell.ifdef.jp/

素数のグラフィック http://www.datapointed.net/visualizations/math/factorization/animated-diagrams/?infinity

個人用ツール
名前空間

変種
操作
案内
ツールボックス