スケーラブルアート論

提供:kuhalaboWiki
(版間での差分)
移動: 案内, 検索
(ワイヤワールド)
(文字列を画面中央に表示)
 
(1人の利用者による、間の574版が非表示)
1行: 1行:
 
== 概要 ==
 
== 概要 ==
 
;前提スキル
 
;前提スキル
一年生の時にメディアプログラミング演習Iを履修したのと同等のプログラミングスキルがあるものとして、授業を進めます。
+
*一年生の時にメディアプログラミング演習Iを履修し、基本的なProcessingのプログラミングができること。
もし、プログラミングに不安があるなら、上記テキストを使って、自分で予習や自習をしてください。
+
** 不安な人は、以下の野口先生のメディアプログラミング演習Iのサイトで復習してください。https://r-dimension.xsrv.jp/classes_j/category/processing/
openFrameworksはProcessingと似ているため、Processingを知っていると、理解が早いです。
+
*個人のPC(Windows、MacOSのどちらでもよい)に自分でProcessingの環境を構築できることが望ましい。
  
;成績評価
+
;授業概要
*出席:学生証scan+[http://www.kuhalabo.net/~web/examination/mpaper/min_paper.php?subj_id=3&grade=2 Minutes paper]
+
* インタラクティブアートは芸術を基盤として科学や工学を統合する新しい領域で、プログラミングなどのIT技術によって実現されます。プログラミングによって制作プロセスをアルゴリズム化した作品は、拡張性が高く(スケーラブル)、多様性を持たせることが容易です。これが、スケーラブルアートです。
*課題:セルオートマトン課題、再帰呼び出し図形課題、複素平面フラクタル課題
+
* この授業では、その中でも、生物に見られる生成的(ジェネラティブ)な特徴をアートに応用したジェネラティブアートに関連する分野を扱います。その中には、人工生命、フラクタル、オートマトン、遺伝的アルゴリズム、ニューラルネットワークなどといったものが含まれます。
*小テスト:[http://www.kuhalabo.net/~web/examination/result_highscore.php?subj_id=3 ハイスコア]
+
*プログラミングを使用して、スケーラブルな特徴を持つ作品を作成します。
  
;授業概要及び到達目標
+
;使用ソフト
:インタラクティブアートは芸術を基盤として科学や工学を統合する新しい領域である。生物科学に関連した分野として、人工生命、ライフゲーム、フラクタル、オートマトン、遺伝的アルゴリズム、ニューラルネットワークなど応用範囲の広いものが数多く存在する。
+
*Processingを使用します。https://processing.org/
そういった生物に見られる特徴をアートに応用したジェネラティブアートの作品をC++のプログラミングを使用して、実際に作成してみる。
+
  
本講義の目標は以下の通り。
+
;到達目標
 +
*スケーラブルアートについて理解し、応用例を作成できる。
 +
*生物の特徴と生物的なシステムについて理解する。
 +
*Processingを使ってジェネラティブアートのプログラミングができる。
  
# 生物の特徴と生物的なシステムについて理解する。
+
;成績評価
# 複雑系システムについて理解し、応用例を作成できる。
+
*確認テスト、課題、まとめテストで、100点満点で評価します。
# openFrameworksを使って作品のプログラミングができる。
+
 
 +
;参考資料
 +
*「[http://www.kuhalabo.net/kxoops/modules/d3blog/details.php?bid=178 数学から創るジェネラティブアート ―Processingで学ぶかたちのデザイン]」([https://www.openprocessing.org/user/57914 Generative Art with Math])
 +
*「The Nature of Code: Simulating Natural Systems with Processing」
 +
**英語PDF版は無料でダウンロードできます。https://wtf.tw/ref/shiffman.pdf
 +
**日本語PDF版を右のサイトで購入できます。https://wgn-obs.shop-pro.jp/?pid=144269527
 +
**ソースコードがGithubで公開されています。https://github.com/nature-of-code/
 +
*Processingのチュートリアル [https://processing.org/tutorials/ Processing Tutorial]
  
 
== 開発環境 ==
 
== 開発環境 ==
  
開発環境として[[openFrameworks for Visual studio]]を使用します。
 
  
テキストや開発環境については、以下を参照してください。
+
開発環境については、以下を参照してください。
* http://www.kuhalabo.net/kxoops/modules/d3blog/details.php?bid=141
+
  
== 予定 ==
+
* https://processing.org/
2020年度から開講予定です。
+
* 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
 +
** https://gihyo.jp/book/2019/978-4-297-10463-4/support/
  
;2020年度
+
* Generative Design
 +
**https://github.com/generative-design/Code-Package-Processing-3.x
  
# Scalable art, Generative art, Mathematical art, Artificial Intelligence, Artificial Life, Complext sysytem
+
* Reference https://processing.org/reference
# 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
+
# Neural network
+
# Genetic algorithm
+
# Logic circuit
+
# Fourier transform
+
# Code, Chyper, Encript
+
# Space X
+
# Robotics
+
# Expert system
+
# Fourier transform, spectrum
+
# Fibonacci number
+
#
+
#
+
#
+
#
+
#
+
#
+
  
 
== 生物と情報とアート ==
 
== 生物と情報とアート ==
 
* 生物とは? 生物の特徴とは?
 
* 生物とは? 生物の特徴とは?
 
** 例:小石と貝殻
 
** 例:小石と貝殻
** * [http://www.kuhalabo.net/~kuha/easybbs/easy_bbs4klb2.php 簡単BBS]に「生物と無生物の違いは何か?」説明してみよう。
+
** 「生物と無生物の違いは何か?」説明してみよう。
* ゲノムのDNAマップ [http://www.ncbi.nlm.nih.gov/mapview/ NCBI Map Viewer]
+
* ゲノムのDNAマップ [https://www.ncbi.nlm.nih.gov/genome/gdv/ NCBI Genome Map Viewer]
 
* [http://www.kuhalabo.net/kxoops/modules/d3blog/details.php?bid=5 ヒト一人を再生するのに必要な情報量は?]
 
* [http://www.kuhalabo.net/kxoops/modules/d3blog/details.php?bid=5 ヒト一人を再生するのに必要な情報量は?]
  
== メモ ==
+
;[https://www.jw.org/ja/%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%83%BC/%E3%83%93%E3%83%87%E3%82%AA/%E5%89%B5%E9%80%A0%E3%81%AE%E9%A9%9A%E7%95%B0%E3%81%AF%E7%A5%9E%E3%81%AE%E6%A0%84%E5%85%89%E3%82%92%E8%A1%A8%E3%82%8F%E3%81%99/%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3/ 自然界の興味深いパターン]
Visual Studioのショートカット
+
*自己相似性、フラクタル
 +
**雪の結晶(0:25)
 +
**樹木(1:17)
 +
**オウム貝(1:30)
 +
*らせん、渦巻き状パターン
 +
*黄金角とフィボナッチ数列(3:00)
  
* Ctrl-K Ctrl-C コメントアウト
+
;ジェネラティブアート
* Ctrl-K Ctrl-U コメントアウト解除
+
:自律性
* Ctrl-K Ctrl-F インデントをそろえる
+
:予測不可能性
 +
:パラメータ変形
 +
:偶発性
 +
:自己相似性
 +
:再帰性
 +
:対称性
 +
:周期性
 +
:双対性
 +
:抽象化と具体化
  
[http://yoppa.org/ クリエイティブ・コーダー]
+
== 数学と力学の基礎 ==
 +
[https://github.com/nature-of-code/noc-examples-processing/tree/master/chp01_vectors Nature of Code Chapter 1 Vector Git Processing]
  
== 複雑系 ==
+
=== ベクトル ===
=== セルオートマトン ===
+
「Nature of Code」第1章の「1.1-1.6」[https://wtf.tw/ref/shiffman.pdf pdf]
  
*[http://ja.wikipedia.org/wiki/%E3%82%BB%E3%83%AB%E3%83%BB%E3%82%AA%E3%83%BC%E3%83%88%E3%83%9E%E3%83%88%E3%83%B3 セルオートマトン]
+
*ベクトルを復習するための動画:[https://www.youtube.com/playlist?list=PLiRy47VSZM635-b9NzlvebaOzI6m9zzvG 高校数学Bベクトルの定義・成分]
*[http://en.wikipedia.org/wiki/Elementary_cellular_automaton Elementary cellular automaton]
+
*[http://ja.wikipedia.org/wiki/%E3%82%B7%E3%82%A7%E3%83%AB%E3%83%94%E3%83%B3%E3%82%B9%E3%82%AD%E3%83%BC%E3%81%AE%E3%82%AE%E3%83%A3%E3%82%B9%E3%82%B1%E3%83%83%E3%83%88 シェルピンスキーのガスケット]
+
*[http://mathworld.wolfram.com/ElementaryCellularAutomaton.html Wolfram Math World 1次元セルオートマトン] /
+
  
=== ライフゲーム ===
+
=== 位置・速度・加速度 ===
 +
「Nature of Code」第1章の「1.7-1.10」[https://wtf.tw/ref/shiffman.pdf pdf]
  
*[https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B2%E3%83%BC%E3%83%A0 ライフゲーム]
+
* 動くボールの位置、速度、加速度はベクトルとして表すことができます。
*[http://www.kuhalabo.net/~kuha/tutorial0/bioart/Lifegame.exe ライフゲームの例] /  
+
* 速度は、位置の変化の割合、すなわち「次の位置=現在位置+速度」
*[http://www.kuhalabo.net/~kuha/tutorial0/bioart/cagallary/ セルオートマトン・ギャラリー] /
+
**秒速10m/sのボールの1秒後の位置=現在位置+10
 +
*加速度は、速度の変化の割合、すなわち「次の速度=現在速度+加速度」
 +
**自然落下運動の加速度は、重力加速度といい、9.8m/s2(秒の2乗)
 +
**したがって、自然落下するボールの1秒後の速度=現在速度+9.8
  
;セルオートマトン音楽
+
;重力加速度 国土地理院 「重力を知る」https://www.gsi.go.jp/buturisokuchi/grageo_gravity.html
[http://tones.wolfram.com/generate/ WolframTones]/
+
[http://tamw.atari-users.net/camus.htm CAMUS]/  
+
[http://www.glitchds.com/ Glitch DS]/
+
[http://www.kuhalabo.net/~kuha/nime/lifegorch/ Life Game Orchestra] /
+
  
;ギャラリー
+
=== トポロジー ===
[http://www.collidoscope.com/modernca/ Modern Cellular Automata]/
+
;パックマン型2次元世界は、3次元ではトーラス(ドーナツ型)
[http://prenzl.sourceforge.net/gallery/category.php CArt gallery]/
+
: https://wakara.co.jp/mathlog/20200204
[http://www.upl.cs.wisc.edu/~oblio/gnarly.html Cellular Automata Art]/
+
[http://akinao.at.infoseek.co.jp/ascii/index.html ASCII Art Cell Automaton]/  
+
  
=== ワイヤワールド ===
+
== 数学アート ==
[http://ja.wikipedia.org/wiki/%E3%83%AF%E3%82%A4%E3%83%A4%E3%83%AF%E3%83%BC%E3%83%AB%E3%83%89 ワイヤワールド] /
+
[http://mathworld.wolfram.com/WireWorld.html Wolfram Math World WireWorld]
+
  
=== 人工生命 ===
+
=== [[矩形分割]] ===
[http://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%B3%E3%82%B0%E3%83%88%E3%83%B3%E3%81%AE%E3%82%A2%E3%83%AA ラングトンのアリ] /
+
[http://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%B3%E3%82%B0%E3%83%88%E3%83%B3%E3%81%AE%E3%83%AB%E3%83%BC%E3%83%97 ラングトンのループ] /
+
[http://necsi.org/postdocs/sayama/sdsr/java/ 自己増殖ループ] /
+
[http://www.red3d.com/cwr/boids/ Reynolds Boid] /
+
  
http://www.local-guru.net/blog/2010/8/19/openframeworks-boid-demo
+
=== [[フィボナッチ数列]] ===
  
https://gist.github.com/tado/6603347
+
=== [[らせん]] ===
  
 +
=== [[整数の合同]] ===
  
Birds Algorhythm Craig Reynolds
+
=== [[コラッツ予想]] ===
http://processing.org/examples/flocking.html
+
  
== openFrameworks Visual C++プログラミング ==
+
== 人工生命(ALife) ==
  
;イントロダクション
+
=== [[セルオートマトン]] ===
: [[openFrameworks for Visual studio]]
+
  
* 参考サイト
+
=== [[ラングトンのアリ]] ===
** http://openframeworks.cc/documentation/
+
** http://yoppa.org/blog/4299.html
+
  
; 0.9での変更点
+
=== [[レイノルズのボイド]] ===
: https://qiita.com/2bbb/items/13f2e20760ec61e3ec89
+
: 教科書のソースプログラムは、0.8ベースなので、上記の変更に注意すること。
+
: 特に、描画系のコマンドが、ofDrawXXX()に変更になっています。例えば、以下の通り。
+
:* ofLine -> ofDrawLine
+
:* ofRect -> ofDrawRectangle
+
:* ofCircle -> ofDrawCircle
+
  
; oFの公式リファレンスは以下の通り。
+
=== [[反応拡散系]] ===
http://openframeworks.cc/documentation/
+
  
 +
=== [[フラクタル]] ===
  
=== [[1つのボールがふらふら動く]] ===
+
== 人工知能(AI) ==
  
=== [[配列とマウスインタラクション]] ===
+
=== [[Genetic Algorithm]] ===
  
=== [[クラスの使用]] ===
+
=== [[Neural Networks]] ===
  
=== [[ランダムウォーク]] ===
+
== Processing Samples ==
  
=== [[1次元セルオートマトン]] ===
+
===音に反応する円===
  
=== [[ライフゲーム]] ===
+
minimライブラリーをインストールする。
  
=== [[ラングトンのアリ]] ===
+
<pre>
 +
/**
 +
* Circles responding Sound Level
 +
*/
  
=== [[Boid]] ===
+
import ddf.minim.spi.*;
 +
import ddf.minim.signals.*;
 +
import ddf.minim.*;
 +
import ddf.minim.analysis.*;
 +
import ddf.minim.ugens.*;
 +
import ddf.minim.effects.*;
  
=== [[物理エンジン Box2D]] ===
+
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();
 +
}
 +
</pre>
  
=== Tips ===
 
  
;パーティクルの位置に画像を置く
+
=== カメラ入力 ===
ofApp.h
+
Video|GStreamer-based video library for Processingライブラリをインストール。
 +
 
 +
;使用可能なカメラのリスト出力
 
<pre>
 
<pre>
ofImage particleImage;
+
import processing.video.*;
 +
 
 +
void setup(){
 +
  size(320, 240);
 +
 
 +
  String[] cameras = Capture.list();
 +
 
 +
  for(int i=0; i<cameras.length; i++){
 +
    println("[" + i + "] " + cameras[i]);
 +
  }
 +
 
 +
}
 
</pre>
 
</pre>
  
ofApp.cpp
+
;カメラ画像の出力
 
<pre>
 
<pre>
setup(){
+
import processing.video.*;
  particleImage.loadImage("particle.png");
+
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();
 
}
 
}
  
draw(){
+
void draw(){
   particleImage.draw(pos.x, pos.y, w, h);
+
   if(cam.available() == true){
 +
    cam.read();
 +
  }
 +
 
 +
  image(cam, 0, 0);
 
}
 
}
 
</pre>
 
</pre>
  
;パーティクルの位置を辿る直線を描く
+
;差分から動きを検出
ofApp.cpp
+
 
 
<pre>
 
<pre>
ofBeginShape();
+
import processing.video.*;
     for(int i = 0; i < particle.size(); i++){
+
         ofVertex(pos[i].x, pos[i].y);
+
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;
 
     }
 
     }
ofEndShape();
+
 +
    updatePixels();   //
 +
    println(movementSum);    //
 +
  }
 +
}
 
</pre>
 
</pre>
  
;パーティクルの位置を辿る曲線を描く
+
 
ofApp.cpp
+
=== 引力と加速度 ===
 +
 
 +
「Nature of Code」第1章の「1.10 Interactivity with Acceleration」(p57)より。(一部改変)[https://wtf.tw/ref/shiffman.pdf pdf]
 +
*粒子はマウスポインタに引力で引き付けられれ、軌跡を残しながらマウスに近づく。
 +
*引力は、距離が近いほど、強くなる(反比例)。
 +
*速度には上限(topspeed)があり、引力と粒子の運動量(速度)が釣り合うと、マウスのまわりを回る惑星のような動きになる。
 +
*Moverクラスの作成
 +
**ベクトルPVectorを使い、location(位置)、velocity(速度)、acceleration(加速度)定義し、力学運動を記述している。
 +
** 速度は、現在速度に加速度を加算 velocity.add(acceleration);
 +
** 位置は、現在位置に速を加算 location.add(velocity);
 +
 
 
<pre>
 
<pre>
ofBeginShape();
+
Mover[] movers = new Mover[1000];//An array of objects
    for(int i = 0; i < particle.size(); i++){
+
void setup() {
        ofCurveVertex(pos[i].x, pos[i].y);
+
  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;
 
     }
 
     }
ofEndShape();
+
    if (location.y > height) {
 +
      location.y = 0;
 +
    } else if (location.y < 0) {
 +
      location.y = height;
 +
    }
 +
  }
 +
}
 
</pre>
 
</pre>
  
== フラクタル ==
 
古代ギリシャからあるユークリッド幾何学と20世紀のフラクタル幾何学の比較
 
  
;考察
+
=== 画像ファイルの結合 ===
:古代エジプト人は3:4:5の辺を持つ三角形で直角が得られることを知っていた.ピラミッドなどの巨大建造物.
+
imagesフォルダにある画像_i000.pngから_i007.png(640*480)を縦2列、横4行に並べて結合する。
:三平方の定理を発見したピタゴラスはどこがすごいか?
+
<table border=1>
 +
<tr><td>000</td><td>004</td></tr>
 +
<tr><td>001</td><td>005</td></tr>
 +
<tr><td>002</td><td>006</td></tr>
 +
<tr><td>003</td><td>007</td></tr>
 +
</table>
  
;フラクタル図形
+
<pre>
[http://www.kuhalabo.net/~kuha/tutorial0/bioart/Fractex.exe フラクタル図形の例]
+
String folderName = "images";
 +
String filePrefix = "_i";
  
[http://www.gaia.h.kyoto-u.ac.jp/~fractal/ フラクタル日除け]
+
int imageWidth = 640;
 +
int imageHeight = 480;
  
== 脳 ==
+
int margin = 0;
;脳波,脳電図(electroencephalogram EEG)
+
:大脳皮質のニューロンの膨大な数のシナプス結合における電位(シナプス後電位)の集合と考えられている。
+
:通常は,空間的および時間的分散性のために一定の形状の波形にはならない。しかし,大脳皮質の活性度が低下した時にはある程度の同期性がみられ,その代表的な状態が睡眠時の脳波である。
+
:開眼時,脳の神経細胞があちこちで活発に作動していると,シナプス電位は同期が取れずに,脳波はランダムなになり,特定の周波数は測定されない。
+
*デルタ波(δ波):1~3Hz ぐっすり睡眠.昏睡.
+
*シータ波(θ波):4~7Hz うたたうね.ぼんやり.
+
*アルファ波(α波):8~13Hz 覚醒,安静,閉眼時。リラックス。
+
*ベータ波(β波):14~30Hz 開眼時,五感が働いている状態。活発な思考。
+
*ガンマ波(γ波):30~64Hz 高次精神活動に関連(?)
+
*オメガ波(ω波):64~128Hz(?)
+
*ロー波(ρ波):128-512Hz (?)
+
*シグマ波(σ波):512-1024Hz (?)
+
*アーティファクト:ノイズ(雑音)。まばたき,眼球運動,電極の接着不良など脳と無関係のものが要因。
+
  
バイノーラルビート
+
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];
  
[http://www.aist.go.jp/aist_j/press_release/pr2010/pr20100329/pr20100329.html ニューロコミュニケーター]
+
void setup() {
 +
  for (int i = 0; i < imageNum; i++) {
 +
    images[i] = loadImage(folderName + "/" + filePrefix + nf(i, 3) + ".png");
 +
  }
 +
  surface.setSize(canvasWidth, canvasHeight);
 +
  noLoop();
 +
}
  
*[http://www.brl.ntt.co.jp/IllusionForum/ イリュージュン・フォーラム]
+
void draw() {
**[http://www.kuhalabo.net/~kuha/easy_bbs4klb2.php 簡単BBS]に聞こえ方を書いてみよう。
+
  background(255);
  
[http://www.mindball.se/ Mindball]
+
  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();
 +
}
 +
</pre>
  
== Neural Networks ==
 
*神経回路モデル(PPT)
 
*神経細胞の写真,構成図[ 1 | 2 | 3 ]
 
**[http://www.kuhalabo.net/~kuha/tutorial0/bioart/synapse1.jpg シナプスの構成図],[http://www.kuhalabo.net/~kuha/tutorial0/bioart/synapse2.jpg 接合部の詳細]
 
*[http://mars.elcom.nitech.ac.jp/java-cai/neuro/menu.html ニューラルネットワーク入門]
 
*Perceptron,
 
*Back Propagation
 
*Hopfield Network
 
*自己組織化ネットワーク
 
*脳の潜在能力
 
**天文学者カール・セーガン「人間の脳はおよそ2,000万冊,すなわち世界最大の図書館に収められているのと同じ数の本を満たすほどの情報を収納することができる」
 
**神経科学者「人は平均寿命の間に脳の潜在能力の0.01%(0.0001)しか使っていない」
 
  
== Genetic Algorithm ==
+
===配列のシャッフル===
*カール・セーガン「コスモス」エピソードII第3話「平家物語と蟹のなぞ」
+
 
**瀬戸内海の蟹の甲羅は武士の顔に似ているのはなぜか?
+
<pre>
[http://www.kuhalabo.net/~kuha/tutorial0/bioart/11_GA.pdf 配布資料PDF]
+
int[] nN = {0,1,2,3,4,5,6};
*geno typeとpheno type
+
 
*GAの概念と応用例
+
for(int i=(nN.length - 1); i>0; --i) {
**[http://www.kuhalabo.net/~kuha/tutorial0/bioart/papperedmoss.gif ペパードモスの絵],[http://www.kuhalabo.net/~kuha/tutorial0/bioart/pmoss/ ペパードモス・ゲーム]
+
  int j = (int)random(i+1);
**[http://prisonersdilemma.groenefee.nl/ The Prisoner's Dilemma]
+
  int tmp = nN[i];
**[http://www.kuhalabo.net/~kuha/tutorial0/bioart/art/Leaf.exe GA for ART]
+
  nN[i] = nN[j];
**[http://www.youtube.com/watch?v=8vzTCC-jbwM&feature=youtube_gdata_player GAでブランコこぎを学習]
+
  nN[j] = tmp;
 +
}
 +
</pre>
  
== 小テスト ==
 
* 場所 いつものPC演習室
 
* 出題 配布資料などから出題されます。ノート,配布資料などを復習しておいてください。問題の形式は,選択式です。
 
* 注意事項
 
** 座席は自由ですが,隣の座席を1つ空けて座ってください。
 
** 持ち込みは不可です。机の上には一切,何も置かないで下さい。
 
** PC上のソフトはブラウザだけ起動してください。他のアプリケーションはすべて終了させてください。
 
  
== Github ==
+
===クラスオブジェクトのソート===
共同開発するときに便利。
+
;バブルソート
 +
rectsをメンバlevelの値の小さい順にソートする。
  
学内のプロキシー環境で作業する場合、コンソールで
 
 
<pre>
 
<pre>
git config --global http.proxy proxy-n.t-kougei.ac.jp:8080
+
Kurasu[] rects = new kurasu[100];
git config --global https.proxy proxy-n.t-kougei.ac.jp:8080
+
 
 +
for(int j=0; j < rects.length - 1; j++){
 +
  for(int i=0; i < rects.length - 1; i++){
 +
    if(rects[i].level > rects[i+1].level){
 +
      Kurasu tmp = rects[i+1];
 +
      rects[i+1] = rects[i];
 +
      rects[i] = tmp;
 +
    }
 +
  }
 +
}
 +
 
 +
class Kurasu{
 +
  int index;
 +
  int level;
 +
}</pre>
 +
 
 +
 
 +
===3D回転===
 +
;X軸を中心にフェルマーらせんを回転
 +
* '''rotateX()'''を使う (https://processing.org/reference/rotateX_.html)
 +
* '''size()'''に'''P3D'''を指定
 +
<pre>
 +
 
 +
int itr = 0;  //描画の繰り返し回数
 +
float scalar = 5; //拡大倍率
 +
float rotation;
 +
float r =0;
 +
void setup() {
 +
  size(500, 500, P3D); // 3D座標を指定する
 +
  background(255);  //背景を白くする
 +
  rotation = (1 + sqrt(5)) / 2;
 +
}
 +
void draw() {
 +
  translate(width / 2, height / 2);  //描画ウィンドウの中心に移動
 +
  rotateX(r);
 +
  fill(0);  //点を黒く塗る
 +
 
 +
  float theta = 2 * PI * itr * rotation; //回転角
 +
  PVector v = PVector.fromAngle(theta);
 +
  v.mult(scalar * sqrt(itr));
 +
  ellipse(v.x, v.y, scalar, scalar); //点を描画
 +
 
 +
  itr++;
 +
  r = r + 0.01;
 +
}
 
</pre>
 
</pre>
とする。
 
  
通常のプロキシーのない環境で作業する場合、コンソールで
+
;Y軸を中心にフェルマーらせんを回転
 +
* '''rotateY()'''を使う (https://processing.org/reference/rotateY_.html)
 +
* '''size()'''に'''P3D'''を指定
 
<pre>
 
<pre>
git config --global --unset http.proxy proxy-n.t-kougei.ac.jp:8080
+
 
git config --global --unset https.proxy proxy-n.t-kougei.ac.jp:8080
+
int itr = 0;  //描画の繰り返し回数
 +
float scalar = 5; //拡大倍率
 +
float rotation;
 +
float r =0;
 +
void setup() {
 +
  size(500, 500, P3D); // 3D座標を指定する
 +
  background(255);  //背景を白くする
 +
  rotation = (1 + sqrt(5)) / 2;
 +
}
 +
void draw() {
 +
  translate(width / 2, height / 2);  //描画ウィンドウの中心に移動
 +
  rotateY(r);
 +
  fill(0);  //点を黒く塗る
 +
 
 +
  float theta = 2 * PI * itr * rotation; //回転角
 +
  PVector v = PVector.fromAngle(theta);
 +
  v.mult(scalar * sqrt(itr));
 +
  ellipse(v.x, v.y, scalar, scalar); //点を描画
 +
 
 +
  itr++;
 +
  r = r + 0.01;
 +
}
 
</pre>
 
</pre>
とする。
 
  
現在の設定を確認するには、コンソールで、
+
===文字列を画面中央に表示===
 +
;ウィンドウ画面の中央にテキストを配置する方法
 +
 
 +
文字の表示について、CENTERやwidth/2を使って、横方法は中央に配置することができます。
 +
しかし、縦方向については、英語のアルファベットの場合、文字によって、高さや縦の位置が異なるので、
 +
CENTERやheight/2では、うまくいきません。
 +
 
 +
フォントはベースラインを基準に作成されています。ベースラインから上の長さはAscent、ベースラインから下の長さはDescentと言います。
 +
例えば、小文字のj,p などはベースラインから下にはみ出ていますし、小文字のk,lなどは縦に長く、iは短めです。
 +
テキストの高さは、Ascent+Descentになります。
 +
 
 +
ref: https://github.com/alexheretic/ab-glyph/issues/6
 +
 
 +
これを計算して、縦の位置を指定する必要があります。
 +
例えば、以下のようにすると、ウィンドウの中央に配置できます。
 
<pre>
 
<pre>
git config --list
+
void setup() {
 +
  size(400, 400);
 +
  textSize(30);
 +
  textAlign(CENTER,TOP);
 +
  background(0);
 +
}
 +
void draw(){
 +
  float ascent = textAscent();
 +
  float descent = textDescent();
 +
  float textHeight = ascent + descent;
 +
  int textPosY = int(height-textHeight)/2;
 +
  text("pijlk,hello world", width/2, textPosY);
 +
}
 +
</pre>
 +
 
 +
===プログラム出力を動画にエクスポート===
 +
Processingで実行したプログラムの出力を動画にするには、
 +
一旦、saveFrame()関数で、コマ送りの静止画を保存して
 +
その後、MovieMakerで静止画をつなげて動画にします。
 +
 
 +
基本的には、draw()関数の最後にsaveFrame()関数を記述してプログラムを実行した後に、
 +
Processingのツールメニューから、ムービーメーカーを使って、書き出せばよいです。
 +
その際、コマ送りの静止画の数が多くなりすぎないように、frameRateを適度に設定するとよいでしょう。
 +
なお、frameRateのデフォルトは60です。
 +
 
 +
<pre>
 +
void setup(){
 +
  size(500,500);
 +
  frameRate(30);
 +
}
 +
int x = 0;
 +
void draw(){
 +
  if (x < 100) {
 +
    line(x, 0, x, 100);
 +
    x = x + 1;
 +
  } else {
 +
    noLoop();
 +
  }
 +
  // Saves each frame as line000001.png, line000002.png, etc.
 +
  saveFrame("line######.png");
 +
}
 
</pre>
 
</pre>
とする。
 
  
 
== リンク ==
 
== リンク ==
304行: 580行:
 
http://www.datapointed.net/visualizations/math/factorization/animated-diagrams/?infinity
 
http://www.datapointed.net/visualizations/math/factorization/animated-diagrams/?infinity
  
Generative Gestaltung
+
 
http://www.generative-gestaltung.de/code
+
== 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
 +
#* https://mrob.com/pub/comp/xmorphia/ogl/index.html
 +
#* http://pmneila.github.io/jsexp/grayscott/
 +
#* https://github.com/MStrandh/gray_scott_reaction_diffusion
 +
# Turing pattern
 +
 
  
 
[[Category:授業]]
 
[[Category:授業]]

2024年4月27日 (土) 07:10時点における最新版

目次

[編集] 概要

前提スキル
  • 一年生の時にメディアプログラミング演習Iを履修し、基本的なProcessingのプログラミングができること。
  • 個人のPC(Windows、MacOSのどちらでもよい)に自分でProcessingの環境を構築できることが望ましい。
授業概要
  • インタラクティブアートは芸術を基盤として科学や工学を統合する新しい領域で、プログラミングなどのIT技術によって実現されます。プログラミングによって制作プロセスをアルゴリズム化した作品は、拡張性が高く(スケーラブル)、多様性を持たせることが容易です。これが、スケーラブルアートです。
  • この授業では、その中でも、生物に見られる生成的(ジェネラティブ)な特徴をアートに応用したジェネラティブアートに関連する分野を扱います。その中には、人工生命、フラクタル、オートマトン、遺伝的アルゴリズム、ニューラルネットワークなどといったものが含まれます。
  • プログラミングを使用して、スケーラブルな特徴を持つ作品を作成します。
使用ソフト
到達目標
  • スケーラブルアートについて理解し、応用例を作成できる。
  • 生物の特徴と生物的なシステムについて理解する。
  • Processingを使ってジェネラティブアートのプログラミングができる。
成績評価
  • 確認テスト、課題、まとめテストで、100点満点で評価します。
参考資料

[編集] 開発環境

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

[編集] 生物と情報とアート

自然界の興味深いパターン
  • 自己相似性、フラクタル
    • 雪の結晶(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

[編集] 位置・速度・加速度

「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行に並べて結合する。

000004
001005
002006
003007
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();
}


[編集] 配列のシャッフル

int[] nN = {0,1,2,3,4,5,6}; 

for(int i=(nN.length - 1); i>0; --i) {
  int j = (int)random(i+1);
  int tmp = nN[i];
  nN[i] = nN[j];
  nN[j] = tmp;
}


[編集] クラスオブジェクトのソート

バブルソート

rectsをメンバlevelの値の小さい順にソートする。

Kurasu[] rects = new kurasu[100];

for(int j=0; j < rects.length - 1; j++){
  for(int i=0; i < rects.length - 1; i++){
    if(rects[i].level > rects[i+1].level){
      Kurasu tmp = rects[i+1];
      rects[i+1] = rects[i];
      rects[i] = tmp;
    }
  }
}

class Kurasu{
  int index;
  int level;
}


[編集] 3D回転

X軸を中心にフェルマーらせんを回転

int itr = 0;  //描画の繰り返し回数
float scalar = 5; //拡大倍率
float rotation;
float r =0;
void setup() {
  size(500, 500, P3D); // 3D座標を指定する
  background(255);  //背景を白くする
  rotation = (1 + sqrt(5)) / 2;
}
void draw() {
  translate(width / 2, height / 2);  //描画ウィンドウの中心に移動
  rotateX(r);
  fill(0);  //点を黒く塗る

  float theta = 2 * PI * itr * rotation; //回転角
  PVector v = PVector.fromAngle(theta);
  v.mult(scalar * sqrt(itr));
  ellipse(v.x, v.y, scalar, scalar); //点を描画
   
  itr++;
  r = r + 0.01;
}
Y軸を中心にフェルマーらせんを回転

int itr = 0;  //描画の繰り返し回数
float scalar = 5; //拡大倍率
float rotation;
float r =0;
void setup() {
  size(500, 500, P3D); // 3D座標を指定する
  background(255);  //背景を白くする
  rotation = (1 + sqrt(5)) / 2;
}
void draw() {
  translate(width / 2, height / 2);  //描画ウィンドウの中心に移動
  rotateY(r);
  fill(0);  //点を黒く塗る

  float theta = 2 * PI * itr * rotation; //回転角
  PVector v = PVector.fromAngle(theta);
  v.mult(scalar * sqrt(itr));
  ellipse(v.x, v.y, scalar, scalar); //点を描画
   
  itr++;
  r = r + 0.01;
}

[編集] 文字列を画面中央に表示

ウィンドウ画面の中央にテキストを配置する方法

文字の表示について、CENTERやwidth/2を使って、横方法は中央に配置することができます。 しかし、縦方向については、英語のアルファベットの場合、文字によって、高さや縦の位置が異なるので、 CENTERやheight/2では、うまくいきません。

フォントはベースラインを基準に作成されています。ベースラインから上の長さはAscent、ベースラインから下の長さはDescentと言います。 例えば、小文字のj,p などはベースラインから下にはみ出ていますし、小文字のk,lなどは縦に長く、iは短めです。 テキストの高さは、Ascent+Descentになります。

ref: https://github.com/alexheretic/ab-glyph/issues/6

これを計算して、縦の位置を指定する必要があります。 例えば、以下のようにすると、ウィンドウの中央に配置できます。

void setup() {
  size(400, 400);
  textSize(30);
  textAlign(CENTER,TOP);
  background(0);
}
void draw(){
  float ascent = textAscent();
  float descent = textDescent();
  float textHeight = ascent + descent;
  int textPosY = int(height-textHeight)/2;
  text("pijlk,hello world", width/2, textPosY);
}

[編集] プログラム出力を動画にエクスポート

Processingで実行したプログラムの出力を動画にするには、 一旦、saveFrame()関数で、コマ送りの静止画を保存して その後、MovieMakerで静止画をつなげて動画にします。

基本的には、draw()関数の最後にsaveFrame()関数を記述してプログラムを実行した後に、 Processingのツールメニューから、ムービーメーカーを使って、書き出せばよいです。 その際、コマ送りの静止画の数が多くなりすぎないように、frameRateを適度に設定するとよいでしょう。 なお、frameRateのデフォルトは60です。

void setup(){
  size(500,500);
  frameRate(30);
}
int x = 0;
void draw(){
  if (x < 100) {
    line(x, 0, x, 100);
    x = x + 1;
  } else {
    noLoop();
  }
  // Saves each frame as line000001.png, line000002.png, etc.
  saveFrame("line######.png");
}

[編集] リンク

http://gushwell.ifdef.jp/

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


[編集] 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
個人用ツール
名前空間

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