ご近所を探せ!(2020.06.29)

はじめに

 このページでは以下の作品について説明します。

この作品はランダムに生成した 5,000 個の点 \( p_i \ (i=1,\cdots,5000) \) に対し、 最も近くに存在する点 \( p_j \ (j \ne i) \) と線を結ぶという作品です。

ソースコード

N=5000
P=[[random(500),random(500),int(random(N)),1e9] for i in [0]*N]
def setup():size(500,500)
def draw():
    clear();stroke(-1)
    for i in range(N):
        t=(i+int(random(N-1))+1)%N
        d=dist(P[i][0],P[i][1],P[t][0],P[t][1])
        if P[i][3]>d:
            P[i][2]=t
            P[i][3]=d
        t=P[i][2]
        line(P[i][0],P[i][1],P[t][0],P[t][1])

解説

 変数 P の使い方が分かれば、特に難しいところはないので、 その部分を中心に説明します。

 i 番目の点 \( p_i \) の情報は P[i] に格闘されています。 \( p_i \) の座標を \( (x_i,y_i) \) とすると、 P[i][0] および P[i][1] にはそれぞれ \( x_i, y_i \) が 格納されています。

 P[i][2] には \( p_i \) の、 現時点で見つかっている最近点 \( p_{n_i} \) のインデックス値 \( n_i \) が 格納されています。

そのため、描画では t=P[i][2] として、

line(P[i][0],P[i][1],P[t][0],P[t][1])

という処理を行っています (これで、現時点で最も近いと思われている点との間に線分が描画されます)。

 P[i][3] には、現時点での \( p_i \) 最近点 \( p_{n_i} \) との距離 \( d_i \) が格納されています。

 各フレームごとに全ての点 \( p_i \) に対し、 適当に乱数でインデックス t を決め、 \( p_i, p_t \) 間の距離を計算します。

その距離が \( d_i \) つまり P[i][3] よりも小さければ、 より近い点を見つけたこととなりますので、 P[i][2] および P[i][3] を更新します。

 毎フレーム毎にこのような処理を行うと、 冒頭で挙げたようなアニメーションが生成できます。

まとめ

 このページでは、最近点を探して線分で結ぶ「ご近所を探せ」という作品について 解説しました。 ソースコードも掲載し、その中でも重要な情報を格納している変数 P について説明しました。

 ツィートでも書いているのですが、プログラムの圧縮に失敗しており、 1 ツィート内に収めることができませんでした。 やっている内容はそんなに難しくないので、 もう少し短く記述できそうなのですが、 上手く言っていません。

つぶやき Processing するためには、 別のアプローチ方法が必要なのかもしれません (が、現時点では全くアイデアがありません)。