今回は、COS 波を使用して下の GIF 画像のように、波状に飛び出すボールを実装していこうと思います。難易度は中級程度ですが、よく使用するパターンかなとも思うので是非実装してみてください。このチュートリアルでは、三角形グリッドを作成する際に LunchBox というプラグインを使用しています。
からインストールしてからチャレンジしてみてください。こちらのチュートリアルは動画化しております、動画の方がよい方は以下のリンクからどうぞ!
概要
上画像がプログラムの全体像となっております。各ブロックごとに説明していこうと思います。
三角形グリッドを作成
- Polygon コンポーネントで三角形を作成します。
- プラグイン Lunch Box の Subdivide Triangle コンポーネントを使用し、作成した三角形を小さな三角形で分割し、三角形グリッドを作成します。
蓋の作成
- Surface コンポーネントで三角形グリッドの各要素をサーフェイス化します。
- Area コンポーネントで各三角形サーフェイスの中心点を取得します。
- Discontinuty コンポーネントで各三角形の頂点を取得します。
- Line コンポーネントで各頂点と中心点を結ぶ直線を作成します。中心点の入力は Graft してデータ構造を頂点に合わせます。
- Surface Split コンポーネントで先ほど作成した直線で、各三角形サーフェイスを切断します。各三角形サーフェイスが 3 つの 2 等辺三角形サーフェイスに分割されました。
蓋を開閉する回転軸を取得
- Explode コンポーネントで先ほど作成した 2 等辺三角形サーフェイスのエッジを 3 本の直線に分割します。このうち最も長い直線を回転軸とします。
- Length コンポーネントで 3 本の直線の長さを取得します。
- Sort List コンポーネントで分割した直線のリストを長さ順に並べ替えます。これでリストの一番最後に長い直線がきます。
蓋の開閉方向の整理
- 先ほど取得した回転軸を中心に、二等辺三角形を回転させれば蓋が開閉するのですが、回転軸の方向がまちまちなので、上に開くものと下に開くものがあり、すべて上側に統一するひつようがあります。その処理をしていこうと思います。
- Sort List コンポーネントで並べ替えた二等辺三角形のエッジのリストから最後の値(-1 番目)を取得し、回転軸を取得します。
- Surface Split コンポーネントの出力端子に Graft Tree コンポーネントを接続します。入力端子を Flatten して接続することで、各直線が個別のブランチに格納されます。後々楽なのでこの処理をしています。
- Is Plane コンポーネントを接続し、各二等辺三角形の法線ベクトルを取得し、Unit Vector コンポーネントで単位ベクトルに変換します。
- リストの中身を確認するとわかるのですが、法線方向が上向きのものと下向きのものがあります。ここで Flip コンポーネントで法線方向を揃えれば開閉方向が統一しそうなもんですが、実際は回転軸を Flip しなければいけないので、法線方向が負の方向の三角形のみ取得していきます。Member Index コンポーネントでと Construct Vector コンポーネントで値が(0,0,-1)のリストのインデックスを取得します。
- List Item コンポーネントで先ほど取得したインデックスの直線を取得し、Flip コンポーネントで向きを反転します。
- Cull Index コンポーネントで反転させなかった直線も取得します。
- Merge コンポーネントで反転した直線としなかった直線を結合して、先ほどのデータ構造になるように元に戻します。この時、Cull Index コンポーネントの後に Trim Tree コンポーネントをかまし、Tree 構造の階層を合わせてます。
- Rotate コンポーネントで向きを統一させた軸を中心に二等辺三角形を回転させていきます。適当に上画像の様に 45 度回転させると上画像の様になると思います。この回転角度を Cos 波を用いて段階的に開閉させていきます。
蓋の開閉角度のリスト作成 ①
- それでは段階的に開閉させるための角度のリストを作成していきます。
- Discontinuty コンポーネントで最初に作成した大きな三角形の頂点を取得し、List Item コンポーネントで頂点を 1 つ取得します。今回は‐1 番目を取得しています。
- Point コンポーネントで以前 Area コンポーネントで取得した三角形グリッドの中心点を取得してきます。
- Discontinuty コンポーネントで先ほど取得した頂点と各グリッドの中心点までの距離のリストを作成します。
蓋の開閉角度のリスト作成 ②
- 作成した距離のリストを Remap Numbers コンポーネントで角度にリマップします。とりあえず 0 度~ 360 度にリマップします。こうすることで、先ほどの距離が短ければ 0 度に近づき、長ければ 360 度に近づきます。Radians コンポーネントでラジアンに変換し、出力端子を Graft します。
- この角度のリストを Cos コンポーネントに接続していく前に、波の位相をずれをコントロールするために Addition コンポーネントで角度を足し算できるようにしておきます。最終的にこのスライダーを変化させることで、波の頂点をずれていき、波打つようにボールが飛び出すようになります。とりあえず今は 0 度を足しておきましょう。
- 足し算した角度を Cosine コンポーネントに接続し、Cos 波を取得します。-1 ~1までのが取得できているかと思います。
蓋の開閉角度のリスト作成 ③
- 先ほど Cos コンポーネントで取得したリストは-1 ~ 1 までの値となっております。1 のとき蓋が完全に開いた状態、-1 ~ 0 のときは閉じた状態、0.5 のときは半分開いた状態、といった感じで Cos の値によって開く角度を変えていこうと思うので、この値に角度を掛けていくことで、蓋の開き角度を設定していきます。
- とりあえず負の値に角度を掛けると下側に蓋が開いてしまうので、Maximum コンポーネントを使用し、負の値は 0 になるようにします。これで Cos のリストが 0 ~ 1 までの値になりました。
- Multiplication コンポーネントで角度を掛けていきます。この時かける角度は最大開き角度を掛けます。今回は 90 度を掛けているので、最も開いたときは 90 度となります。つまり、先ほどのリストが 1 のとき 90 度蓋が開き、0.5 のときは 45 度、0 のときは 0 度といった感じになります。Radians コンポーネントでラジアン変換します。
- Repeat Data コンポーネントで各値を 3 つずつ用意します。1 つの三角形グリッドに対して 3 との 2 等辺三角形があるので 3 つ用意しています。
- Graft Tree コンポーネントを用意入力端子を Flatten し、Graft することで、角度のリストを個別のブランチに格納します。これを先ほどの Rotate コンポーネントに接続すると上画像の様になります。
- 頂点からの距離が一番近い箇所と最も遠い箇所で蓋が 90 度開いているかと思います。これは、Cos の値は 0 度のときと 360 度のときに値が 1 となるためです。
- 上画像の赤丸で囲った Number Slider コンポーネントを変化させると波の周波数を変えることができます。例えば、720 度にすれば、2 波できるので 90 度開く箇所が 2 波分できます、
- 上画像の青丸で囲った Addition コンポーネントで足している位相の Number Slider コンポーネントを変化させれば、蓋が波打つように開いていくと思います。
ボールを作成
- Point コンポーネントで三角形グリッドの中心を持ってきます。
- Line SDL コンポーネントで各三角形グリッドの中心点から Z 方向に延びる直線を作成します。長さは 0.4 にしています。
- Evaluate Curve コンポーネントを作成した直線に接続し、Reparametraize します。入力端子 t に先ほど作成した Maximum コンポーネントの出力端子 0 ~ 1 までの値を接続します。こうすることで、0 のとき直線の始点、1 のとき直線の終点を取得できます。
- Mesh Sphere コンポーネントで取得した点を中心とした球を作成します。Brep でもいいのですが、メッシュの方が動作が軽いのでメッシュにしています。
- 蓋が閉じ切ったとき、球は蓋より下あってほしいので、作成した球体を Move コンポーネントで-Z 方向に移動させます。-0.15 動かすといい感じになりました。調整してみてください。
蓋に隙間を設ける
- 現状、蓋同士がゼロタッチなので、若干小さくします。Curve Middle コンポーネントで回転軸の中心点を取得します。
- Scale コンポーネントで取得した中心点をもとに縮小します。0.98 倍しました。
箱の作成
- 一番最初に作成した大きな Polygon コンポーネントから取得できる大きな三角形を Extrude コンポーネントでー Z 方向に押し出します。-0.2 押し出しています。
- Cap Hole コンポーネントで蓋をします。
- 上面は不要なので取り除きます。Deconstrut Brep コンポーネントで分解し、Cull Index コンポーネントで上面を取り除きます。リストの 4 番目が上面でした。
- Custom Preview コンポーネントと Colour Swatch コンポーネントで色付けします。
ボールの色付け
- ボールの色付けをします。今回は虹色に変化するように設定していきます。Number コンポーネントで Maximum コンポーネントから取得できる 0 ~ 1 までのリストを取得します。リストは Flatten しておきます。
- Bounds コンポーネントで最小値~最大値までのドメインを取得し、Deconstruct Domain コンポーネントで最小値と最大値を取得します。
- Gradient コンポーネントの L0 に最小値、L1 に最大値を接続し、Number コンポーネントで取得した 0 ~ 1 までのリストを入力端子 t に接続します。
- Custom Preview コンポーネントに接続し色付けします。ボールが最も高い位置にあるときは、Gradient コンポーネントの右側の色、最も低い位置のときは左側の色に近づきます。
完成
以上になります。最初の Gif 画像のようなアニメーションを作成したい方は、位相をずらすための Number Slider コンポーネントで Animate 機能を使用し、動画編集ソフトなどで画像を結合してアニメーションを作成してみてください。難しく感じた方は、Panel コンポーネントでデータの中身を確認しながら、少しづつ進めいき理解していっていただければと思います。