simple 3D 01 (not using PV3D)
もうすぐ3D本出るし、勉強。
PV3Dとかを使わない3D表現その1
Zソートとかもしてない。ただ点を打ってるだけです。
/**
* Copyright sakef ( http://wonderfl.net/user/sakef )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/z3To
*/
/*
もうすぐ3D本出るし、勉強。
PV3Dとかを使わない3D表現その1
Zソートとかもしてない。ただ点を打ってるだけです。
*/
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
[SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
public class simple3d_01 extends Sprite
{
private const FOCUS:Number=280;
private const RADIUS:Number=100;
private const N_POINT1:int=60;
private const N_POINT2:int=100;
private const CENTER_X:int=465 / 2;
private const CENTER_Y:int=465 / 2;
private const W:int=465;
private const H:int=465;
private const RADIAN:Number=Math.PI / 180;
private var canvas:BitmapData;
private var ary:Array;
private var theta:Number=0;
public function simple3d_01()
{
canvas=new BitmapData(465, 465, false, 0x000000);
addChild(new Bitmap(canvas));
ary=[];
// 各点の初期位置を計算
for(var i:int=0; i < N_POINT1; i++)
{
var theta1:Number=(360 / N_POINT1) * i * RADIAN;
for(var j:int=0; j < N_POINT2; j++)
{
var theta2:Number=((180 / N_POINT2) * j - 90) * RADIAN;
var xx:Number=RADIUS * Math.cos(theta2) * Math.sin(theta1);
var yy:Number=RADIUS * Math.sin(theta2);
var zz:Number=RADIUS * Math.cos(theta2) * Math.cos(theta1);
var p:point3d=new point3d(xx, yy, zz);
ary[i * N_POINT2 + j]=p;
}
}
addEventListener(Event.ENTER_FRAME, onFrame);
}
private function onFrame(e:Event):void
{
theta+=1.0;
canvas.fillRect(canvas.rect, 0x000000);
canvas.lock();
for(var i:int=0; i < N_POINT1; i++)
{
for(var j:int=0; j < N_POINT2; j++)
{
var p:point3d=ary[i * N_POINT2 + j] as point3d;
// 回転行列で回転 (x軸回転とy軸回転の積を展開したもの)
var tmpX:Number=p.x * Math.cos(theta * RADIAN) + p.y * Math.sin(theta * RADIAN) * Math.sin(theta * RADIAN) - p.z * Math.sin(theta * RADIAN) * Math.cos(theta * RADIAN);
var tmpY:Number=p.y * Math.cos(theta * RADIAN) + p.z * Math.sin(theta * RADIAN);
var tmpZ:Number=p.x * Math.sin(theta * RADIAN) - p.y * Math.sin(theta * RADIAN) * Math.cos(theta * RADIAN) + p.z * Math.cos(theta * RADIAN) * Math.cos(theta * RADIAN);
// 3D→2D変換
var scale:Number=FOCUS * 1.5 / (FOCUS - tmpZ);
var xx:int=int(tmpX * scale) + CENTER_X;
var yy:int=int(tmpY * scale) * (-1) + CENTER_Y;
// 範囲内なら点を打つ
if (xx >= 0 && yy >= 0 && xx < W && yy < H) canvas.setPixel(xx, yy, p.color);
}
}
canvas.unlock();
}
}
}
class point3d
{
public var x:Number;
public var y:Number;
public var z:Number;
public var color:uint;
public function point3d(x:Number=0, y:Number=0, z:Number=0)
{
this.x=x;
this.y=y;
this.z=z;
color=Math.random() * 0x00ffff;
}
}