growCrystalsでやっていること[考えたこと]

 

 

どうやってクリスタルを生やしているか

f:id:tonoshake:20191114091545j:image

一枚の三角ポリゴンの上に頂点を6つ定義して、そこから六角柱を伸ばしています。

 

どうやって6つの頂点を定義しているか

f:id:tonoshake:20191114094040j:image

三角ポリゴンの各頂点からの距離を使って6つの点を導出しています。

点の座標をABCそれぞれにどの程度寄せるかを係数として与えています。

 

 

三角ポリゴンの頂点3つをABCとして具体的な式を示します。

p0=A/3 + B/3 + C/3

p1=A×1/2 +B×1/4+C×1/4

p2=A×2/5 +B×2/5+C×1/5

p3=A×1/4 +B×1/2+C×1/4

p4=A×2/5 +B×1/5+C×2/5

p5=A×1/4 +B×1/4+C×1/2

p6=A×2/5 +B×2/5+C×1/5

 

係数の合計値がどれも1になっているのがポイントです。

 

どうやって面からまっすぐに伸ばすか

面の法線を利用しています。

f:id:tonoshake:20191114145739j:image

そのままでは頂点ごとに別の法線を持っていて扱いにくいので、面の法線を求めます。

 

外積を用いることで簡単に求められます。

f:id:tonoshake:20191114150622j:image

C→A向きのベクトルとC→B向きのベクトルの外積をとることで、ABCに垂直なベクトルが取れます。

それを正規化することで、好きな数字をかければ面に垂直な方向へ大きくなる便利な単位ベクトルとして扱えます。

 

C→A向きのベクトルは、AからCを引いたものになります。

外積や正規化は、それぞれcross()とnormalize()という関数が用意されているので、手で実装しなくても大丈夫です。

 

どうやって先端を作るか

二つ前に出した六角形の中心点p0を使用します。

 

p0からp6まで法線方向に移動させたものを、それぞれpp0〜pp6とします。

 

f:id:tonoshake:20191114153209j:image

pp0、pp1、pp2を結べば三角形を作ることができます。

あとはこれをpp0 pp2 pp3のように隣り合った頂点とpp0を結んで行きます。

 

クリスタルの大きさの変え方

 

以上のものをコードにすれば六角柱を生やすことは出来ますが、太さの調整がしにくいため一工夫加えます。

 

形を崩さず太さを変えるには、六角の中心→六角の頂点(または六角の頂点→六角の中心)の方向に六角の頂点を移動させる必要があります。

先程法線を求める際AからCをひくことで、C→A向きのベクトルを求めました。

六角の中心→六角の頂点も同様にして求めることができます。中心→各頂点の向きベクトルをそれぞれpd1〜pd6としていくつか式として示します。

pd1=p1-p0

pd2=p2-p0

...

pd6=p6-p0

 

各pdを正規化すれば、好きな数字をかけると中心→頂点の方向に移動する便利なベクトルになります。

マイナスをかければ中心→頂点方向へ移動するのでサイズ調整はばっちりです。

 

以上が考え方の説明です。

次の記事では実際にコードに起こすためのあれこれを解説します。

 https://tonoshake.hateblo.jp/entry/2019/11/14/221842

 

こちらで配布してます

Grow Crystals + 水晶の置物△188 | さかなや https://booth.pm/ja/items/1679585