forked from: sphere by setPixel
頂点を setPixel によって描いた sphere
以下の URL の sphere とは、レンダリングでビミョーに違っています。
wonderfl.kayac.com/code/717c0d8afd7ef96747925381e6d82f effd10b4ff
// forked from Aquioux's sphere by setPixel
// 頂点を setPixel によって描いた sphere
// 以下の URL の sphere とは、レンダリングでビミョーに違っています。
// wonderfl.kayac.com/code/717c0d8afd7ef96747925381e6d82f effd10b4ff
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Vector3D;
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
[SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "#000000")]
public class Main extends Sprite {
// プロジェクション
private var fov:PerspectiveProjection;
// 3D オブジェクトのコンテナ
private var canvas:BitmapData;
// 頂点格納 Vector
private var vctrVertics:Vector.<Vertex>;
private var vctrVerticsCol:Vector.<Vertex>;
// 回転に関わる変数
private var aX:Number = 0;
private var aY:Number = 0;
// 定数
private const SW:uint = 465; // stage.stageWidth
private const SH:uint = 465; // stage.stageHeight
private const DIST:uint = 150; // 中心から頂点までの距離
private const XOFF:Number = SW / 2; // stageWidth / 2
private const YOFF:Number = SH / 2; // stageheight / 2
private var twoDArray:Array = new Array(new Array(), new Array());
public var mainArr:Array;
public function Main() {
inittrace(stage);
var gridSize:Number = 465;
mainArr = new Array(gridSize);
var i:Number;
var j:Number;
for (i = 0; i < gridSize; i++) {
mainArr[i] = new Array(gridSize);
for (j = 0; j < gridSize; j++) {
mainArr[i][j] = Math.round( Math.random()*0xFFFFFF);
}
}
Wonderfl.capture_delay(10);
createCanvas(); // キャンバス生成
createProjection(); // プロジェクション生成
createVertics(); // 頂点生成
randomColVert();
// イベントハンドラ
stage.addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
}
// onEnterFrame
private function onEnterFrameHandler(e:Event):void {
// 回転角度を増加
aX += (mouseX - XOFF) * 0.005;
aY -= (mouseY - YOFF) * 0.005;
// 変換行列生成
var mat:Matrix3D = new Matrix3D();
// 回転を変換行列に合成
mat.appendRotation(aX, Vector3D.Y_AXIS);
mat.appendRotation(aY, Vector3D.X_AXIS);
mat.appendRotation(aY, Vector3D.Z_AXIS);
//trace(aX+","+aY);
perspective(mat, fov); // 投影
render(); // レンダリング
}
// 投影
private function perspective(mat:Matrix3D, fov:PerspectiveProjection):void {
for each (var element:Vertex in vctrVertics) {
element.perspective(mat, fov);
}
}
// レンダリング
private function render():void {
canvas.lock();
canvas.fillRect(canvas.rect, 0x000000);
for each (var element:Vertex in vctrVertics) {
canvas.setPixel(element.x+XOFF, element.y+YOFF,element.color);
//trace(element.x);
// canvas.setPixel(element.x+XOFF, element.y+YOFF, mainArr[int(element.x)][int(element.y)]);
//trace(mainArr[int(element.x)][int(element.y)]);
// trace(element.x);
}
canvas.unlock();
}
// キャンバス生成
private function createCanvas():void{
canvas = new BitmapData(SW, SH, false, 0x000000);
addChild(new Bitmap(canvas));
}
// プロジェクション生成
private function createProjection():void {
fov = new PerspectiveProjection();
fov.fieldOfView = 60; // 視野角の設定
}
// 頂点生成
private function createVertics():void {
var baseNum:uint =10;
var vNum:uint = baseNum * 2;
var hNum:uint = baseNum * 30;
trace("vetice");
// theta:シータ(θ)は緯度、phi:ファイ(φ)は経度
var theta:Number = Math.PI / vNum; //point distance
var phi:Number = Math.PI * 2 / hNum; //vertex seperation
vctrVertics = new Vector.<Vertex>();
vctrVerticsCol = new Vector.<Vertex>();
var i:uint = 0;
for (var v:int = 0; v < vNum+1 ; v++) {
for (var h:int = 0; h < hNum ; h++) {
var px:Number = DIST * Math.sin(theta * v) * Math.cos(phi * h);
var pz:Number = DIST * Math.sin(theta * v) * Math.sin(phi * h);
var py:Number = DIST * Math.cos(theta * v);
var vertex:Vertex = new Vertex(px, py, pz,0x555555);
vctrVertics.push(vertex);
}
}
}
public function randomColVert():void {
for each (var element:Vertex in vctrVertics) {
element.color = 0x00ff00;
}
}
}
}
/*
* 頂点クラス
*/
import flash.geom.Vector3D;
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
class Vertex {
private var home:Vector3D = new Vector3D(); // 座標ホームポジション
private var proj:Vector3D = new Vector3D(); // 投影座標
public var color:int = 0xff0000;
public function Vertex(x:Number, y:Number, z:Number,col:Number) {
home.x = x;
home.y = y;
home.z = z;
}
/**
* 投影処理(透視投影)
*/
public function perspective(mat:Matrix3D, fov:PerspectiveProjection):void {
proj = mat.transformVector(home);
proj.w = fov.focalLength / (fov.focalLength + proj.z);
proj.project();
}
// getter
public function get x():Number { return proj.x; }
public function get y():Number { return proj.y; }
public function get z():Number { return proj.z; }
public function get w():Number { return proj.w; }
}
//// WONDERFL TRACE /////
import flash.display.Sprite;
import flash.display.Stage;
import flash.text.TextField;
import flash.text.TextFormat;
function inittrace(s:Stage):void
{
WTrace.initTrace(s);
}
//global trace function
var trace:Function;
//wtreace class
class WTrace
{
private static var FONT:String = "Fixedsys";
private static var SIZE:Number = 12;
private static var TextFields:Array = [];
private static var trace_stage:Stage;
public static function initTrace(stg:Stage):void
{
trace_stage = stg;
trace = wtrace;
}
private static function scrollup():void
{
// maximum number of lines: 100
if (TextFields.length > 100)
{
var removeme:TextField = TextFields.shift();
trace_stage.removeChild(removeme);
removeme = null;
}
for(var x:Number=0;x<TextFields.length;x++)
{
(TextFields[x] as TextField).y -= SIZE*1.2;
}
}
public static function wtrace(... args):void
{
var s:String="";
var tracefield:TextField;
for (var i:int;i < args.length;i++)
{
// imitating flash:
// putting a space between the parameters
if (i != 0) s+=" ";
s+=args[i].toString();
}
tracefield= new TextField();
tracefield.autoSize = "left";
tracefield.text = s;
tracefield.y = trace_stage.stageHeight - 20;
var tf:TextFormat = new TextFormat(FONT, SIZE, 0xeeeeee);
tracefield.setTextFormat(tf);
trace_stage.addChild(tracefield);
scrollup();
TextFields.push(tracefield);
}
}