Adobe AfterEffects での物理演算第三弾記事です。今回は、物が床でバウンドした場合について処理を作成してみました。
今回も様々な要因は考えず、減衰しながら連続して二次曲線を描く方法で実現していきます。
AfterEffectsには、エクスプレッションという、Javascriptのエンジンを使ったプログラミングができるようになっています。 このエクスプレッションを使うことで、様々な計算やアニメーションを自動化し、制作を最大限に効率化[…]
実現イメージ
以下の動画のようにバウンドする動作を作ります。
処理イメージ

放物運動を地面で折り返し、減衰させて繰り返し放物運動を行います。バウンド回数に応じて、減衰量のべき乗分を減衰させていくイメージです。
放物運動の計算については以下の記事で解説していますので合わせてご覧ください。
Adobe AfterEffects での物理演算第二弾記事です。今回は、物を投げた時の運動である、放物運動(斜方投射)について処理を作成してみました。 風や空気抵抗などの様々な要因は考えず、シンプルに二次曲線を描く方法で実現してい[…]
事前準備

① 新規コンポジションを作成(1920×1080)
② シェイプレイヤーを作成し、「楕円形」と「塗り」を追加し、レイヤー名を「layer0001」にします。
これで準備OKです。
処理内容
バウンド後の位置を取得する関数を作成しました。
AfterEffectsのエクスプレッション内で、時間計算など、同じ処理を何度もする場合もあると思います。 そんな時は、関数を使うと記述量を大幅に減らせる可能性があります。 この関数の使い方についてご紹介します。 関数と[…]
以下のコードを「layer0001」の位置のエクスプレッションにコピペします。
//c 2021 COLORCODE-AE
//バウンド後の位置を返す
function getBoundPosition(nRadius, nBasePeriod, nRepulsion, n1mPx, nSpeed, nMaxBoundTimes, nStartTime, anStartPosition){
var nPeriodStartTime = 0;
var nPeriod = 0;
var nBoundTimes = 0;
var nG = 9.8;
var nT = Math.max(0, time - nStartTime);
for(var i=0; i<=nMaxBoundTimes; i++){
nPeriod = nBasePeriod * Math.pow(nRepulsion, i);
if(nT <= (nPeriodStartTime + nPeriod)){
break;
}
else{
nPeriodStartTime += nPeriod;
}
nBoundTimes = i;
}
var nBoundHeight;
if(nBoundTimes < nMaxBoundTimes){
var nPeriodT = nT - nPeriodStartTime - (nPeriod / 2);
var nPeriodMaxHeight = nG * n1mPx * Math.pow((nPeriod / 2), 2);
nBoundHeight = nG * n1mPx * Math.pow(nPeriodT, 2) - nPeriodMaxHeight;
}
else{
nBoundHeight = 0;
}
var addPositionn = [nT * nSpeed, nBoundHeight - nRadius];
return add(anStartPosition, addPositionn);
}
//関数を使う
var nRadius = 50; /* バウンド対象物の半径 */
var nBasePeriod = 1; /* 最初の滞空時間 */
var nRepulsion = 0.8; /* バウンドごとの減衰量 */
var n1mPx = 300; /* 1mを表すピクセル数 */
var nSpeed = 500; /* 1秒あたりのX方向移動距離 */
var nStartTime = 0; /* アニメーション開始時刻 */
var nMaxBoundTimes = 30; /* 最大バウンド回数 */
var anStartPosition = [0, 1080]; /* アニメーション開始位置 */
getBoundPosition(nRadius, nBasePeriod, nRepulsion, n1mPx, nSpeed, nMaxBoundTimes, nStartTime, anStartPosition);
これで完成です。再生すると、赤い円が画面左からバウンドすると思います。
処理説明
今回作成した関数「getBoundPosition」を使うことで、バウンド後の位置を取得します。
関数の使い方
関数「getBoundPosition」には引数が8つあります。
- nRadius・・・バウンド対象物の半径
- nBasePeriod・・・最初の滞空時間
- nRepulsion・・・バウンドごとの減衰量
- n1mPx・・・1mを表すピクセル数
- nSpeed・・・1秒あたりのX方向移動距離
- nMaxBoundTimes・・・最大バウンド回数
- nStartTime・・・アニメーション開始時刻
- anStartPosition・・・アニメーション開始位置
①は半径が違う対象物でも、バウンドする地面の高さを合わせるために使用します。②は最初の滞空時間で、2回目以降は③を掛け合わせた滞空時間になります。③は1だと減衰なしです。④と⑤でバウンド高さ、移動速度を変更できます。⑥は最大バウンド回数、⑦⑧はアニメーション開始時刻、開始位置になります。
関数説明
関数「getBoundPosition」では以下の処理をしています。
- バウンドの周期を計算
- 現在時刻のバウンド周期からバウンド演算を実施
- 最大バウンド回数を超えたらバウンド計算をやめる(yの加算量0)
まとめ
減衰しながら放物運動を繰り返せばバウンドになるのでは?と思い作成しましたが、それなりにリアルなアニメーションになりました。
様々なサイズの対象物でも、地面の高さが合うように作ったので、色々なサイズでお試しください。