drawTrianglesをやってみた

前から興味があったdrawTriangleに触ってみました。

デモ

これは画像の4隅を頂点にして、その四角形を三角形二つに分けています。

結構簡単でびっくりしました。

package
{
    import __AS3__.vec.Vector;
    
    import flash.display.Bitmap;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;

    [SWF(backgroundColor="#000000")]
    public class DrawTriangle01 extends Sprite
    {
    	[Embed(source='Dock.jpg')]
        private var img:Class;
        private var bmp:Bitmap=new img();
    	private var p1:DrugPoint, p2:DrugPoint, p3:DrugPoint, p4:DrugPoint;
    	private var t:Shape=new Shape();
    	private var vec:Vector.<Number>, uvtData:Vector.<Number>;
    	private var indices:Vector.<int>;
    	
        public function DrawTriangle01()
        {
        	stage.scaleMode = StageScaleMode.NO_SCALE;
        	stage.align = StageAlign.TOP_LEFT;
        	
            vec = new Vector.<Number>();
            vec.push(100,100,400,100,100,400,400,400);
            indices = new Vector.<int>();
            indices.push(0,1,2,1,2,3);
            uvtData=new Vector.<Number>();
            uvtData.push(0, 0, 1, 0, 0, 1, 1, 1);
            
            addChild(t);

            p1 = new DrugPoint(100,100);
            p2 = new DrugPoint(400,100);
            p3 = new DrugPoint(100,400);
            p4 = new DrugPoint(400,400);
            addChild(p1);
            addChild(p2);
            addChild(p3);
            addChild(p4);
            
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
        
        private function onEnterFrame(event:Event):void{
        	vec=Vector.<Number>([p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y]);
        	t.graphics.clear();
        	t.graphics.beginBitmapFill(bmp.bitmapData);
            t.graphics.drawTriangles(vec, indices, uvtData);
            t.graphics.endFill();
        }
    }
}
	import flash.events.MouseEvent;
	import flash.display.Sprite;
	

class DrugPoint extends Sprite{
	public function DrugPoint(x:Number, y:Number, color:uint=0xff0000){
		this.x = x;
		this.y = y;
		graphics.beginFill(color);
		graphics.drawCircle(0,0,5);
		graphics.endFill();
		addEventListener(MouseEvent.MOUSE_DOWN, function():void{ startDrag(); });
		addEventListener(MouseEvent.MOUSE_UP, function():void{ stopDrag(); });
	}
}

drawTrianglesをやってみた2

drawTriangleをやってみました。

ぷるぷるします。


頂点を縦横等間隔に配置して、頂点がマウスの近くにあればマウスに吸い寄せられるようにしています。
ぷるぷるした感じはバネの法則を使って表現しています。


ソース

package
{
    import __AS3__.vec.Vector;
    
    import flash.display.Bitmap;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.geom.Point;

    [SWF(backgroundColor="#000000")]
    public class DrawTriangle02 extends Sprite
    {
    	[Embed(source='prin3.gif')]
        private var image:Class;
        private var bmp:Bitmap=new image();
        //頂点を格納する配列
        private var drugpAry:Array;
        //頂点の個数
        private const WN:int = 30, HN:int = 30;
        //描画する大きさ
        private const W:int = 400, H:int = 400;
        //一マスの大きさ
        private const MASSW:Number = W/WN, MASSH:Number = H/HN;
        //画像を描画するShape
    	private var sp:Shape=new Shape();
    	//頂点、uvt、使用する頂点を管理する配列
    	private var vec:Vector.<Number>, uvtData:Vector.<Number>, indices:Vector.<int>;
    	//ばね定数
    	private var k:Number = 1.2;
    	//減衰定数
    	private var a:Number = 0.9;
    	//頂点、マウスの位置を格納するためのPoint
    	private var p:Point = new Point(), mouseP:Point = new Point();
    	
        public function DrawTriangle02()
        {
        	stage.scaleMode = StageScaleMode.NO_SCALE;
        	stage.align = StageAlign.TOP_LEFT;
        	stage.frameRate = 30;
        	
        	//初期化
            vec = new Vector.<Number>();
            uvtData=new Vector.<Number>();
            indices = new Vector.<int>();
            drugpAry = [];
            
            //頂点を等間隔に並べる。
            for(var i:int = 0; i <= HN; i++){
            	drugpAry[i] = [];
            	for(var j:int = 0; j <= WN; j++){
            		vec.push(j*MASSW, i*MASSH);
            		uvtData.push(j/WN, i/HN);
            		drugpAry[i][j] = new SPoint(j*MASSW, i*MASSH);
            	}
            }
            
            //使用する頂点の格納。一つの四角形を2つの三角形に分けている。
            for(i = 0; i < HN; i++){
            	for(j = 0; j < WN; j++){
            		indices.push(j+i*(WN+1), (j+1)+i*(WN+1), j+(i+1)*(WN+1));
            		indices.push((j+1)+i*(WN+1), j+(i+1)*(WN+1), (j+1)+(i+1)*(WN+1));
            	}
            }

            addChild(sp);
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
        
        private function onEnterFrame(event:Event):void{
        	vec = Vector.<Number>([]);
        	for(var i:int = 0; i <= HN; i++){
            	for(var j:int = 0; j <= WN; j++){
            		p.x = drugpAry[i][j].x; 
            		p.y = drugpAry[i][j].y;
            		mouseP.x = mouseX;
            		mouseP.y = mouseY;
            		var d:Number = p.subtract(mouseP).length;
            		if(d < 100 && d > 0){
            			//マウスの位置に引き寄せる
            			drugpAry[i][j].x += (mouseP.x - p.x)/(d*2) + (j*MASSW - p.x)/50;
            			drugpAry[i][j].y += (mouseP.y - p.y)/(d*2) + (i*MASSH - p.y)/50;
            		}
            		else{
            			//ばねの力の計算
            			drugpAry[i][j].forceX = drugpAry[i][j].forceX*a + (j*MASSW - p.x)*k;
            			drugpAry[i][j].forceY = drugpAry[i][j].forceY*a + (i*MASSW - p.y)*k;
            			//頂点の移動
            			drugpAry[i][j].x += drugpAry[i][j].forceX;
            			drugpAry[i][j].y += drugpAry[i][j].forceY;
            		}
            		vec.push(drugpAry[i][j].x, drugpAry[i][j].y);
            	}
            }
        	
        	sp.graphics.clear();
        	sp.graphics.beginBitmapFill(bmp.bitmapData);
            sp.graphics.drawTriangles(vec, indices, uvtData);
            sp.graphics.endFill();
        }
    }
}
	import flash.geom.Point;
	
class SPoint extends Point{
	public var forceX:Number, forceY:Number;
	public function SPoint(x:int, y:int):void{
		super(x, y);
		forceX = 0;
		forceY = 0;
	}
}