様々な関数の使い方をおさらいし、作例コードを書くことで、自分の知識の定着を図っています。
今回は、sin() 関数やサンプルコードの解説を行うことで、その使い方を学びます。誤りや、勘違いがあるかもしれません。何かあれば、ご指摘をいただけると嬉しいです。
p5.js は、バージョン 1.10.0 を使用しています。
sin() 関数の説明と使い方
こちらの p5js.org の公式リファレンスの 24/08/22 時点の内容を基に解説します。
sin() | p5.js 公式リファレンス
説明
sin() はクリエイティブ・コーディングで幾何的な処理を行う際に便利な関数です。
角度の正弦(サイン)を返し、その値は角度の増加に伴って -1 から 1 の間で振動します。つまり、 -1 から 1 の範囲をはみ出すことはありません。
角度の単位は angleMode() の指定によって "ラジアン angleMode(RADIANS)" や "度 angleMode(DEGREES)" になります。
デフォルトはラジアンです。
※参考
angleMode() | p5.js 公式リファレンス
書き方
sin(角度)
パラメータ
角度:単位がラジアンの場合、円の一周は 0 から 2pi です。度の場合は 0 から 360 になります。
1/2pi、pi、2pi はよく使うので、それぞれを表す HALF_PI、 PI、 TWO_PI という定数が用意されています。
1/4pi である QUARTER_PI という定数もありますが、これは綴りが長いし、個人的には使ったことはありません。
返り値
角度により -1 から 1 の範囲の値が返ります。
p5.js 公式リファレンスのコード例の補足
白いボールがゆ~らゆら
function setup() {
createCanvas(100, 100);
describe('A white ball on a string oscillates up and down.');
}
function draw() {
background(200);
// Calculate the coordinates.
let x = 50;
let y = 30 * sin(frameCount * 0.05) + 50;
// Draw the oscillator.
line(50, y, x, y);
circle(x, y, 20);
}
-1 から 1 までの範囲で振動する sin() の性質を使って、ボールを上下に振動させています。
コードの下記部分で、 30 は上下の変化幅、50 は上下動の中心をキャンバスの上下中央に持ってくるためです。
let y = 30 * sin(frameCount * 0.05) + 50;
角度はラジアン扱いで、円の 1周分は 2pi = 約 2 * 3.14 = 約 6.28 です。コード上の frameCount * 0.05 だと 126 フレーム目には sin(6.3) になって 2pi を超えてしまいます。
2pi 超えてしまうとエラーになるかというと、そんなことはなく単に 1周分を超えて円の 2周目に入るだけです。
sin() と関係ないところで恐縮ですが、キャンバスの中心を表すために let x = 50; とかしてるところは個人的にはちょっとムズムズします。
ここはこうしたい。
// Calculate the coordinates.
// let x = 50;
let x = width * 0.5;
// let y = 30 * sin(frameCount * 0.05) + 50;
let y = height * (0.3 * sin(frameCount * 0.05) + 0.5);
あと、 line(50, y, x, y); が何をしたかったのかよくわかりません。
こうじゃないのかな?
// Draw the oscillator.
line(x, 50, x, y);
これもこうしておきたい。
// Draw the oscillator.
// line(x, 50, x, y);
line(x, height * 0.5, x, y);
点描でサインカーブ
function setup() {
createCanvas(100, 100);
background(200);
describe('A series of black dots form a wave pattern.');
}
function draw() {
// Calculate the coordinates.
let x = frameCount;
let y = 30 * sin(x * 0.1) + 50;
// Draw the point.
point(x, y);
}
1フレーム毎に x 軸を移動しながら、y 軸の値を下記の式で計算し、そこに点を打つ。結果、サインカーブが描かれます。
let y = 30 * sin(x * 0.1) + 50;
式中の 30 が波形の振幅、0.1 が周波数的なものに相当します。これらの値をいろいろ変えてみると感覚がつかめると思います。
例えば sin(x * TWO_PI * 0.01) とすると、ちょうど円 1周分のカーブが見られるでしょう。
こうしても面白いですね。
let y = x * 0.3 * sin(x * 0.1) + 50;
これも 50 に同様のムズムズを感じますが省略します。
無限大印というか、リサージュ図形というか
function setup() {
createCanvas(100, 100);
background(200);
describe('A series of black dots form an infinity symbol.');
}
function draw() {
// Calculate the coordinates.
let x = 30 * cos(frameCount * 0.1) + 50;
let y = 10 * sin(frameCount * 0.2) + 50;
// Draw the point.
point(x, y);
}
x軸の計算にも三角関数を使って面白い図形を描こうという試みです。
x軸, y軸どちらも範囲内を周期的に振動するので、図形がどっか行っちゃうことなくキャンバス内に収まるわけです。
改造例
// Calculate the coordinates.
let x = 30 * cos(frameCount * 0.1) + 50;
let y = 10 * sin(frameCount * 0.3) + 50;
// Calculate the coordinates.
let x = 30 * cos(frameCount * 0.3) + 50;
let y = 30 * sin(frameCount * 0.2) + 50;
// Calculate the coordinates.
let x = 30 * cos(frameCount * 0.1) + 50;
let y = 30 * sin(frameCount * 0.1) + 50;
三角関数は使い勝手がよくて楽しい関数
今回解説した sin() を含む三角関数は使い勝手がよく、クリエイティブ・コーディングの様々な場面で活躍してくれる関数です。
この記事が参考になって、sin() を使った楽しいコーディングをしていただけたら嬉しいです。