Glass Sphere
球の方程式を偏微分してガラス球っぽくしています
...
@author Njf
/**
* Copyright nappingjellyfish ( http://wonderfl.net/user/nappingjellyfish )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/uWMe
*/
package
{
/****************************
* 球の方程式を偏微分してガラス球っぽくしています
******************************/
import flash.display.Bitmap;
import flash.display.BitmapDataChannel;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.events.Event;
import flash.filters.BitmapFilter;
import flash.filters.DisplacementMapFilter;
import flash.filters.DisplacementMapFilterMode;
import flash.net.URLRequest;
import flash.display.BitmapData;
import flash.geom.Point;
import flash.display.Sprite;
/**
* ...
* @author Njf
*/
public class GlassSphere extends Sprite
{
public static const IMG_URL:String = "http://assets.wonderfl.net/images/related_images/3/33/335c/335ce3c6047316a32e439f50cb9b4887236e240f";
public var myLoader:Loader = new Loader();
private var bitmapData:BitmapData;
private var radius:int = 100;
public function GlassSphere()
{
loadDefault();
var rbmp:SphereBitmap = new SphereBitmap(radius*2, radius*2);
bitmapData = rbmp.createBitmapData();
//addChild(bmp);
stage.addEventListener(Event.ENTER_FRAME, onEnterFrameHaneler);
addEventListener(Event.REMOVED_FROM_STAGE, onRemoveHandler);
}
/****************
* On remove
* **************/
private function onRemoveHandler(e:Event):void
{
stage.removeEventListener(Event.ENTER_FRAME, onEnterFrameHaneler);
removeEventListener(Event.REMOVED_FROM_STAGE, onRemoveHandler);
}
/****************
* On enter Frame
* **************/
private function onEnterFrameHaneler(e:Event):void
{
//bmp.x = mouseX - bmp.width / 2;
//bmp.y = mouseY - bmp.height / 2;
var filter:BitmapFilter = getBitmapFilter(bitmapData, mouseX-radius, mouseY-radius,radius);
filters = [filter];
}
/****************
* image load
* **************/
private function loadDefault():void {
var myRequest:URLRequest = new URLRequest(IMG_URL);
myLoader.load(myRequest);
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImgLoaded);
addChild(myLoader);
}
/****************
* load complete
* **************/
private function onImgLoaded(e:Event):void
{
myLoader.width = stage.stageWidth;
myLoader.height = stage.stageHeight;
}
/****************
* フィルター作成
* **************/
private function getBitmapFilter(bmpData:BitmapData,mapPointX:int,mapPointY:int,scale:int):BitmapFilter {
var mapBitmap:BitmapData = bmpData;
var mapPoint:Point = new Point(mapPointX, mapPointY);
var componentX:uint = BitmapDataChannel.RED;
var componentY:uint = BitmapDataChannel.GREEN;
var scaleX:Number = scale;
var scaleY:Number = scale;
var mode:String = DisplacementMapFilterMode.WRAP;
var color:uint = 0;
var alpha:Number = 0;
return new DisplacementMapFilter(mapBitmap,
mapPoint,
componentX,
componentY,
scaleX,
scaleY,
mode,
color,
alpha);
}
}//class end
}//package end
import flash.display.BitmapData;
import flash.geom.Point;
/**
* ...
* @author Njf
*/
class SphereBitmap
{
private var _sizeX:int = 0;
private var _sizeY:int = 0;
private static const CENTER_COLOR:uint = 0x80;
private var centerX:Number = 0;
private var centerY:Number = 0;
/****************
* コンストラクタ
* **************/
public function SphereBitmap(sizeX:int,sizeY:int)
{
_sizeX = sizeX;
_sizeY = sizeY;
centerX = sizeX / 2.0;
centerY = sizeY / 2.0;
}
/****************
* ビットマップ作成
* **************/
public function createBitmapData():BitmapData
{
var bitmapData:BitmapData = new BitmapData(sizeX, sizeY, true, 0x000000);
for (var i:int = 0; i < sizeX; i++)
{
for (var j:int = 0; j < sizeY; j++)
{
setBitMap(i, j, bitmapData);
}
}
return(bitmapData);
}
/****************
* ビットマップ作成メイン
* **************/
private function setBitMap(i:int,j:int,bmpd:BitmapData):void
{
var p:Point = diffPotential(poteintial, i, j);
var r:uint;
var g:uint;
var a:uint = 0;
if (p.x == 0 && p.y==0) {
r = CENTER_COLOR;
g = CENTER_COLOR;
a = CENTER_COLOR;
}else{
r = ((CENTER_COLOR * p.x) + CENTER_COLOR );
g = ((CENTER_COLOR * p.y) + CENTER_COLOR);
a = 0xFF;
}
if (r > 0xFF || g > 0xFF ){
r = CENTER_COLOR;
g = CENTER_COLOR;
}
g = g << 8;
r = r << 16;
a = a << 24;
bmpd.setPixel32(i, j, CENTER_COLOR | a| r | g);
}
/****************
* ポテンシャル
* **************/
private function poteintial(x:Number,y:Number):Number
{
var dx:Number = x - centerX;
var dy:Number = y - centerY;
var r2:Number = (dx * dx + dy * dy) ;
var r:Number = Math.sqrt(r2);
var ret:Number = 0;
var R:Number = 100;
if (r < R) {
ret = -Math.sqrt(R * R - r * r)/4;
}
return(ret);
}
/****************
* ポテンシャル微分
* **************/
public static function diffPotential(pot:Function,x:Number,y:Number):Point
{
var p:Point = new Point();
var d:Number = 0.01;
p.x = (pot(x + d / 2, y) - pot(x - d / 2, y))/d;
p.y = (pot(x, y + d / 2) - pot(x, y - d / 2))/d;
return(p);
}
/****************
* サイズ取得
* **************/
public function get sizeX():int { return _sizeX; }
public function get sizeY():int { return _sizeY; }
}