HTML5とJavaScriptで3Dタグクラウド1歩手前

あむちょです。

HTML5とJavaScriptで3Dに再び挑戦。

PR アプリ作ってます

tagCloud

今回作ったのはグルグル回る地球儀みたいなやつです。クリックする位置により、回転する方向が変わります。

3dTagCloud

やってみたら分かるけど、本当にただ回るだけです。今後の予定では、タグクラウド(カテゴリを細分化した物を重要度で並べた物)をこれで表示しようかと思います。

以下説明。

まずは、画面上に均等になるように座標値を与える。ほんとはどう考えても二次元配列使った方がわかりやすいです。

<br />
function object(n,name,fontSize){<br />
    this.x=width/numX*(Math.floor(n%numX)+0.25);<br />
    this.y=height/numY*(Math.floor(n/numY)+0.5);</p>
<p>    this.drawX=0;<br />
    this.drawY=0;<br />
    this.tempX;<br />
    this.tempY;<br />
    this.z=0;<br />
    this.tempZ=0;</p>
<p>    this.rad0=0;<br />
    this.rad1=0;</p>
<p>    this.string=name;<br />
    this.size=fontSize;<br />
    this.alp=1;<br />
}<br />

次に上下と左右を繋げて球体にするために中心からの距離に比例した角度を与える。

<br />
struct[n].rad0=90/(height/2)*Math.abs(struct[n].y-height/2)*dtr;	//delY 0~height/2<br />
if(struct[n].y &gt; height/2)struct[n].rad0=-1*struct[n].rad0;</p>
<p>struct[n].rad1=180/(width/2)*Math.abs(struct[n].x-width/2)*dtr;		//delX 0~width/2<br />
if(struct[n].x &gt; width/2)struct[n].rad1=-1*struct[n].rad1;<br />

これで 以下の画像のような角度になる。

world

最初から角度を順番に与える方が楽な気がするけど、のちのち応用がききそうなので、座標値から角度をだしてます。

次に、二次元平面に投影される座標を求める。

3d

x=r・cosθ・cos(φ)          //図だとz軸が逆向きになってます。
y=r・sin(θ)
z=r・cosθ・sin(φ)

<br />
//x<br />
struct[n].drawX=disRound*Math.cos(struct[n].rad0)*Math.cos(struct[n].rad1);<br />
//y<br />
struct[n].drawY=disRound*Math.sin(struct[n].rad0);<br />
//z<br />
struct[n].z=disRound*Math.cos(struct[n].rad0)*Math.sin(struct[n].rad1);<br />

となります。次にクリックによって回転させたいので、x軸とy軸を回転させる。

x軸回りをdθ回した時の座標(x2,y2,z2)は

x2=x
y2=y・cos(dθ)+z・sin(dθ)
z2=-y・sin(dθ)+z・cos(dθ)

また同時にy軸をdθ回転させた時の座標は

x2=x2・cos(dθ)+z2・sin(dθ)
y2=y2
z2=z2・cos(dθ)-x2・sin(dθ)

となります。

<br />
struct[n].tempX=struct[n].drawX;<br />
struct[n].tempY=struct[n].drawY;<br />
struct[n].tempZ=struct[n].z;</p>
<p>//rotation x<br />
struct[n].drawY=struct[n].tempY*Math.cos(delRad0)+struct[n].tempZ*Math.sin(delRad0);<br />
struct[n].z=-struct[n].tempY*Math.sin(delRad0)+struct[n].tempZ*Math.cos(delRad0);</p>
<p>//rotation y<br />
struct[n].drawX=struct[n].tempX*Math.cos(delRad1)+struct[n].z*Math.sin(delRad1);<br />
struct[n].z=struct[n].z*Math.cos(delRad1)-struct[n].tempX*Math.sin(delRad1);<br />

あとはzの値により、透明度を変化させてます。

現状だと最初に均等に座標値を与えているせいで、球体の上下が密になってしまいます。実際にタグクラウドとして使うには改良の必要ありです。

それにしても軸が一個増えるだけで、すごくめんどくさいです。3Dができないと、ゲーム屋としてはもぐりらしいが、

いっそもぐりでいい(嘘)

 

コメント