物体を時間経過で動かす,アニメーションの基本を学ぶ.
void setup()
{
size(640, 480, P3D);
}
void draw()
{
background(127, 127, 127);
camera(100, -100, 100, 0, 0, 0, 0, 1, 0);
axis(100);
sphereandaxis();
}
void axis(float l)
{
stroke(255, 0, 0);
line(0, 0, 0, l, 0, 0);
stroke(0, 255, 0);
line(0, 0, 0, 0, l, 0);
stroke(0, 0, 255);
line(0, 0, 0, 0, 0, l);
}
void sphereandaxis()
{
axis(30);
stroke(0, 0, 0);
sphere(20);
}
基本的なアニメーション手法の一つ,アニメーションさせたい物体に対して,特定の時間における位置や向きを指定し,それらをコンピュータ側で補間することでアニメーションを行う.
キーフレームアニメーション _ CG・映像の専門情報サイト _ CGWORLD.jp
ここでは2つのキーフレーム(位置)を線形補間する基本的なコードを示す.
float t = 0;
void setup()
{
size(640, 480, P3D);
}
void draw()
{
background(127, 127, 127);
camera(100, -100, 100, 0, 0, 0, 0, 1, 0);
axis(100);
float startx = 0;
float starty = 0;
float startz = -100;
float endx = 0;
float endy = 0;
float endz = 100;
t += 0.005;
if (t > 1) t = 1;
float newx = (1- t) * startx + t * endx;
float newy = (1- t) * starty + t * endy;
float newz = (1- t) * startz + t * endz;
translate(newx, newy, newz);
sphereandaxis();
}
void axis(float l)
{
stroke(255, 0, 0);
line(0, 0, 0, l, 0, 0);
stroke(0, 255, 0);
line(0, 0, 0, 0, l, 0);
stroke(0, 0, 255);
line(0, 0, 0, 0, 0, l);
}
void sphereandaxis()
{
axis(30);
stroke(0, 0, 0);
sphere(20);
}
ここでは,位置をキーフレームとしている.
一つ目のキーフレーム(位置),
float startx = 0; float starty = 0; float startz = -100;
二つ目のキーフレーム(位置),
float endx = 0; float endy = 0; float endz = 100;
それらを線形補間する.パラメータt(0<=t<=1)によって現在の補間された位置を算出する.tが0であれば,startx,tが1であればendxとなることが分かる.
float newx = (1- t) * startx + t * endx; float newy = (1- t) * starty + t * endy; float newz = (1- t) * startz + t * endz;
パラメータtには毎フレーム値を加算する,この値がアニメーションの速度となる.
t += 0.005;
ここまでのプログラムでは,x,y,zの値をそれぞれ別の変数として扱っていたが,Processingではベクトルを表すPVector型がある.
PVectorを導入すると次のようにプログラムを書き換えることができる,線形補間もよく使われる計算のためPVector.lerpメソッドが用意されている.
float t = 0;
void setup()
{
size(640, 480, P3D);
}
void draw()
{
background(127, 127, 127);
camera(100, -100, 100, 0, 0, 0, 0, 1, 0);
axis(100);
PVector start = new PVector(0, 0, -100);
PVector end = new PVector(0, 0, 100);
t += 0.005;
if (t > 1) t = 1;
PVector newpos = start.lerp(end, t);
translate(newpos.x, newpos.y, newpos.z);
sphereandaxis();
}
void axis(float l)
{
stroke(255, 0, 0);
line(0, 0, 0, l, 0, 0);
stroke(0, 255, 0);
line(0, 0, 0, 0, l, 0);
stroke(0, 0, 255);
line(0, 0, 0, 0, 0, l);
}
void sphereandaxis()
{
axis(30);
stroke(0, 0, 0);
sphere(20);
}
イージング(Easing)とはアニメーションの速度に緩急をつけることを意味する.これまで
t += 0.005;
としていたことから,等速度でのアニメーションとなる.
イージングを導入することで緩急のあるアニメーションを実現できる.
以下のサイトにイージングの一覧がまとまっている.
例えば,アニメーションの始めと終わりが緩やかになるeaseInOutCubicを導入すると以下のようになる.
コードを以下のように変更した.
サイト下部に書かれているイージングの関数プログラム(ただしJavaScriptをProcessingに直したもの)を追加し,
//JavaScript版
function easeInOutCubic(x: number): number {
return x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2;
}
↓
float easeInOutCubic(float x) {
return x < 0.5 ? 4 * x * x * x : 1 - (float)Math.pow(-2 * x + 2, 3) / 2;
}tを関数を通してイージングを適用するようにする.
t += 0.005; float newt = easeInOutCubic(t); if (t > 1) t = 1; PVector newpos = start.lerp(end, newt);
招待されているBoxアップロードフォルダ「第07回」に自身の学籍番号のフォルダ(アルファベット大文字,例:20FI999)を自身で作成し,その中に各課題,指定された名前で完成させたスケッチフォルダごとアップロードしてください.
提出締め切り:第6回と同様
BOXアップロードフォルダの招待メールが来ていない,また,WebClassで本講義が見えない方は森谷まで連絡ください.
以下のサイトのイージングの一覧から,例で作ったeaseInOutCubic以外のイージングを一つ実装せよ.
提出スケッチフォルダ名:BASIC7_1
以下はeaseInOutElasticを実装した例:
コード修正のポイント:
JavaScriptでは,左から関数を表すfunction,関数名,引数名,引数名の型(JavaScriptでは数字はすべてnumber型),戻り値の型となっている.
function easeInOutCubic(x: number): number {
Processingに直すと,戻り値の型(float),関数名,引数の型,引数名となる.
float easeInOutCubic(float x) {
また,Math.powなどはProcessingではdouble型なので直前に(float)を付けてfloat型にキャスト(変換)する.
===
は
==
にする.
ファーガソン曲線(エルミート曲線)を実装し,曲線上を物体が動くアニメーションを作成せよ.
提出スケッチフォルダ名:ADVANCE7_1
参考:ファーガソン曲線(3年前期CGモデリングおよび演習より)
以下は始点(start),始点における接線(startt),終点(end),終点における接線(endt)を以下で実装した例.
PVector start = new PVector(0, 0, -100); PVector startt = new PVector(1000, 0, 0); PVector end = new PVector(0, 0, 100); PVector endt = new PVector(1000, 0, 0);
ベクトルの足し算にはPVector.addを使う.
例:
PVector startaddend = start.add(end);
ベクトルのスカラー倍にはPVector.multを使う.
例:
PVector doublestart = start.mult(2);