Skip to content

Instantly share code, notes, and snippets.

@andyli
Created April 9, 2010 13:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save andyli/361166 to your computer and use it in GitHub Desktop.
Save andyli/361166 to your computer and use it in GitHub Desktop.
Draw distorted image like perspective transform.
//Ported from the work of Zeh:
//http://zehfernando.com/2010/the-best-drawplane-distortimage-method-ever/
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.geom.Point;
import flash.Vector;
class PerspectiveImage {
/**
* @author zeh
*/
static public function drawPlane(graphics:Graphics, bitmap:BitmapData, p1:Point, p2:Point, p3:Point, p4:Point) : Void {
var pc:Point = getIntersection(p1, p4, p2, p3); // Central point
// If no intersection between two diagonals, doesn't draw anything
if (pc == null) return;
// Lengths of first diagonal
var ll1:Float = Point.distance(p1, pc);
var ll2:Float = Point.distance(pc, p4);
// Lengths of second diagonal
var lr1:Float = Point.distance(p2, pc);
var lr2:Float = Point.distance(pc, p3);
// Ratio between diagonals
var f:Float = (ll1 + ll2) / (lr1 + lr2);
// Draws the triangle
graphics.clear();
graphics.beginBitmapFill(bitmap, null, false, true);
graphics.drawTriangles(
flash.Lib.vectorOfArray([p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y]),
flash.Lib.vectorOfArray([0,1,2, 1,3,2]),
flash.Lib.vectorOfArray([0,0,(1/ll2)*f, 1,0,(1/lr2), 0,1,(1/lr1), 1,1,(1/ll1)*f]) // Magic
);
}
static private function getIntersection(p1:Point, p2:Point, p3:Point, p4:Point): Point {
// Returns a point containing the intersection between two lines
// http://keith-hair.net/blog/2008/08/04/find-intersection-point-of-two-lines-in-as3/
// http://www.gamedev.pastebin.com/f49a054c1
var a1:Float = p2.y - p1.y;
var b1:Float = p1.x - p2.x;
var a2:Float = p4.y - p3.y;
var b2:Float = p3.x - p4.x;
var denom:Float = a1 * b2 - a2 * b1;
if (denom == 0) return null;
var c1:Float = p2.x * p1.y - p1.x * p2.y;
var c2:Float = p4.x * p3.y - p3.x * p4.y;
var p:Point = new Point((b1 * c2 - b2 * c1)/denom, (a2 * c1 - a1 * c2)/denom);
if (Point.distance(p, p2) > Point.distance(p1, p2)) return null;
if (Point.distance(p, p1) > Point.distance(p1, p2)) return null;
if (Point.distance(p, p4) > Point.distance(p3, p4)) return null;
if (Point.distance(p, p3) > Point.distance(p3, p4)) return null;
return p;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment