p5.jsの続きです。前回までは「Generative Design with p5.js」の「P.1. 色」編を見ていましたが、他の機能も知りたくなってきたので「P.2. 形」「P.3. 文字」「P.4. 画像」*1も並行しようと思います*2。今回は「P.2. 形」の「01」を見ていきます*3。それではいきましょう!
【目次】
※参考:【p5.js】Generative Design with p5.js「色 P_1_0_03」のコードを読み解く - クモのようにコツコツと
※p5.jsを習得するためにやったことまとめ
qiita.com
完成品
書籍「Generative Design with p5.js」より
Generative Design with p5.js - [p5.js版ジェネラティブデザイン] ―ウェブでのクリエイティブ・コーディング
- 作者:Benedikt Gross,Hartmut Bohnacker,Julia Laub
- 発売日: 2018/06/22
- メディア: 単行本
ソースコード一覧
※参考:Generative Design with p5.js[p5.js版ジェネラティブデザイン] ―ウェブでのクリエイティブ・コーディング
「P_2_0_01」のソースコード
※参考:p5.js Web Editor
中心の円がある。円に見えているが実際には線の集合体。マウスの左右の動きで円のサイズが変わり、上下の動きで線の太さと本数が変わる。
JSコード
// P_2_0_01 // // Generative Gestaltung – Creative Coding im Web // ISBN: 978-3-87439-902-9, First Edition, Hermann Schmidt, Mainz, 2018 // Benedikt Groß, Hartmut Bohnacker, Julia Laub, Claudius Lazzeroni // with contributions by Joey Lee and Niels Poldervaart // Copyright 2018 // // http://www.generative-gestaltung.de // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /** * drawing a filled circle with lines. * * MOUSE * position x : length * position y : thickness and number of lines * * KEYS * s : save png */ 'use strict'; function setup() { createCanvas(550, 550); strokeCap(SQUARE); } function draw() { background(255); translate(width / 2, height / 2); var circleResolution = int(map(mouseY, 0, height, 2, 80)); var radius = mouseX - width / 2; var angle = TAU / circleResolution; strokeWeight(mouseY / 20); for (var i = 0; i <= circleResolution; i++) { var x = cos(angle * i) * radius; var y = sin(angle * i) * radius; line(0, 0, x, y); } } function keyPressed() { if (key == 's' || key == 'S') saveCanvas(gd.timestamp(), 'png'); }
前半のコメント部分はクレジット。
その次の概要部分の訳。
塗りつぶされた円を線で描画します。
マウス
位置x:長さ
位置y:太さと線の数 キー
s:pngを保存
全体構成
まずは大枠から見ていく。
function setup() { // ページ読み込み時の処理 } function draw() { // 一定時間ごとに繰り返し実行 } function keyPressed() { // キーを押した時に実行 }
setup()
メソッドはページ読み込み時の処理draw()
メソッドは一定時間ごとに繰り返し実行keyPressed()
メソッドはキーを押した時に実行
大枠は前回までと変わらない。
※参考:【p5.js】Generative Design with p5.js「色 P_1_0_03」のコードを読み解く - クモのようにコツコツと
setup()の中身
setup()
メソッドはページ読み込み時の処理。
function setup() { createCanvas(550, 550); strokeCap(SQUARE); }
createCanvas()
メソッドの第一引数、第二引数共に550
strokeCap()
メソッドの引数をSQUARE
に
createCanvas()
メソッドで幅550px、高さ550pxのキャンバスを作成する。
strokeCap()
メソッドは線の先端の形状を設定するようだ。初期値はROUND
で角丸だがSQUARE
だと四角になる。
Sets the style for rendering line endings. These ends are either squared, extended, or rounded, each of which specified with the corresponding parameters: SQUARE, PROJECT, and ROUND. The default cap is ROUND.
行末をレンダリングするためのスタイルを設定します。 これらの端は、2乗、拡張、または丸められており、それぞれが対応するパラメータSQUARE、PROJECT、およびROUNDで指定されています。 デフォルトの上限はROUNDです。
setup()
メソッドキャンバスと線の先端の形状を設定している。
draw()の中身
次、draw()
メソッドは一定時間ごとに繰り返し実行。
function draw() { // 一定時間ごとに繰り返し実行 }
中の処理はボリュームがあるので順番に見ていく。
背景色(background())と移動量(translate())の設定
background(255); translate(width / 2, height / 2);
background()
メソッドの引数は255translate()
メソッドの第一引数はキャンバス幅の半分、第二引数はキャンバス高さの半分(キャンバス中心)
背景色は引数一つだと全て同じ値になり、初期値はRGBなので255は真っ黒。
translate()
メソッドは移動量の設定
Specifies an amount to displace objects within the display window. The x parameter specifies left/right translation, the y parameter specifies up/down translation.
表示ウィンドウ内のオブジェクトを移動する量を指定します。 xパラメータは左/右への移動を指定し、yパラメータは上/下への移動を指定します。
引数は下記の意味になる
translate(x, y, [z])
引数は横、縦の順で、そこにキャンバス幅の半分、キャンバス高さの半分が入るのでキャンバスの中心になる。
マウスの縦位置を「2〜80」の範囲に関連付ける
var circleResolution = int(map(mouseY, 0, height, 2, 80));
- 変数
circleResolution
の値はint()
メソッド
int()
メソッドの引数はmap()
メソッド
map()
メソッドの引数は左からマウス縦位置、0、キャンバス高さ、2、80
変数名のcircleResolution
は「サークル解像度」と訳されるが、数学でのResolution
は「分解 (ホモロジー代数)」という意味になるようだ。
数学のホモロジー代数において,分解(ぶんかい,英: resolution)(あるいは左分解 (left resolution); 双対の余分解 (coresolution) あるいは右分解 (right resolution)[1])は加群(あるいはより一般に,アーベル圏の対象)の完全列であり,加群あるいはこの圏の対象の構造を特徴づける不変量を定義するために用いられる.
うーむ、読んでもよくわからない。。
int()
メソッドは少数を切り捨てて整数にするようだ。
Converts a boolean, string, or float to its integer representation. When an array of values is passed in, then an int array of the same length is returned.
ブール値、文字列、または浮動小数点数をその整数表現に変換します。 値の配列が渡されると、同じ長さのint配列が返されます。
なお、「ブール値」は真偽値(true
、false
)のこと。int()
はtrue
を1、false
を0に変換する。
※参考:https://wa3.i-3-i.info/word16183.html
map()
は以前こちらの記事でも使ったが、ある範囲とある範囲を関連付けるメソッド。
※参考:【p5.js】クリエイティブコーディングに挑戦(その2) - クモのようにコツコツと
map()
の引数は下記の意味になる。
map(value, start1, stop1, start2, stop2, [withinBounds])
value Number: the incoming value to be converted
start1 Number: lower bound of the value's current range
stop1 Number: upper bound of the value's current range
start2 Number: lower bound of the value's target range
stop2 Number: upper bound of the value's target range
withinBounds Boolean: constrain the value to the newly mapped range (Optional)
value数値:変換される入力値 start1数値:値の現在の範囲の下限 stop1数値:値の現在の範囲の上限 start2数値:値のターゲット範囲の下限 stop2数値:値のターゲット範囲の上限 withinBoundsブール値:値を新しくマップされた範囲に制限します(オプション)
そうするとmap(mouseY, 0, height, 2, 80)
は下記ということになる。
- マウスの縦位置が入力値
- 値の現在の範囲は0からキャンバス高さ
- 値のターゲット範囲の下限は2、上限は80
マウスの縦位置の0〜キャンバス縦位置までの数字が2〜80までの数値に変換される。
半径の設定
次、変数radius
の設定。
var radius = mouseX - width / 2;
- 変数
radius
の値はマウス横位置引くキャンバス幅の半分(キャンバス横中心)
変数のradius
は半径という意味。
※参考:【p5.js】Generative Design with p5.js「色 P_1_0_03」のコードを読み解く - クモのようにコツコツと
マウスの横位置からキャンバスの半分を引くということは、キャンバスの横中心からマウスの横位置までの距離が半径になる。
角度の設定
次は変数angle
、角度の設定か。
var angle = TAU / circleResolution;
- 変数
angle
の値はTAU
割るcircleResolution
また見慣れないプロパティ が…TAU
ってなんぞ? タウ?
TAU is an alias for TWO_PI, a mathematical constant with the value 6.28318530717958647693. It is twice the ratio of the circumference of a circle to its diameter. It is useful in combination with the trigonometric functions sin() and cos().
TAUは、値6.28318530717958647693の数学定数TWO_PIのエイリアスです。 これは、円の円周と直径の比の2倍です。 三角関数sin()およびcos()と組み合わせると便利です。
これまたすごい桁数の値だなー。TWO_PI? 円の円周と直径の比の2倍?
τ(タウ)は、一部の研究者により、現在の円周率 π に代わるべき数学定数として提唱されている数であり、円の半径に対する周長の比として定義される定数である。その値は 2π に等しい。
あー、2πか!円周率の2倍で約6.28ってことか。
でもって前回も出てきた「ラジアン(弧度法)」の「2π」は角度でいうと「360°」になる。
この2πをcircleResolution
(2〜80)の数字で割った数字をangle
(角度)にすると。マウスの上下で変わる線の本数に関係していそう。
strokeWeight()メソッドで線の太さを変更
次はstrokeWeight()
メソッドを実行。
strokeWeight(mouseY / 20);
strokeWeight()
メソッドを実行。引数はマウス縦位置割る20
strokeWeight()
メソッドは文字通り線の太さを変えるメソッド。
Sets the width of the stroke used for lines, points, and the border around shapes. All widths are set in units of pixels.
線、点、および図形の周囲の境界線に使用されるストロークの幅を設定します。 すべての幅はピクセル単位で設定されます。
マウスの縦位置を20で割った数字で、左上基準の数値のため、マウスが下に行くほど線が太くなる。
for文でline()メソッド線の描画をループ
最後にfor文がある。
for (var i = 0; i <= circleResolution; i++) { var x = cos(angle * i) * radius; var y = sin(angle * i) * radius; line(0, 0, x, y); }
- 変数
i
は0から開始、circleResolution
の回数繰り返す、1ずつ加算 - 変数
x
:cos()
の引数はangle
にi
を掛ける。さらに半径radius
を掛ける。 - 変数
y
:sin()
の引数はangle
にi
を掛ける。さらに半径radius
を掛ける。 line()
メソッドを実行。引数は左から0、0、x
、y
for文はcircleResolution
の2〜80の回数繰り返す。
変数x
と変数y
に出てくるコサイン、サインは三角関数か!
cos()
、sin()
の引数、angle
はラジアンの2π=360°をcircleResolution
で割った数。そこに回数i
を掛ける(最大はcircleResolution
なので360になる)
そしてコサイン、サイン半径を掛けると前回の三角関数「角度から座標(位置)を割り出す」の公式になる!
- 半径の長さrとコサインを掛けるとX(横)位置
- 半径の長さrとサインを掛けるとY(縦)位置
※参考:【p5.js】Generative Design with p5.js「色 P_1_0_03」のコードを読み解く - クモのようにコツコツと
そこから割り出されたx
、y
はその下のline()
メソッドの引数に使われる。
line()
メソッドは線の描画のメソッドで引数は下記の意味になる。
line(x1, y1, x2, y2)
引数は左から点1の横、縦、点2の横、縦。
そうすると
line(0, 0, x, y);
点1は縦、横ともに0、点2がx
、y
になる。
これがfor文でcircleResolution
の回数分angle
の角度で繰り返される。
keyPressed()の中身
keyPressed()
メソッドはキーを押した時に実行。
function keyPressed() { if (key == 's' || key == 'S') saveCanvas(gd.timestamp(), 'png'); }
- もし
s
やS
が押されたらキャンバスをpng
の画像で保存する。
これはいつもと同じ保存設定。
最後に
ということで今回は「形」編の最初のコードを読み解きました。今回もサイン、コサイン(三角関数)やTAU(2π)などの数学用語が当たり前のように出てきて、やはりインタラクション系の制作には数学知識はあったほうがいいんだなと感じられました。自分自身、数学のやり直しにもなるので、とても勉強になります。
次回は「文字」編のコードを見ていきたく思います。それではまた!
※p5.jsを習得するためにやったことまとめ
qiita.com