計算の記憶は?
エクスプレッションは各フレームごとに計算を行います。そのため前のフレームで計算した結果を次のフレームで使うことが出来ないのです。
- 例として棒グラフが不規則に増加しながら伸びるエクスプレッションを考えてみます。
- それには 1フレーム前の値に乱数を加えるコードを書けば良さそうです。(24fps)
x=random(300);
scale.valueAtTime(time-1/24)+[x,0]
- 結果はオレンジの棒グラフです。
- フレーム毎にスケールが変化するだけでそれまでの計算結果は加算されていません。
- valueAtTime( )は残念ながらエクスプレッションの計算結果ではなく、計算前の値を返してきます。
- この状況に対処するには、Compのスタートから現在までに起こった変化をコードの中で再計算しなければなりません。そのために計算結果を合計するループが必要になります。
i = 0;
accum = 0;
while (i <= time){
accum += random(60);
i += 1/24;
}
scale+[accum,0]
- 結果はグリーンの棒グラフです。
- whileループは[ i ]が現在の時間より小さければaccumにrandom( )の値を加え、[ i ]を1フレーム分追加します。ループから抜けたとき、accumにそれまでの乱数がすべて合計されています。
さらに
- ※これ以降は計算の記憶とは直接関係ありません。
- グリーンのグラフをよく見ると棒が短くなるところがあります。
- その原因はrandom( )に有ります。random( )は呼ばれる度に違う値を返します。つまり前のフレームで合計したのと次のフレームで合計した時の値は全く別のもなのです。
- これを回避するにはseedRandom( )の第二引数[ timeless ]を[ true ]にして乱数を固定する必要があります。
i = 0;
accum = 0;
seedRandom(1,true);
while (i <= time){
accum += random(60);
i += 1/24;
}
scale+[accum,0]
- 結果はグレーの棒グラフです。
ブラウン運動 もどき
小さな粒子が不規則にジグザグ運動をするシミュレーションです。
- フレーム毎にランダムな値を加算して小さな点を移動させます。
- ここでもwhileループで0フレームからの軌跡を加算します。
- またseedRandom( )の第二引数を[ true ]にする必要があります。
i = 0;
X =0;
Y=0;
d=5; //1frの最大移動幅
seedRandom(1,true);
while (i <= time){
X += random(-d,d);
Y += random(-d,d);
i += 1/24;
}
[X,Y]