barycentric coordinates
/**
* Copyright lizhi ( http://wonderfl.net/user/lizhi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/dRyO5
*/
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Vector3D;
import flash.net.FileReference;
import sliz.miniui.Button;
import sliz.miniui.Silder;
import sliz.miniui.SilderBlack;
import sliz.miniui.skin.SilderBlackSkin;
import sliz.net.MiniLoader;
import flash.net.URLRequest;
import flash.system.Security;
/**
* ...
* @author sliz http://game-develop.net/
*/
public class TestUV extends Sprite
{
private var p1:Point;
private var p2:Point;
private var p3:Point;
private var uvt1:Vector3D;
private var uvt2:Vector3D;
private var uvt3:Vector3D;
private var target:BitmapData;
private var source:BitmapData;
private var cp1:SilderBlack;
private var cp2:SilderBlack;
private var cp3:SilderBlack;
private var us1:Silder;
private var us2:Silder;
private var us3:Silder;
private var us4:Silder;
private var us5:Silder;
private var us6:Silder;
private var nowSelectedId:int=1;
private var file:FileReference;
private var loader:Loader;
public function TestUV()
{
Security.allowDomain("*");
target = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0xffffff);
addChild(new Bitmap(target));
source = target.clone();
source.perlinNoise(100, 100, 3, 1, true, true);
p1 = new Point(stage.stageWidth*Math.random(),stage.stageHeight*Math.random());
p2 = new Point(stage.stageWidth*Math.random(),stage.stageHeight*Math.random());
p3 = new Point(stage.stageWidth*Math.random(),stage.stageHeight*Math.random());
uvt1 = new Vector3D(1);
uvt2 = new Vector3D(1, 1);
uvt3 = new Vector3D(0, 1);
cp1 = new SilderBlack(p1.x, p1.y, this, null);
cp1.addEventListener(MouseEvent.MOUSE_DOWN, onMD);
cp2 = new SilderBlack(p2.x, p2.y, this, null);
cp2.addEventListener(MouseEvent.MOUSE_DOWN, onMD);
cp3 = new SilderBlack(p3.x, p3.y, this, null);
cp3.addEventListener(MouseEvent.MOUSE_DOWN, onMD);
us1 = new Silder(0, 0, this, "num");
us2 = new Silder(0, 20, this, "num");
us3 = new Silder(0, 40, this, "num");
us4 = new Silder(0, 60, this, "num");
us5 = new Silder(0, 80, this, "num");
us6 = new Silder(0, 100, this, "num");
us1.bind(uvt1, "x", usf);
us2.bind(uvt1, "y", usf);
us3.bind(uvt2, "x", usf);
us4.bind(uvt2, "y", usf);
us5.bind(uvt3, "x", usf);
us6.bind(uvt3, "y", usf);
us1.addEventListener(Event.CHANGE, render);
us2.addEventListener(Event.CHANGE, render);
us3.addEventListener(Event.CHANGE, render);
us4.addEventListener(Event.CHANGE, render);
us5.addEventListener(Event.CHANGE, render);
us6.addEventListener(Event.CHANGE, render);
render();
var explorer:Button = new Button("explorer", 2, 120, this, browse);
var url:String="http://www.thecrimsoncrow.com/wp-content/uploads/2011/04/cosplay-1.jpg"; loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoad2);
//loader.load(new URLRequest(url));
}
private function browse(e:Event):void
{
file = new FileReference();
file.browse();
file.addEventListener(Event.SELECT, onSelect);
}
private function onSelect(e:Event):void
{
file.load();
file.addEventListener(Event.COMPLETE, onLoad);
}
private function onLoad(e:Event):void
{
loader.loadBytes(file.data);
}
private function onLoad2(e:Event):void
{
var content:Bitmap = loader.contentLoaderInfo.content as Bitmap;
source = content.bitmapData;
render();
}
private function usf(v:Number):Number
{
return v;
}
private function onMD(e:MouseEvent):void
{
if (e.currentTarget == cp1) nowSelectedId = 1;
if (e.currentTarget == cp2) nowSelectedId = 2;
if (e.currentTarget == cp3) nowSelectedId = 3;
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMM);
stage.addEventListener(MouseEvent.MOUSE_UP, onMU);
}
private function onMU(e:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMM);
stage.removeEventListener(MouseEvent.MOUSE_UP, onMU);
}
private function onMM(e:MouseEvent):void
{
this["cp"+nowSelectedId].x = mouseX;
this["cp"+nowSelectedId].y = mouseY;
this["p"+nowSelectedId].x = mouseX;
this["p"+nowSelectedId].y = mouseY;
render();
e.updateAfterEvent();
}
private function triangleArea(x1:Number,y1:Number,x2:Number,y2:Number,x3:Number,y3:Number):Number {
var a:Number = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
var b:Number = Math.sqrt((x1 - x3) * (x1 - x3) + (y1 - y3) * (y1 - y3));
var c:Number = Math.sqrt((x3 - x2) * (x3 - x2) + (y3 - y2) * (y3 - y2));
var p:Number = (a + b + c) / 2;
return Math.sqrt(p * (p - a) * (p - b) * (p - c));
}
private function triangleArea2(x1:Number,y1:Number,x2:Number,y2:Number,x3:Number,y3:Number):Number {
return ((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) / 2;
}
private function render(e:Event = null):void {
target.fillRect(target.rect, 0xffffffff);
var t:Number = triangleArea2(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
var minX:Number = Math.min(Math.min(p1.x, p2.x), p3.x);
var minY:Number = Math.min(Math.min(p1.y, p2.y), p3.y);
var maxX:Number = Math.max(Math.max(p1.x, p2.x), p3.x);
var maxY:Number = Math.max(Math.max(p1.y, p2.y), p3.y);
for (var i:int = minX; i <= maxX;i++ ) {
for (var j:int = minY; j <= maxY; j++ ) {
var t1:Number = triangleArea2(i, j, p2.x, p2.y, p3.x, p3.y);
if (t * t1 < 0) continue;
var t2:Number = triangleArea2(p1.x, p1.y, i, j, p3.x, p3.y);
if (t * t2 < 0) continue;
var t3:Number = triangleArea2(p1.x, p1.y, p2.x, p2.y, i, j);
if (t * t3 < 0) continue;
var b1:Number = t1 / t;
var b2:Number = t2 / t;
var b3:Number = t3 / t;
var u:Number = uvt1.x * b1 + uvt2.x * b2 + uvt3.x * b3;
var v:Number = uvt1.y * b1 + uvt2.y * b2 + uvt3.y * b3;
var x:Number = source.width * u;
var y:Number = source.height * v;
target.setPixel32(i, j, source.getPixel32(x, y));
}
}
}
}
}