[Go to “teaching” in Morimoto Lab]

Drawing & Pattern 3

式を使って模様を描く。
GUIを使って制御する。
黄金比を使ってひまわりを描く。
その他。


1. 色々な式と図形

1..1 リサジュー図形

リサジュー図形の式 from wikipedia

以下の楕円の式と比べてみよう

どちらも極座標系で考える。
以下は点で円を描くプログラム。

Alt text

float halfWidth;//画面の横幅の半分
float halfHeight;//画面の縦幅の半分
void setup() {
size(500, 500);
halfWidth = width / 2;
halfHeight = height / 2;
smooth();
strokeWeight(2);
}
void draw() {
colorMode(RGB, 255);
background(255);
Lissajous();
}
void Lissajous() {
float A = 200; // 横の大きさ
float B = 200; // 縦の大きさ
colorMode(HSB, 1f);//RGBではなくHSB指定に変更。二つ目の引数はmax値を示す
stroke(0, 1, 1, 0.2f);
//fill(0, 1, 1, 0.2f);//中身を塗りつぶしてもよい
for (float t=0; t<TWO_PI; t+=0.03f)
{
//一点ずつ色を変えるなら
stroke(t/7, 1, 1, 0.5f);
// xとyを計算する
float x = A * cos(t);
float y = B * sin(t);
// 図形を画面の中央に移動する
x += halfWidth;
y += halfHeight;
// 得られたxとyの位置に円を描く
ellipse(x, y, 20, 20);
}
}

Ex A:リサジュー図の描画プログラムを作成し、更にアニメーションさせてみよう。

まず、上記のプログラムの式をリサジューに変更してみよう
次に、以下のようにアニメーションを加えてください
(途中でアニメーションが不連続になっていますがレコーディングの途切れ目で、実際は連続した動きになっています)。

Alt text

Hint:
アニメーション用のtをグローバル変数として用意し、draw()内でt+=0.03などとし、すでに描画されているリサジューと別に点の位置を計算してください。

Hint:
PITWO_PIなどがProcessingでは用意されている。
ちょうど一週するのに円の場合だとtはの範囲で増加し、また0に戻すとよい。

Hint:
メニューのスケッチ>Tweak を選ぶと、プログラムを実行中に、プログラム内の変数の値を変更できます。試してみましょう。

おまけ:可視化を工夫する

こちらは余力のある人はチャレンジしてみてもよいです。

  1. 点を線に変更する

    • 線で描画する方法は一つではないですが、vertex()などを使うとよいかもしれません。

Alt text

  1. 全ての点と点の間に線を描画する

    • 一度作った点列を配列などに保存しておく必要がある

    • 2重for文

    • drawで繰り返し描くと処理が重いかもしれない。noLoop()等もある

Alt text Alt text

  1. 他にどのような変更をしたら面白いか、下記参考URLよりコードをダウンロードして確認し、取り入れてみよう。

参考URL:
http://www.bnn.co.jp/support/generativedesign/code/M_2_5_02_TOOL.html
Generative Designの本では、このような↑コードが提供されています。
点ではなく、線で描画し、かつ、全ての点と点を線で結んでいるようです。
また、3次元のようです。
また、点の総数を与えて、きっちり一回り分だけ描画するようにしてあります。


以下、1.2~1.5は類似の図形の紹介などです。
Ex課題はないので、気になるところだけ実装してみるとよいでしょう。


1.2 バラ曲線

enter image description here

1.1の冒頭でも紹介しましたが、
円の極座標の式、

ここで、は半径、は角度である。

この半径を滑らかに変えれば(例えばsinやcosで)、原点中心に面白い模様(お花のような)ができそうである。
というわけで発想はシンプルでわかりやすいですね!

バラ曲線では、

または

とする。
は原点と最も離れた点の距離となる。
wikipediaを見てみよう。


バラ曲線を実装し、パラメータを変えて様々な形を作りなさい。


1.3 超楕円

まず超楕円を実装しましょう。
超楕円は建築などでも利用されているようです。

式は以下です。

aは横軸の最大幅、bは縦軸の最大幅、pで楕円のふくらみを調整できます、へこませることもできます。
p=2のとき、普通の楕円になります。

しかし実装するなら、極座標系にしたいところ。
結局、以下のURLに超楕円からその一般系まですべて書いてありました。
https://en.wikipedia.org/wiki/Superellipse

実装し、pを表示すると以下のようになります。

Alt text

Alt text

Alt text

Alt text

上記のURLを参考に、超楕円の描画を実装し、パラメータを変えて、挙動を確かめてみましょう。

真ん中あたりに極座標形式の超楕円の式の解説があります。
更に進むと、一般化形式であるsuperformulaの式があります(generalizationのところ)。


1.4 Superformula

https://en.wikipedia.org/wiki/Superformula

enter image description here

上記のURLを参考に、superformulaの描画を実装し、パラメータを変えて、挙動を確かめなさい。


1.5. その他

●しずく曲線やアステロイド曲線など→[まとめページ]
●糸掛け数学or曼荼羅→[検索結果]

enter image description here

プログラムではわざわざ糸を掛けずに、しかもアニメーションでも作れるので面白そうです。
ストリングアートというものもあるみたいです。
今日の最後の課題の参考にどうぞ。


2. ControlP5でGUIをつけよう

GUIとはGraphical User Interfaceのことで、平たく言うとソフトウェア上の
ボタン、スライダー、
などのことです。
ProcessingではControlP5を使うとかなり豊富なGUIを使うことができます(以下は例)。

enter image description here

これはProcessingは他の言語等よりかなり簡単に使えて便利ですので、汎用的な内容を学ぶという感じではないかもしれませんが、他の言語でもProcessingほどではないにしてもこのようなGUIを使えることも多いです。

2.1 ControlP5の導入

1.まずはライブラリをインストールします(初回のみ)。
スケッチ>
ライブラリをインポート>
ライブラリを追加>
Librariesタブ>
controlP5を検索してInstallボタンを押す

2.次にライブラリをインポートします(毎回)。 スケッチ> ライブラリをインポート> controlP5を選択

2.2 サンプルを見よう

ファイル>サンプル>Contributed Libraries > ControlP5 > controllers
から
ControlP5sliderとControlP5button
を見て行きます。
※他にもたくさんGUIがありますが、他のものは個人で見てみてください

ボタンのサンプル解説

ボタンのサンプルは公式のものを少しシンプル化した以下のプログラムを使います。
皆さんは下記からコピーするなどしてみてください。
上のボタンを押すと緑、下のボタンを押すと赤になります。

Alt textAlt textAlt text

import controlP5.*;//controlP5のインポート
ControlP5 cp5;//ControlP5変数を定義
int myColor = color(255);//色の変数
void setup() {
size(400,250);
noStroke();
cp5 = new ControlP5(this);//とりあえずcp5をnewしましょう。
// 上のボタンを加えます。ボタンの名前はCOLORAになり、
// 後で定義するcolorA関数がこのボタンのイベント発生時(押したときなど)に処理されます。
cp5.addButton("colorA")
.setPosition(100,100)//位置の指定
.setSize(200,19)//サイズの指定
;
// 下のボタンを加えます
cp5.addButton("colorB")
.setPosition(100,120)
.setSize(200,19)
;
}
void draw() {
background(myColor);//背景色を以下の関数で変更するmyColorにします。初期は白。
}
// 以下の関数はcolorAというボタンにイベントが発生したら呼ばれます
public void colorA() {
println("a button event from colorA: ");
myColor = color(0,160,100);
}
// 以下の関数はcolorBというボタンにイベントが発生したら呼ばれます
public void colorB() {
println("a button event from colorB: ");
myColor = color(150,0,0);
}

スライダーのサンプル解説

Alt text
まずは実行画面↑
4つの領域に分かれて、それぞれのスライダーで、その背景色が決まります。
※わかりやすいように塗りつぶしの横幅を違うものに変更したので、少し違う実行結果になります。

import controlP5.*;//controlP5のインポート
ControlP5 cp5;//ControlP5変数を定義
int myColor = color(0,0,0);//これは上から2番目の背景色指定に使われます
int sliderValue = 100;//一番上の背景色
int sliderTicks1 = 100;
int sliderTicks2 = 30;
void setup() {
size(700,400);
noStroke();
cp5 = new ControlP5(this);
// 1個目のスライダー(水平方向)を加えます
// このスライダーの値はsliderValueにリンクされます。
// スライダーの名前はSLIDERVALUEとしてスライダーの周囲に自動配置されます。
cp5.addSlider("sliderValue")
.setPosition(100,50)//スライダーの左上の位置を指定
.setRange(0,255)//スライダーの範囲を指定
;
// 2個目のスライダー(垂直方向)をメモリ付きで加えます。
// ここにはsetValueによる値の指定がないので、
// 初期値はsliderTick2と同じになります。
// このスライダーは垂直方向になります。
// 縦横の長い方に動くように自動化されています。
cp5.addSlider("sliderTicks1")
.setPosition(100,140)
.setSize(20,100)//スライダーのサイズを指定
.setRange(0,255)
.setNumberOfTickMarks(5)//メモリの数を指定
;
// 3個目のスライダーの追加
cp5.addSlider("slider")
.setPosition(100,305)
.setSize(200,20)
.setRange(0,200)
.setValue(128)//値が一つなら0からその値までの範囲で設定
;
// 直前に追加した'slider'のラベルの位置を調整しています。
// 以下それぞれ左右のラベルの位置の調整。値はそれぞれ端からの間隔。
cp5.getController("slider").getValueLabel().align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
cp5.getController("slider").getCaptionLabel().align(ControlP5.RIGHT, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
// 4個目のスライダー
cp5.addSlider("sliderTicks2")
.setPosition(100,370)
.setWidth(400)//横幅だけ指定もできます
.setRange(255,0) // setRangeは小→大だけでなく、大→小のスライダーも設定できます
.setValue(128)
.setNumberOfTickMarks(7)
.setSliderMode(Slider.FLEXIBLE)//スライダーに▲を表示します。デフォルトでは.FIXで表示無です。
;
}
void draw() {
fill(sliderValue);//1つ目のスライダーでその背景を塗りつぶす。
rect(0,0,width-10,100);
fill(sliderTicks1);//2つ目のスライダーその背景を塗りつぶす
rect(0,100,width-20,180);
fill(myColor);//3つ目
rect(0,280,width-30,70);
fill(sliderTicks2);//4つ目
rect(0,350,width-40,50);
}
//3つ目のスライダーはスライダーに何かイベントが起こった時に以下の関数が呼ばれるようになっています。
//引数にはスライダーの値が入っています。
//単純にaddSliderでintの値と結びつけることもできれば、関数を実行することもできるということです
//とりあえずは関数を使わない簡単な方法だけ使って問題ないと思います
void slider(float theColor) {
myColor = color(theColor);
println("a slider event. setting background to "+theColor);
}

Ex B:リサジュー図の描画プログラムにスライダーを加えて、アニメーションを制御しましょう。

Ex. Aを変更して、スライダーの位置でアニメーションする大きな丸の位置が変わるようにしてください。


3. 黄金比とフィボナッチ数列

黄金比とフィボナッチ数列は関係あると言われています。
ここでは、黄金比を使って描いた図形にフィボナッチが現れる例として、ひまわりの種の並びを再現したいと思います。

https://github.com/nmillward/processing_sketches

Alt text

上記のURLからballsのプログラムを参考にします。
ただし、上記のプログラムには後日講義で扱うclassや動的配列が出てくるので、それらを使わないバージョン&装飾を簡素化したサンプルコードを以下に記載します。

※注意
年によってはclassや動的配列を先に学んでいます。
その場合でも、課題と関係するので、以下のプログラムを使って(クラスを使わないままで)進めてください。
上記のリンク先のballsは課題を解くためにぜひ参考にしてください。
また、課題を解いた後、クラス化にもチャレンジしてみて、その一つの模範解答としてください。
ただ、この模範解答、やや初学者を迷わせる要素があるので、迷わない自信のある人にはお勧めと言う感じです。
というのも、実はこのリンク先のプログラムでは、講義中にNGとしている自身のクラス配列(グローバル変数)をクラス内で使っている部分があるのです。。
ここら辺はテキストには解説は載せませんが、気になる人は先生に聞いてみましょう!

Alt text

int count = 0;
int ballnum = 1000;//ballは1000個に限定
PVector cen;
float siz;
//極座標で点の位置を決める
float dist[];//中心からの距離
float ang[];//中心からの角度
void setup() {
size(800, 800);
cen = new PVector();
cen.x = width/2;
cen.y = height/2;
siz = 4;//ball size
dist = new float[ballnum];
ang = new float[ballnum];
noStroke();
fill(255);
}
void draw() {
background(50);
//ボールを一個ずつ配置していくので、
//count番目のボールを中央付近に配置するところから始まる
//配置位置を決める角度と距離
float angle = 10;
//float angle = 137.5;//黄金比に関連のある角度
//配置当初の距離と角度(角度はこの後も不変)
dist[count]=50;
ang[count]=angle*count;
//count番目以下のボールは既に配置されているので、
//それらの位置の更新もしてあげます
for (int i=0; i < count; i++)
{
//単純に円の極座標で、距離を少しずつ大きくしてます。
//角度は変わっていません。
float x = dist[i] * cos(radians(ang[i]));
float y = dist[i] * sin(radians(ang[i]));
ellipse(x+cen.x, y+cen.y, siz, siz);
dist[i] += 0.4f;//これでちょっとずつ外側に移動する
}
//次のdraw()の処理でcount+1番目のボールを配置するため
//countを一つ足す。
count++;
//ボールは1000個しかないので、0~999番目までしかない。
//countが1000になったら、0に戻してエラーを回避します。
if (count>=ballnum)count=0;
}

上記プログラムの解説です。
(詳細はプログラム中に記載しています。)

で、どこがフィボナッチ数列かというと、
右回りや左回りに螺旋がありますが、これらのそれぞれの螺旋の数がフォボナッチ数になってるらしいです。

enter image description hereenter image description here

[参考URL ]


Ex C. 上記のプログラムの点の配置角度を黄金比に関係するものに変えた上で、点の色/大きさを個別に変更して、アニメーションを装飾してください。

例えば以下のような感じのイメージです。
この例では一つ一つのサイズや色は一度決まったら変更されていません。

Alt text

Hint:
距離や角度などのように、色や大きさの配列を作り、一つ一つ個別に指定しましょう。

ちなみに参考元のプログラムのballsというプログラムを実行すると以下のような動画が作成されます。
こちらの方では色やサイズの与え方が少し複雑です。
興味のある人は元のプログラムを見るなどしてみてください。

enter image description here


Note: アレキメデス螺旋
ちなみに、上記プログラムの点と点の間隔を狭めると螺旋になりますが、
今回のような半径が一定の倍数になっている螺旋をアレキメデス螺旋といいます。
で表されます(半径, 定数, 角度)。



Ex D: 今回の内容をアレンジするなどして、オリジナルの模様やアニメーションを作成してください。

色や追加の装飾などもぜひ工夫してください。

参考:以下のような作品事例を先に見ておくとイメージが湧くかも。
deconbatchさんのTwitter:趣味でProcessingでジェネラティブアートを作っている人のようです。ウェブページもあって、コードの記載もあります。
enter image description here
daveさんのTwitter:上記と類似のTwitterです。
この他、Twitterの#dailycodingchallengeなどを見てみるといろんな人がプログラムを公開しています。