今回の記事の目的はProcessingの「lerp()関数」を理解し、自分なりに使ってみること。
【Processing】lerp()関数について
lerp()
は「線形補間」の略で、”linear interpolation” という意味がある- 線形補間は、二つの点の間を滑らかに移動する方法です。たとえば、A点が0で、B点が10だとします。0から10までの間を、一定の割合で進むと考える
- もし、A点から0%進んだときは、まだ0の位置にいます。50%進むと、ちょうど5の位置に来ます。そして100%進むと、10の位置に到達します。このように、A点からB点の間を、どのくらい進むかを割合で指定することを線形補間と言います。
- 簡単に言うと、線形補間は「始まりから終わりまでの間をなめらかに動く」方法です。イメージとしては、A地点とB地点の間をまっすぐな線で結んで、その線の上をゆっくり進んでいく感じ
lerp()
関数は、二つの値の間を一定の割合で補間する関数- 例えば、0から10の間を半分の値(5)を得るために使います(記事の先にコードあり)
- もしくは、スタートからゴールまでの間をなめらかに動く図形を描ける(記事の先にコードあり)
【Processing】lerp()関数の書き方【構文】
lerp(value1, value2, amt)
と書きます- value1とvalue2は始点と終点の値
- amtはその間の割合(0.0から1.0)を示す
amt
は “amount”(量)という英語の略- amtは0.0から1.0の間と決まっている
- 基本的にはfloatを使う
【Processing】lerp()関数の使い方3つ【画像とコード】
【1】lerp()でvalue1とvalue2の間を半分の値を得るための使い方
float start = 0;
float end = 10;
float percent = 0.5; // 50% つまり間の値
// lerp(value1, value2, amt)
float result = lerp(start, end, percent);
println(result); // 出力は5になります
start
値(0)から end
値(10)までの間の50%の位置を計算して50% の位置は 5 であることは何の役に立つのかというと、物体を滑らかに移動するアニメーションを作成するときに役に立ちます。
【2】lerp()関数で図形がスタートからゴールまで滑らかに動く使い方
// 円がゆっくり動くプログラム
float x = 0;
float targetX = 200;
void setup() {
size(400, 400);
}
void draw() {
background(255);
// 0.01から0.2くらいがtargetXまで滑らかに動きました
x = lerp(x, targetX, 0.05); // 円のx位置がターゲットに近づく
ellipse(x, height/2, 50, 50); // 中心に円を描く
}
lerp()
関数では、現在の位置から目標の位置に向かってどのくらいの割合で進むかを決めるのが amt
の部分。→構文:lerp(value1, value2, amt)
0.05
(5%)という数値を選ぶ理由は、動きを滑らかにするため。もし大きな数値(例えば1.0)を選ぶと、一気に移動してしまって滑らかに見えない。でも小さな数値を選ぶと、少しずつ確実に目標に近づいていくので、動きが自然でスムーズに見える。
なぜ0.05%は5%なのか。
パーセンテージを小数で表すときに、100で割ると出てくるから。つまり、5%は0.05、10%は0.1、50%は0.5というようになる。だから、lerp(x, targetX, 0.05) の 0.05 は、x から targetX への距離の5%という意味。
上記の考え方から1は100%になる。
以下のように書くと、いきなりゴールであるtagetXの200に円が表示されてしまう。
13行目のamtの部分を0.05から1に変更。
// 円がゆっくり動くプログラム
float x = 0;
float targetX = 200;
void setup() {
size(400, 400);
}
void draw() {
background(255);
// 0.01から0.2くらいがtargetXまで滑らかに動きました
x = lerp(x, targetX, 1); // 円のx位置がターゲットに近づく
ellipse(x, height/2, 50, 50); // 中心に円を描く
}
【3】lerp()関数を使って、車が急ブレーキをかけて止まる表現
float x = 0;
float targetX = 340;
void setup() {
size(400, 400);
}
void draw() {
background(255);
x = lerp(x, targetX, 0.05); // 車のx位置がターゲットに近づく
// 車のピクセルアートを描画
//自作関数
drawCar(x, height/2 - 25);
}
void drawCar(float x, float y) {
fill(0, 0, 255); // 車の色を青に設定
rect(x, y, 50, 25); // 車の本体を描く
fill(0); // タイヤの色を黒に設定
ellipse(x + 10, y + 25, 10, 10); // 前タイヤ
ellipse(x + 40, y + 25, 10, 10); // 後タイヤ
}
【Processing】lerp()関数でスタートは勢いよく動いて、ゴールに近づくと動きがゆっくりになる理由
lerp()
関数の性質によるものだよ。
lerp(x, targetX, 0.05)
(上の項目の車のコード)の 0.05
は、現在の位置 x
を目標の位置 targetX
に向かって5%ずつ近づけるという意味。
最初のうちは x
と targetX
の距離が大きいので、1回の移動量もそれなりに大きくなります。でも、x
が targetX
に近づくにつれて、移動する距離も次第に小さくなります。これは、距離が小さくなるにつれて5%も小さくなるからです。
イメージとしては、大きな一歩からスタートし、ゴールに近づくにつれて徐々に小さな一歩に変わっていく感じ。だから、targetX
に近づくと動きがゆっくりになる。
滑らかで自然な動きが生まれるわけ。
【Processing】lerp()関数の計算式
以下のコードをlerp()
関数の計算式に当てはめて理解を深めます。
float start = 0;
float end = 10;
float percent = 0.5; // 50% つまり間の値
// lerp(value1, value2, amt)
float result = lerp(start, end, percent);
println(result); // 出力は5になります
lerp()
関数の計算式
result=value1+(value2−value1)×amt
value1
から value2
までの間の amt
(割合)だけ進んだ位置を計算します。例えば、lerp(0, 10, 0.5)
の場合、計算は以下のようになります。
result=0+(10−0)×0.5=5
簡単に言うと、スタートとゴールの間が何パーセントかを求める計算になる。
【Processing】lerp()関数はどんな表現で使えそうか
この記事で書いた車が急ブレーキをかけて止まる表現のように「危なっかしさ、不安定さ、驚き、怖さ。」などの表現で、lerp()
関数を使えると思いました。
【Processing】lerp()関数を使ってみた感想
車の急ブレーキの表現をして「危ない」と思ってしまえるような表現ができたことに上達を感じました。
今まではどちらかと言うと「おお。こうなるんか。すごい。面白い」と思うことが多かったのですが、lerp()
関数で1つ進んだ感じ。
学んでいて「なぜ?」と思うことも多くなり、調べたり考えたりすることも多くなってきたけど、時間を忘れて調べることができているので楽しい。
なんでそうなるの?が分かると気持ちいいですね。
それでは今日もレッツワクワクコーディング。