mirror of
https://github.com/fergalmoran/dss.git
synced 2025-12-23 10:10:21 +00:00
410 lines
11 KiB
JavaScript
Executable File
410 lines
11 KiB
JavaScript
Executable File
/**
|
|
* http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html
|
|
*
|
|
* A great resource: http://www.senocular.com/flash/tutorials/transformmatrix/
|
|
*
|
|
* (a:Number = 1, b:Number = 0, c:Number = 0, d:Number = 1, tx:Number = 0, ty:Number = 0)
|
|
*
|
|
* @param int a
|
|
* @param int b
|
|
* @param int c
|
|
* @param int d
|
|
* @param int tx
|
|
* @param int ty
|
|
*/
|
|
|
|
Matrix = function(a, b, c, d, tx, ty){
|
|
|
|
|
|
/**
|
|
* @var int a The value that affects the positioning of pixels along the x
|
|
* axis when scaling or rotating an image.
|
|
*/
|
|
this.a = a || 1;
|
|
|
|
|
|
/**
|
|
* @var int b The value that affects the positioning of pixels
|
|
* along the y axis when rotating or skewing an image.
|
|
*/
|
|
this.b = b || 0;
|
|
|
|
|
|
/**
|
|
* @var int c The value that affects the positioning of pixels
|
|
* along the x axis when rotating or skewing an image.
|
|
*/
|
|
this.c = c || 0;
|
|
|
|
/**
|
|
* @var int d The value that affects the positioning of
|
|
* pixels along the x axis when scaling or rotating an image.
|
|
*/
|
|
this.d = d || 1;
|
|
|
|
/**
|
|
* @var int tx The distance by which to translate each point
|
|
* long the x axis.
|
|
*/
|
|
this.tx = tx || 0;
|
|
|
|
/**
|
|
* @var int ty The distance by which to translate each point
|
|
* along the y axis.
|
|
*/
|
|
this.ty = ty || 0;
|
|
|
|
};
|
|
|
|
/**
|
|
* @return {Matrix} A clone of this Matrix.
|
|
*/
|
|
Matrix.prototype.clone = function(){
|
|
|
|
return new Matrix(this.a, this.b, this.c, this.d, this.tx, this.ty);
|
|
|
|
};
|
|
|
|
/**
|
|
* Concatenates a matrix with the current matrix, effectively combining the
|
|
* geometric effects of the two.
|
|
*
|
|
* http://en.wikipedia.org/wiki/Matrix_multiplication
|
|
*
|
|
* @link {http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html#concat()}
|
|
*
|
|
* @param {Matrix} m The matrix to contat with this matrix.
|
|
*
|
|
* @return void
|
|
*/
|
|
Matrix.prototype.concat = function(m) {
|
|
|
|
var r = new Matrix();
|
|
|
|
// 1,1
|
|
// (a,c,tx) * (a,b,0)
|
|
r.a = (this.a * m.a) + (this.c * m.b);
|
|
|
|
// 1,2
|
|
// (a,c,tx) * (c,d,0)
|
|
r.c = (this.a * m.c) + (this.c * m.d);
|
|
|
|
// 1,3
|
|
// (a,c,tx) * (tx,ty,1)
|
|
r.tx = (this.a * m.tx) + (this.c * m.ty) + this.tx;
|
|
|
|
// 2,1
|
|
// (b,d,ty) * (a,b,0)
|
|
r.b = (this.b * m.a) + (this.d * m.b);
|
|
|
|
// 2,2
|
|
//(b,d,ty) * (c,d,0)
|
|
r.d = (this.b * m.c) + (this.d * m.d);
|
|
|
|
// 2,3
|
|
// (b,d,ty) * (tx,ty,1);
|
|
r.ty = (this.b * m.tx) + (this.d * m.ty) + this.ty;
|
|
|
|
this.a = r.a;
|
|
this.b = r.b;
|
|
this.c = r.c;
|
|
this.d = r.d;
|
|
this.tx = r.tx;
|
|
this.ty = r.ty;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* Includes parameters for scaling, rotation, and translation.
|
|
* createBox(scaleX:Number, scaleY:Number, rotation:Number = 0, tx:Number = 0,
|
|
* ty:Number = 0):void
|
|
*
|
|
* @param float scaleX
|
|
* @param float scaleY
|
|
* @param float rotation
|
|
* @param float tx
|
|
* @param float ty
|
|
*
|
|
* @return void
|
|
*/
|
|
Matrix.prototype.createBox = function(scaleX, scaleY, rotation, tx, ty){
|
|
this.identity();
|
|
this.rotate(rotation);
|
|
this.scale(scaleX, scaleY);
|
|
this.translate(tx, ty);
|
|
};
|
|
|
|
/**
|
|
* Creates the specific style of matrix expected by the beginGradientFill() and
|
|
* lineGradientStyle() methods of the Graphics class.
|
|
* createGradientBox(width:Number, height:Number, rotation:Number = 0, tx:Number =
|
|
* 0, ty:Number = 0):void
|
|
*
|
|
* @link {http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html#createGradientBox()}
|
|
*
|
|
* @param float width
|
|
* @param float height
|
|
* @param float rotation
|
|
* @param float tx
|
|
* @param float ty
|
|
*
|
|
* @return void
|
|
*/
|
|
Matrix.prototype.createGradientBox = function(width, height,
|
|
rotation, tx, ty){
|
|
|
|
// does the graphics class have to be finished first? thinking yes.
|
|
|
|
};
|
|
|
|
/**
|
|
* Given a point in the pretransform coordinate space, returns the coordinates
|
|
* of that point after the transformation occurs.
|
|
* deltaTransformPoint(point:Point):Point
|
|
*
|
|
* @link {http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html#deltaTransformPoint()}
|
|
*
|
|
* @param {Point} point
|
|
*
|
|
* @return {Point}
|
|
*/
|
|
Matrix.prototype.deltaTransformPoint = function(point){
|
|
|
|
var point = {
|
|
x : ( (this.a * point.x) +
|
|
(this.c * point.y) ),
|
|
y : ( (this.b * point.x) +
|
|
(this.d * point.y) )
|
|
};
|
|
|
|
return new Point(point.x, point.y);
|
|
|
|
|
|
};
|
|
|
|
/**
|
|
* Sets each matrix property to a value that causes a null transformation.
|
|
* identity():void
|
|
*
|
|
* @link {http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html#identity()}
|
|
*
|
|
* @return void
|
|
*/
|
|
Matrix.prototype.identity = function(){
|
|
|
|
// 1 0 0
|
|
// 0 1 0
|
|
// 0 0 1
|
|
|
|
this.a = 1;
|
|
this.b = 0;
|
|
this.c = 0;
|
|
this.d = 1;
|
|
this.tx = 0;
|
|
this.ty = 0;
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* Performs the opposite transformation of the original matrix. invert():void
|
|
*
|
|
* Math below taken straight from Wikipedia:
|
|
* http://en.wikipedia.org/wiki/Matrix_inversion#Methods_of_matrix_inversion
|
|
*
|
|
* @link {http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html#invert()}
|
|
*
|
|
* @return void
|
|
*/
|
|
Matrix.prototype.invert = function(){
|
|
|
|
var determinant = this.a * this.d - this.b * this.c;
|
|
return new Matrix(
|
|
this.d / determinant,
|
|
-this.b / determinant,
|
|
-this.c / determinant,
|
|
this.a / determinant,
|
|
(this.c * this.ty - this.d * this.tx) / determinant,
|
|
(this.b * this.tx - this.a * this.ty) / determinant
|
|
);
|
|
|
|
// AA-1 = A-1A = I
|
|
// Flash Matrix -> Wikipedia Matrix -> Inverted Matrix
|
|
// a c tx -> a b c -> A D G
|
|
// b d ty -> d e f -> B E H
|
|
// 0 0 1 -> g h k -> C F K
|
|
|
|
// Notice we do not need F or K
|
|
// C is necessary to test for invertability
|
|
var A = (this.d * 1) - (this.ty * 0),
|
|
B = (this.ty * 0) - (1 * this.b),
|
|
C = (this.b * 0) - (this.d_ * 0),
|
|
D = (this.tx * 0) - (this.c * 1),
|
|
E = (this.a * 1) - (this.tx * 0),
|
|
G = (this.c * this.ty) - (this.tx * this.d),
|
|
H = (this.tx * this.b) - (this.a * this.ty);
|
|
|
|
// Z = a(ek − fh) + b(fg − kd) + c(dh − eg)
|
|
// Test to see if this Matrix is invertable
|
|
if(((this.a * A) + (this.c * B) + (this.tx * C)) <= 0) { // not invertable
|
|
return null;
|
|
}
|
|
|
|
return new Matrix(A, B, D, E, G, H);
|
|
|
|
};
|
|
|
|
/**
|
|
* Applies a rotation transformation to the Matrix object.
|
|
* rotate(angle:Number):void
|
|
*
|
|
* http://en.wikipedia.org/wiki/Rotation_matrix
|
|
*
|
|
* @link {http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html#rotate()}
|
|
*
|
|
* @return void
|
|
*
|
|
*/
|
|
Matrix.prototype.rotate = function(r){
|
|
|
|
var m = new Matrix(Math.cos(r), Math.sin(r), -Math.sin(r), Math.cos(r), 0, 0);
|
|
this.concat(m);
|
|
|
|
};
|
|
|
|
Matrix.prototype.getRotation = function(degrees) {
|
|
var scale = Math.sqrt(this.a*this.a + this.b*this.b);
|
|
|
|
// arc sin, convert from radians to degrees, round
|
|
// DO NOT USE: see update below
|
|
var sin = this.b/scale;
|
|
|
|
var radians = Math.asin(sin);
|
|
|
|
if(degrees) {
|
|
return Math.round(radians * (180/Math.PI));
|
|
}
|
|
return radians;
|
|
};
|
|
|
|
Matrix.prototype.degToRad = function(deg) {
|
|
return deg * (Math.PI / 180);
|
|
};
|
|
|
|
Matrix.prototype.radToDeg = function(rad) {
|
|
return rad * (180/Math.PI);
|
|
};
|
|
|
|
/**
|
|
* Applies a scaling transformation to the matrix. scale(sx:Number,
|
|
* sy:Number):void
|
|
*
|
|
* @link http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html#scale()}
|
|
*
|
|
* @param float sx
|
|
* @param float sy
|
|
*
|
|
* @return void
|
|
*
|
|
*/
|
|
Matrix.prototype.scale = function(sx, sy){
|
|
|
|
var m = new Matrix(sx, 0, 0, sy, 0, 0);
|
|
this.concat(m);
|
|
|
|
};
|
|
|
|
/**
|
|
* Returns a text value listing the properties of the Matrix object.
|
|
* toString():String
|
|
*
|
|
* @link {http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html#toString()}
|
|
*
|
|
* @return string
|
|
*
|
|
* TODO: need to test this override...see if it works.
|
|
*/
|
|
Matrix.prototype.toString = function(){
|
|
|
|
return this.a + ' ' + this.c + ' ' + this.tx + '\n' +
|
|
this.b + ' ' + this.d + ' ' + this.ty;
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* Returns the result of applying the geometric transformation represented by
|
|
* the Matrix object to the specified point. transformPoint(point:Point):Point
|
|
*
|
|
* Converts a local point to a world (matrix) point.
|
|
*
|
|
* @link {http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html#transformPoint()}
|
|
*
|
|
* @param {Point} point
|
|
*
|
|
* @return {Point}
|
|
*
|
|
*/
|
|
Matrix.prototype.transformPoint = function(point){
|
|
|
|
// WARNING: DOUBLE CHECK MATH!! been awhile since knocking these out
|
|
// in my linear algebra class
|
|
var point = {
|
|
x : ( (this.a * point.x) +
|
|
(this.c * point.y) +
|
|
(this.tx) ),
|
|
y : ( (this.b * point.x) +
|
|
(this.d * point.y) +
|
|
(this.ty) )
|
|
};
|
|
|
|
return new Point(point.x, point.y);
|
|
|
|
};
|
|
|
|
/**
|
|
* Translates the matrix along the x and y axes, as specified by the dx and dy
|
|
* parameters. translate(dx:Number, dy:Number):void
|
|
*
|
|
* @link {http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html#translate()}
|
|
*
|
|
* @param float dx
|
|
* @param float dy
|
|
*
|
|
* @return void
|
|
*
|
|
*/
|
|
Matrix.prototype.translate = function(dx, dy){
|
|
|
|
this.tx += dx;
|
|
this.ty += dy;
|
|
|
|
};
|
|
|
|
Matrix.prototype.toMatrixString = function () {
|
|
return 'matrix(' + this.a.toFixed(20) + ', ' +
|
|
this.b.toFixed(20) + ', ' +
|
|
this.c.toFixed(20) + ', ' +
|
|
this.d.toFixed(20) + ', ' +
|
|
this.tx.toFixed(20) + ', ' +
|
|
this.ty.toFixed(20) + ')';
|
|
};
|
|
|
|
Matrix.initWithElem = function ($elem) {
|
|
var tr = $elem.css('-webkit-transform');
|
|
var m = new Matrix();
|
|
|
|
try {
|
|
var v = tr.split('(')[1].split(')')[0].split(',');
|
|
m = new Matrix(Number(v[0]),
|
|
Number(v[1]),
|
|
Number(v[2]),
|
|
Number(v[3]),
|
|
Number(v[4]),
|
|
Number(v[5]));
|
|
} catch (e) {}
|
|
|
|
return m;
|
|
}; |