綺麗なキューブ
http://www.youtube.com/watch?v=5wiwi74ek1A&feature=watch_response
Onwards by Traction というメガデモに影響されて作った紫キューブ。再現できねぇ。
/**
* Copyright kuma360 ( http://wonderfl.net/user/kuma360 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/mr9e
*/
//http://www.youtube.com/watch?v=5wiwi74ek1A&feature=watch_response
//Onwards by Traction というメガデモに影響されて作った紫キューブ。再現できねぇ。
//
package
{
import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.geom.*;
[SWF ( width = 465, height = 465, frameRate = 60 )];
public class Main extends Sprite
{
private var _EFFECT1:BitmapData ;
private var _EFFECT2:BitmapData ;
private var _SCREEN:BitmapData ;
private var _CANVAS:BitmapData ;
private var _cube1:Cube ;
private var _cube2:Cube ;
public static var _L:Vector3D ;
public static var _RX:Vector3D ;
public static var _RY:Vector3D ;
public static var _RZ:Vector3D ;
public function Main():void {
_EFFECT1 = new BitmapData ( stage.stageWidth , stage.stageHeight , true , 0 ) ;
_EFFECT2 = new BitmapData ( stage.stageWidth , stage.stageHeight , true , 0 ) ;
_SCREEN = new BitmapData ( stage.stageWidth , stage.stageHeight , true , 0 ) ;
_CANVAS = new BitmapData ( stage.stageWidth , stage.stageHeight , false , 0 ) ;
addChild ( new Bitmap ( _CANVAS ) ) ;
_L = new Vector3D ( .1 , 1 , 0 ) ;
_L.normalize () ;
_RX = new Vector3D ( 1, 0, 0 ) ;
_RY = new Vector3D ( 0, 1, 0 ) ;
_RZ = new Vector3D ( 0, 0, 1 ) ;
_cube1 = new Cube ( 0 ) ;
_cube2 = new Cube ( 100 ) ;
addEventListener ( Event.ENTER_FRAME , RUN ) ;
}
public function RUN ( e:Event ):void {
var I:int = 0 ;
_SCREEN.fillRect ( _SCREEN.rect , 0 ) ;
for ( I = 0 ; I < 20 ; ++ I ) {
_cube1.RUN ( _SCREEN , I * 25 + 10 , .2 , 0 ) ;
}
for ( I = 0 ; I < 20 ; ++ I ) {
_cube2.RUN ( _SCREEN , I * 25 + 10 , .3 , 1 ) ;
}
//グレアフィルター作成
_EFFECT1.draw ( _SCREEN ) ;
_EFFECT2.threshold ( _EFFECT1 , _EFFECT1.rect , new Point , "<" , 0xA0 , 0 , 0xFF , true ) ;
_EFFECT1.applyFilter ( _EFFECT2 , _EFFECT2.rect , new Point , new BlurFilter ( 40 , 40 , 2 ) ) ;
//描画
_CANVAS.lock () ;
_CANVAS.fillRect ( _CANVAS.rect , 0 ) ;
_CANVAS.draw ( _SCREEN ) ;
_CANVAS.draw ( _EFFECT2 , null , null, "screen" ) ;
_CANVAS.draw ( _EFFECT1 , null , null, "screen" ) ;
_CANVAS.unlock() ;
}
}
}
import flash.display.*;
import flash.events.*;
import flash.geom.*;
class Cube extends Sprite
{
private var _V:Vector.<Vector3D> ;
private var _C:Vector.<Vector3D> ;
private var _S:Sprite ;
private var _z:Array = new Array ;
private var _M1:Matrix3D = new Matrix3D ;
private var _M2:Matrix = new Matrix ;
private var _time:Number = 0 ;
//////////////////////////////
public function Cube( time:Number ) {
_time = time ;
const S:int = 12 ;
const A:Array = [
new Vector3D ( -S , -S , -S ) ,
new Vector3D ( S , -S , -S ) ,
new Vector3D ( S , S , -S ) ,
new Vector3D ( -S , S , -S ) ,
new Vector3D ( -S , -S , S ) ,
new Vector3D ( S , -S , S ) ,
new Vector3D ( S , S , S ) ,
new Vector3D ( -S , S , S )
];
_V = new Vector.<Vector3D>;
_C = new Vector.<Vector3D>;
_S = new Sprite ;
for ( var I:int = 0 ; I < A.length ; ++ I ) {
_V.push ( A[I] ) ;
_C.push ( new Vector3D ) ;
}
_z = new Array ;
}
//////////////////////////////
public function RUN ( SCREEN:BitmapData , X:int , cnt:Number , color:uint ):void {
const TX:int = X ;
const TY:int = 230 + Math.cos ( ( X + _time ) * Math.PI / 180 ) * 90 ;
_time += cnt ;
const A:Array = [
[ 0, 1, 2, 3 ],
[ 7, 6, 5, 4 ],
[ 0, 4, 5, 1 ],
[ 1, 5, 6, 2 ],
[ 2, 6, 7, 3 ],
[ 3, 7, 4, 0 ]
];
var I:int ;
//更新
_M1.identity() ;
_M1.prependRotation ( _time * 5 * Math.PI / 180 , Main._RX );
_M1.prependRotation ( _time * 10 * Math.PI / 180 , Main._RY );
_M1.prependRotation ( _time * 90 * Math.PI / 180 , Main._RZ );
for ( I = 0 ; I < _V.length ; ++ I ) {
_C[I] = _M1.transformVector ( _V[I] ) ;
}
// 面の中心のZ座標を求める
for( I = 0 ; I < A.length ; ++I ){
_z[I] = { I:I , Z:( _C[A[I][0]].z + _C[A[I][1]].z + _C[A[I][2]].z + _C[A[I][3]].z ) / 4 } ;
}
//Zソート
_z.sort ( function ( a:Object , b:Object ):Number { return b.Z - a.Z; } );
//描画
var G:Graphics = _S.graphics ;
G.clear() ;
for ( I = 0 ; I < A.length ; ++ I ) {
var J:int = _z[I].I ;
//法線を求める
var V1:Vector3D = _C[A[J][1]].subtract ( _C[A[J][0]] ) ;
var V2:Vector3D = _C[A[J][3]].subtract ( _C[A[J][0]] ) ;
V1 = V1.crossProduct ( V2 ) ;
V1.normalize ( ) ;
//色決定
var D:Number = V1.dotProduct ( Main._L ) ;
var C:int = D * 0x40 + 0x80 ;
var COLOR:uint ;
if ( color == 0 ) {
if ( 0 < D ) {
COLOR = ( C << 16 ) | ( ( D * 0xA0 ) << 8 ) | C ;
} else {
COLOR = ( C << 16 ) | C ;
}
} else {
if ( 0 < D ) {
COLOR = ( ( D * 0xA0 ) << 16 ) | ( C << 8 ) | C ;
} else {
COLOR = ( C << 8 ) | C ;
}
}
var ALPHA:Number = .5 + ( ( D < 0 ) ? 0 : D ) ;
//光の乗り方は適当
_M2.createGradientBox (
330 ,
330 ,
0 ,
TX - 100 ,
100
) ;
//面を描画
G.beginGradientFill ( "radial" , [ 0xFFFFFF , COLOR ] , [ ALPHA , ALPHA ] , [ 0 , 255 ] , _M2 ) ;
G.moveTo ( _C[A[J][0]].x + TX , _C[A[J][0]].y + TY ) ;
G.lineTo ( _C[A[J][1]].x + TX , _C[A[J][1]].y + TY ) ;
G.lineTo ( _C[A[J][2]].x + TX , _C[A[J][2]].y + TY ) ;
G.lineTo ( _C[A[J][3]].x + TX , _C[A[J][3]].y + TY ) ;
G.endFill () ;
}
SCREEN.draw ( _S ) ;
}
}