LoginSignup
2
1

More than 1 year has passed since last update.

【p5.js】『Generative Design with p5.js』P_1_2_1_01 で登場する関数 part.2 map()

Last updated at Posted at 2021-12-02

この記事は Qiita p5js アドベントカレンダー3日目の記事です。

これはなに

書籍『Generative Design with p5.js』P_1_2_1_01に登場する関数について理解を深める記事です。
今回はmap()。

map()

mapといえば他の言語だと配列操作の印象がありますが、
p5のmap関数は全然違う目的で使用されるようです。

Type

map(
    value: number,
    start1: number,
    stop1: number,
    start2: number,
    stop2: number,
    withinBounds?: boolean
): number;

引数については下記の通り。

  • value 動的な値
  • start1 valueの下限
  • stop1 valueの上限
  • start2 valueの下限に対して返す値の下限
  • stop2 valueの上限に対して返す値の上限
  • withinBounds trueのとき、stop2の値を超えることがなくなるオプション


mapを理解してこれを書くまで結構苦しみました。

リファレンスより

Re-maps a number from one range to another.
In the first example above, the number 25 is converted from a value in the range of 0 to 100 into a value that ranges from the left edge of the window (0) to the right edge (width).

数値をある範囲から別の範囲に再マッピングします。
上の最初の例では、25という数字は、0から100の範囲の値から、ウィンドウの左端(0)から右端(幅)までの範囲の値に変換されます。(DeepL翻訳)

これだけではわからん(素直な気持ち)

試してみる

リファレンスを参考に下記のコードを試してみました。
コンソールにポインタのX座標とmapの結果を出力します。
(Vueで使用しているため関数の前に'p'があります)

p.setup = () => {
  p.createCanvas(500, 500);
  // p.colorMode(p.HSB);
};

p.draw = () => {
  p.background(204);
  let x1 = p.map(p.mouseX, 0, p.width, 25, 75);
  console.log(`mouseX: ${p.mouseX} x1: ${x1}`);
  p.ellipse(x1, 25, 25, 25);
};

出力結果がこちら。
mouseXが522のとき、mapの結果は77.2と出ています。

mouseX: 522 x1: 77.2

mapの結果はellipse()の第一引数にセットされているため、
ポインタが横に動けば描画された楕円も横に動きます。

p.ellipse(x1, 25, 25, 25);

では何がおこっているのか。

まずstart1は0、stop1はwidthです。
つまりmapにおけるvalueの開始地点は0、
終着地点は500となります。

それを踏まえてstart2とstop2の結果が返る値となります。
start2は25、ということはmouseX(value)が0のときに25を返します。
スクリーンショット 2021-12-02 19.30.00.png

stop2は75なので、mouseX(value)が500(width)のときに75を返します。
ここでもう一度コンソールに出力した結果を確認しましょう。

mouseX: 522 x1: 77.2

ポインタのX座標が522、x1が77.2と出ています。
つまり、現在のポインタはcreateCanvasの範囲からはみ出た場所におり、
targetの位置もstop2の値を少し超えた場所に位置しているということになります。
スクリーンショット 2021-12-02 19.21.52.png

今回はつけていないですが、第五引数のwithinBoundsにtrueを渡せば
mouseXが500を超えても、mapの返り値は75でストップします。

いやー難しかった!!

どんなときに使えそうか

「変動する値をもって、範囲を指定したい別の値に置き換えたいとき」
でいいんじゃないでしょうか。

実際にP_1_2_1_01で使用している箇所をみてみましょう。

tileCountX = int(map(mouseX, 0, width, 2, 100));
tileCountY = int(map(mouseY, 0, height, 2, 10));

リンクから挙動を試してみてください。
横軸の正確な目視は難しいですが、
マウスが右いっぱいの時にタイルの数が1行に対して100列、
マウスが下いっぱいの時にタイルが10行になっていることが分かります。

動的な要素で制御したいときはmap()の使用を検討してみると
面白い動きができるかもしれませんね。

参考

p5.js reference | map()
『Generative Design with p5.js』P_1_2_1_01

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1