3Dを応用して球を作成。

ところで、Mac版Firefox3.0だとstage.stageWidthとか取得できないみたいなんですが、何なんでしょうか?Event.ADDEDイベントで待ってみても音沙汰無しなので、2フレーム目じゃないと取得できないとかではなく永久に取得できてないみたい。めんどくせーなー

ソースもまるっと載せてみます。座標番号はデバッグ用のために付けたのでその辺は割愛しています。Point3Dクラス、TrianglePolygonクラスはActionscript3.0アニメーションのものです。

ずっと転がしてると結構CPU使うみたい。300個のテキストフィールドを30フレーム/秒で更新するのは厳しいかな・・加速を緩めてみたけどどうだろう。

package
{
    import flash.display.Sprite;
    import flash.events.Event;

    public class Sphere3D extends Sprite
    {
        private var points:Array = [];
        private var triangles:Array = [];
        private var radius:Number = 250;
        private var numDiv:uint = 24;
        private var FL:Number = 250;
        private var vpX:Number = stage.stageWidth/2;
        private var vpY:Number = stage.stageHeight/2;

        public function Sphere3D()
        {
            initialize();
        }
        public function initialize():void
        {
            var circums:uint = numDiv/2+1;

            for(var i:uint=0; i<circums; i++)
            {
                var degY:Number = 360/numDiv*i-90;
                var radY:Number = Math.PI/180*degY;
                var cosY:Number = Math.cos(radY);
                var sinY:Number = Math.sin(radY);
                var radius2:Number = Math.floor(radius*cosY);

                for(var j:uint=0; j<numDiv; j++)
                {
                    var id:uint = i*numDiv+j;
                    var degZ:Number = 360/numDiv*j;
                    var radZ:Number = Math.PI/180*degZ;
                    var cosZ:Number = Math.cos(radZ);
                    var sinZ:Number = Math.sin(radZ);

                    points[id] = new Point3D(cosZ*radius2, sinY*radius, sinZ*radius2);
                    points[id].setVanishingPoint(vpX, vpY);
                    points[id].setCenter(0, 0, 200);
                }
            }

            for(i=0; i<(circums-1); i++)
            {
                for(j=0; j<numDiv; j++)
                {
                    id = i*numDiv+j;
                    var end:uint = (i+1)*numDiv-1;

                    var a:uint = id;
                    var b:uint = id+1;
                    var c:uint = id+numDiv;
                    var d:uint = id+numDiv+1;

                    if(id==end)
                    {
                        b = id-numDiv+1;
                        d = id+1;
                    }

                    var d0:Number = distance3D(points[a], points[b]);
                    var d1:Number = distance3D(points[c], points[d]);

                    var triangle0 = new TrianglePolygon(points[a], points[b], points[c]);
                    var triangle1 = new TrianglePolygon(points[b], points[d], points[c]);

                    if(d0>0) triangles.push(triangle0);
                    if(d1>0) triangles.push(triangle1);
                }
            }

            draw();
            addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
        }
        private function onEnterFrameHandler(e:Event):void
        {
            var angleX:Number = (mouseY - vpY)*0.0002;
            var angleY:Number = (mouseX - vpX)*0.0002;

            for(var i:uint=0; i<points.length; i++)
            {
                var point:Point3D = points[i];
                point.rotateX(angleX);
                point.rotateY(angleY);
            }

            draw();
        }
        private function draw():void
        {
            graphics.clear();
            for(var i:uint=0; i<triangles.length; i++)
            {
                triangles[i].draw(graphics);
            }
        }
        private function distance3D(a:Point3D, b:Point3D):Number
        {
            var dx = b.x-a.x;
            var dy = b.y-a.y;
            var dz = b.z-a.z;
            return Math.sqrt(dx*dx+dy*dy+dz*dz);
        }
    }
}