いぬおさんのおもしろ数学実験室

おいしい紅茶でも飲みながら数学、物理、工学、プログラミング、そして読書を楽しみましょう

100日で50弾! Day 26/ Bullet13:ワンダーショット

 100日チャレンジ『100日で50弾!』第13回、ワンダーショットです。wanderは「さまよう」です。

 次の動画を見ると、弾が右、左、上、右、左、上、……と向きを変えているのが分かります。弾が飛んでいるのですから向きはジワジワ変えています(カクン、カクン、と変わるとヘンでしょう。そういう演出ならともかく)。

実際には次のように、向きを乱数で決めるなどして変化を持たせます。なかなか面白い!

 

 次の関数で弾の進む向きを定期的に変えています。中で使っている関数
Vector3.Lerp(Vector3 a, Vector3 a, float t)
はベクトルa, bの間を補間してくれる関数です。このLerp()はt = 0のときベクトルaを返し、t = 1 のときベクトルbを返します。t = 0.3のときはabに7:3の重みをつけたベクトルを返します。tを少しずつ変化させると、aから始まってだんだんbに近づいたベクトルが手に入るわけです。(1 - t)a + tb を返す関数、と思ってもよいです。このLerp()をdir1→dir2、dir2→dir3、dir3→dir1 と変えるときに利用します。コード中の tt / span は

0≦tt / span≦1

となります。

//----------------------------------
//時間幅spanでdir1→dir2とジワジワ変わり、
//次のspanでdir2→dir3、次のspanでdir3→dir1 ……
//と繰り返す
//
Vector3 lerp3(float time,
            Vector3 dir1, Vector3 dir2, Vector3 dir3,
            float span) {
    int m = (int)(time / span);
    float tt = time - m * span;
    Vector3 p;
    switch (m % 3) {
    case 0:
        p = Vector3.Lerp(dir1, dir2, tt / span);
        break;
    case 1:
        p = Vector3.Lerp(dir2, dir3, tt / span);
        break;
    default:
        p = Vector3.Lerp(dir3, dir1, tt / span);
        break;
    }
    return p;
}
//----------------------------------
 Lerp()は弾の動きに限ってもいろいろ使えます。曲線A、Bがあり、弾が最初はAに沿って動いていて、途中でジワリとBに変わる、といったことができます。次回、これをやってみます。

 

 弾はここまでで13種類。目標は50なので、1/4が終わったということです。「ああ、何となくこんな感じ」と分かってきたところですが、なかなかいいです。少し時間ができると「記事を書いておこう」とか「あれを調べるかな」とかになるので、充実しています。