[AE]　二次元配列でのsort()

#最終的にやりたい事
適当にシェイプで楕円形をwiggleなんかで動かして、楕円形近いシェイプ同士を線で結ぶ
connected dotsのモーションを作る
![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178061/0f379fbc-c21d-2bba-c9dc-3a3e7b5d6cea.jpeg)
こんな感じの物ね！

#縛りとしてはエクスプレッションで書く。
今の頭のイメージとしては
・シェイプをwiggleで動かす
・エフェクトのビームを使って線は描画する（オーソドックスなやり方）
・ビームの開始点には基準となるのシェイプを指定
・ビームの終了点にはエクスプレッションで基準のシェイプレイヤーに近いシェイプを取ってくる（何番目に近いかはスライダー制御で指定出来る様にする）
とまあこんな感じでモーションは出来ると思っています。

###軽くまとめると
➊コンポジションにはDotという名前の楕円形シェイプレイヤーを量産して線を繋げるのは➋のエクスプレッションで自動化する。
➋ビーム用のレイヤー（平面レイヤー）終了点にエクスプレッションを書いていく

#具体的には
Dotのレイヤー分と必要なのと基準シェイプから何本まで線を出すか、つまりn番目まで近いレイヤーをターゲットにするかで➋を複製する必要がある。

まずは距離を取る為にビームの終了点にプログラムを書いていくわけだが

```jsx
TargetPos = thisComp.layer("Dot").transform.position;
MyPos =  effect("It's Me")("レイヤー").transform.position;
c = sub(TargetPos,MyPos);
d = length(c);
( d < effect("Distance")("スライダー") )? MyPos :TargetPos;
```

とりあえず、これでMyPos（基準となるシェイプ開始点）からTargetPos （目標となるシェイプ終了点)までの距離は取れる

ただDotというレイヤーは量産するので、コンポジション内のDotレイヤーがいくつあるのかと、距離を出してソートする必要がある。
そこで考えたのがこのエクスプレッション

```jsx
MyPos =  thisComp.layer("Beam").effect("It's Me")("レイヤー").transform.position;

n = thisComp.numLayers;
var arry = [];

for (var i = 1 ; i <= n ; i++){
	var ln = thisComp.layer(i).name;
	if ( ln.match(/Dot/)){
		var getPos = thisComp.layer(i).transform.position;
		c = sub(getPos,MyPos);
		d = length(c);
		arry.push([ln,d])
	}
}

function compareFunc(a, b) {
  return a[0],(a[1] - b[1]);
}

arry.sort(compareFunc)

arry.join("\r");

```
arryに返ってくるのは二次元配列で[レイヤー名、距離]が返ってくる。

#重要な役割を担っているソートの関数
このソートの部分がちょっと迷ったのと今回のプログラムで重要な役割を担ってるので
記事メモ。
内容は二次元配列をソートしてくれる関数

```jsx
function compareFunc(a, b) {
  return a[0],(a[1] - b[1]);
}
```

ちなみにAEをキャプチャするとこんな感じです。
![コメント 2020-01-18 111246.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178061/0c7adde9-2965-ac21-88c1-1a6a25f672a6.jpeg)

コンポジション内にあるレイヤーを全て繰り返しfor文でかけて（/Dot/）でマッチをかけて
距離を計算して配列に、レイヤー名と距離を入れる。
最後にソートして距離の小さい順に並ぶ。

#ほぼ完成が見えてきた
今はわかりやすくテキストレイヤーにエクスプレッションを書いているが、これをbeamのレイヤーの終了点に持って行って、もうちょっとゴニョゴニョすれば完成すると思う。
ちなみに現在は二次元空間のみで考えています。
三次元になるとどうなるのやら。。。

完成したらまたこの続きを追記しようと思います。

#という事で続き
#ロジックはほぼ完成と思いきや
何か違う。。。近くの物ポジションを取っていないっぽい。
とりあえず現状
これをbeamのレイヤーの終了点に書く

```jsx
prop = thisProperty.propertyGroup(1).propertyIndex;
parentTarget = effect(prop);
idx = parentTarget.name.replace(/[^0-9]/g, '');

MyPos =  effect("It's Me")("レイヤー").transform.position;
neares = Math.floor(effect("NearNum "+idx)("スライダー"));
dist =  effect("Distance "+idx)("スライダー");

n = thisComp.numLayers;
var arry = [];

for (var i = 1 ; i <= n ; i++){
	var ln = thisComp.layer(i).name;
	if ( ln.match(/Dot/)){
		var getPos = thisComp.layer(i).transform.position;
		c = sub(getPos,MyPos);
		d = length(c);
		if (d >= dist){
			arry.push([getPos,d])
		}
	}
}

function compareFunc(a, b) {
  return a[0],(a[1] - b[1]);
}

arry.sort(compareFunc);

try{
( arry[neares][1] < dist )? MyPos :arry[neares][0];
}catch(e){
	MyPos
}
```

#ごちゃごちゃしているので動画でまとめるが・・・
こうゆうことね！！

beam開始点

```jsx
thisComp.layer(effect("It's Me")("レイヤー").name).transform.position
```

beam終了点

```jsx
MyPos =  thisComp.layer(effect("It's Me")("レイヤー").name).transform.position;
neares = Math.floor(thisComp.layer("Beam").effect("NearNum 1")("スライダー"));
dist =  thisComp.layer("Beam").effect("Distance 1")("スライダー");
var result;
n = thisComp.numLayers;
var arry = [];
var ln ;

for (var i = 1 ; i <= n ; i++){
    ln = thisComp.layer(i).name;
    if ( ln.match(/Dot/)){
        var getPos = thisComp.layer(i).transform.position;
        c = sub(getPos,MyPos);
        d = length(c);
        if (d >= dist){
            arry.push([getPos,d,ln])
        }
    }
}

function compareFunc(a, b) {
  return a[0],(a[1] - b[1]);
}

arry.sort(compareFunc);

try{
    var result = ( arry[neares][1] < dist )? MyPos :arry[neares][0];
//    result = ( arry[neares][1] < dist )? MyPos :arry[neares][2];
}catch(e){
    result = MyPos;
}

result;
```

#とりあえずどんな物が出来たのかを発表
とりあえず、形になったというか、力技で何とか形にしたって言った方がいいかもしれない。
何故なら３次元で作ってないため、すごーく平面感があって、気に入らないから、３次元っぽく、被写界深度があるかのように無理やりカメラブラーでデプスマップ作って、それっぽく作ってるからだ。

出来上がったのがこちら
![コメント 2020-01-19 225446.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178061/4b33840a-ca45-59ed-822b-82a8b862f3be.jpeg)
何となくそれっぽいけども・・・

ちなみにトップのサンプル画像に寄せた設定にするとこんな感じ

![コンポ 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178061/061c82a2-76d8-1a00-fdc5-7bba8f334f96.png)



今日も撮影の合間時間があったから考えてたけど、違うアプローチ方法見つけた。
こっちの方が合理的かもしれない、からもう少し詰めてみて、いい感じであれば発表します。