API Docs for: 1.4.0
Show:

File: src\geom\Matrix.ts

/**
*  
* @module Kiwi
* @submodule Geom
*/

module Kiwi.Geom {

	/**
	* Represents a 2d transformation matrix. This can be used to map points
	* between different coordinate spaces. Matrices are used by Transform
	* objects to represent translation, scale and rotation transformations,
	* and to determine where objects are in world space or camera space.
	* Objects such as entities and groups may be nested, and their associated
	* transforms may represent how they are scaled, translated and rotated
	* relative to a parent transform. By concatenating an object's
	* transformation matrix with its ancestors matrices, it is possible to
	* determine the absolute position of the object in world space.
	* See
	* http://en.wikipedia.org/wiki/Transformation_matrix#Examples_in_2D_graphics
	* for an in depth discussion of 2d tranformation matrices.
	* 
	* @class Matrix
	* @namespace Kiwi.Geom
	* @constructor
	* @param [a=1] {Number}  position 0,0 of the matrix,
	*	affects scaling and rotation.
	* @param [b=0] {Number}  position 0,1 of the matrix,
	*	affects scaling and rotation.
	* @param [c=0] {Number}  position 1,0 of the matrix,
	*	affects scaling and rotation.
	* @param [d=1] {Number}  position 1,1 of the matrix,
	*	affects scaling and rotation.
	* @param [tx=0] {Number}  position 2,0 of the matrix,
	*	affects translation on x axis.
	* @param [ty=0] {Number}  position 2,1 of the matrix,
	*	affects translation on y axis.
	* @return (Object) This object.
	* 
	*/
	export class Matrix {

		constructor(a: number = 1, b: number = 0, c: number = 0, d: number = 1, tx: number = 0, ty: number = 0) {

			this.setTo(a, b, c, d, tx, ty);

		}

		/**
		* The type of object this is.
		* @method objType
		* @return {String} "Matrix"
		* @public
		*/
		public objType() {
			return "Matrix";
		}

		/**
		* Position 0,0 of the matrix, affects scaling and rotation
		* @property a
		* @type Number
		* @default 1
		* @public
		*/
		public a: number = 1;

		/**
		* Position 0,1 of the matrix, affects scaling and rotation.
		* @property b
		* @type Number
		* @default 0
		* @public
		*/
		public b: number = 0;

		/**
		* Position 1,0 of the matrix, affects scaling and rotation.
		* @property c
		* @type Number
		* @default 0
		* @public
		*/
		public c: number = 0;

		/**
		* Position 1,1 of the matrix, affects scaling and rotation.
		* @property d
		* @type Number
		* @default 1
		* @public
		*/
		public d: number = 1;

		/**
		* Position 2,0 of the matrix, affects translation on x axis.
		* @property tx
		* @type Number
		* @default 0
		* @public
		*/
		public tx: number = 0;

		/**
		* Position 2,1 of the matrix, affects translation on y axis.
		* @property ty
		* @type Number
		* @default 0
		* @public
		*/
		public ty: number = 0;

		/**
		* Set all matrix values 
		* @method setTo
		* @param [a=1] {Number} position 0,0 of the matrix, affects scaling and rotation.
		* @param [b=0] {Number} position 0,1 of the matrix, affects scaling and rotation.
		* @param [c=0] {Number} position 1,0 of the matrix, affects scaling and rotation.
		* @param [d=1] {Number} position 1,1 of the matrix, affects scaling and rotation.
		* @param [tx=0] {Number} position 2,0 of the matrix, affects translation on x axis.
		* @param [ty=0] {Number} position 2,1 of the matrix, affects translation on y axis.
		* @return {Kiwi.Geom.Matrix} This object.
		* @public
		*/
		public setTo(a: number = 1, b: number = 0, c: number = 0, d: number = 1, tx: number = 0, ty: number = 0): Matrix {

			this.a = a;
			this.b = b;
			this.c = c;
			this.d = d;
			this.tx = tx;
			this.ty = ty;

			return this;

		}

		/**
		* Set matrix values from transform values
		* @method setFromTransform
		* @param tx {Number} Translation on x axis.
		* @param ty {Number} Translation on y axis.
		* @param scaleX {Number} scaleX. Scale on x axis.
		* @param scaleY {Number} scaleY. Scale on y axis.
		* @param rotation {Number} rotation. 
		* @return {Kiwi.Geom.Matrix} This object.
		* @public
		*/
		  public setFromTransform(tx: number, ty: number, scaleX: number, scaleY: number, rotation: number) {
			this.identity();
			var cos = Math.cos(rotation);
			var sin = Math.sin(rotation);

			this.append(cos * scaleX, sin * scaleX, -sin * scaleY, cos * scaleY, tx, ty);

			return this;
		}

		/**
		* Set matrix values from transform values, with rotation point data included
		* @method setFromOffsetTransform
		* @param tx {Number} tx. Translation on x axis.
		* @param ty {Number} ty. Translation on y axis.
		* @param scaleX {Number} scaleX. Scale on x axis.
		* @param scaleY {Number} scaleY. Scale on y axis.
		* @param rotation {Number} rotation. 
		* @param rotPointX {Number} Rotation point offset on x axis.
		* @param rotPointY {Number} Rotation point offset on y axis.
		* @return {Kiwi.Geom.Matrix} This object.
		* @public
		* @since 1.0.1
		*/
		  public setFromOffsetTransform(tx: number, ty: number, scaleX: number, scaleY: number, rotation: number, rotPointX: number, rotPointY: number) {
			this.identity();
			var cos = Math.cos(rotation);
			var sin = Math.sin(rotation);

			this.append(cos * scaleX, sin * scaleX, -sin * scaleY, cos * scaleY, tx + rotPointX, ty + rotPointY);

			return this;
		}

		/**
		* Prepend values to this matrix, paramters supplied individually.
		* @method prepend
		* @param [a=1]{Number} position 0,0 of the matrix, affects scaling and rotation.
		* @param [b=0]{Number} position 0,1 of the matrix, affects scaling and rotation.
		* @param [c=0]{Number} position 1,0 of the matrix, affects scaling and rotation.
		* @param [d=0]{Number} position 1,1 of the matrix, affects scaling and rotation.
		* @param [tx=0]{Number} position 2,0 of the matrix, affects translation on x axis.
		* @param [ty=0]{Number} position 2,1 of the matrix, affects translation on y axis.
		* @return {Kiwi.Geom.Matrix} This object.
		* @public
		*/
		public prepend(a: number = 1, b: number = 0, c: number = 0, d: number = 1, tx: number = 0, ty: number = 0): Matrix {
			var tx1 = this.tx;
			var a1 = this.a;
			var c1 = this.c;

			this.a = a1 * a + this.b * c;
			this.b = a1 * b + this.b * d;
			this.c = c1 * a + this.d * c;
			this.d = c1 * b + this.d * d;

			this.tx = tx1 * a + this.ty * c + tx;
			this.ty = tx1 * b + this.ty * d + ty;
			return this;

		}

		/**
		* Prepend a matrix to this matrix.
		* @method prependMatrix
		* @param m {Kiwi.Geom.Matrix} The matrix to prepend.
		* @return {Kiwi.Geom.Matrix} This object.
		* @public
		*/
		public prependMatrix(m: Matrix): Matrix {
			var tx1 = this.tx;
			var a1 = this.a;
			var c1 = this.c;

			this.a = a1 * m.a + this.b * m.c;
			this.b = a1 * m.b + this.b * m.d;
			this.c = c1 * m.a + this.d * m.c;
			this.d = c1 * m.b + this.d * m.d;

			this.tx = tx1 * m.a + this.ty * m.c + m.tx;
			this.ty = tx1 * m.b + this.ty * m.d + m.ty;
			return this;

		}

		/**
		* Append values to this matrix, parameters supplied individually.
		* @method append
		* @param [a=1]{Number} position 0,0 of the matrix, affects scaling and rotation.
		* @param [b=0]{Number} position 0,1 of the matrix, affects scaling and rotation.
		* @param [c=0]{Number} position 1,0 of the matrix, affects scaling and rotation.
		* @param [d=1]{Number} position 1,1 of the matrix, affects scaling and rotation.
		* @param [tx=0]{Number} position 2,0 of the matrix, affects translation on x axis.
		* @param [ty=0]{Number} position 2,1 of the matrix, affects translation on y axis.
		* @return {Kiwi.Geom.Matrix} This object.
		* @public
		*/
		public append(a: number = 1, b: number = 0, c: number = 0, d: number = 1, tx: number = 0, ty: number = 0): Matrix {
			var a1 = this.a;
			var b1 = this.b;
			var c1 = this.c;
			var d1 = this.d;

			this.a = a * a1 + b * c1;
			this.b = a * b1 + b * d1;
			this.c = c * a1 + d * c1;
			this.d = c * b1 + d * d1;
			this.tx = tx * a1 + ty * c1 + this.tx;
			this.ty = tx * b1 + ty * d1 + this.ty;
			return this;
		}

		/**
		* Append a matrix to this matrix.
		* @method appendMatrix
		* @param m {Kiwi.Geom.Matrix} The matrix to append.
		* @return {Kiwi.Geom.Matrix} This object.
		* @public
		*/
		public appendMatrix(m: Matrix): Matrix {
			var a1 = this.a;
			var b1 = this.b;
			var c1 = this.c;
			var d1 = this.d;

			this.a = m.a * a1 + m.b * c1;
			this.b = m.a * b1 + m.b * d1;
			this.c = m.c * a1 + m.d * c1;
			this.d = m.c * b1 + m.d * d1;
			this.tx = m.tx * a1 + m.ty * c1 + this.tx;
			this.ty = m.tx * b1 + m.ty * d1 + this.ty;
			return this;
		}

		/**
		* Set the tx and ty elements of the matrix.
		* @method setPosition
		* @param x {Number} Translation on x axis.
		* @param y {Number} Translation on y axis.
		* @return {Kiwi.Geom.Matrix} This object.
		* @public
		*/
		public setPosition(x: number, y: number): Matrix {
			this.tx = x;
			this.ty = y;
			return this;
		}

		/**
		* Set the tx and ty elements of the matrix from an object with x and y properties.
		* @method setPositionPoint
		* @param p {Number} The object from which to copy the x and y properties from.
		* @return {Kiwi.Geom.Matrix} This object.
		* @public
		*/
		public setPositionPoint(p: any): Matrix {
			this.tx = p.x;
			this.ty = p.y;
			return this
		}

		/**
		* Get the x and y position of the matrix as an object with x and y properties
		* @method getPosition
		* @return {Kiwi.Geom.Point} An object constructed from a literal with x and y properties.
		* @public
		*/
		public getPosition(output: Kiwi.Geom.Point = new Kiwi.Geom.Point): Kiwi.Geom.Point {
			return output.setTo(this.tx, this.ty);
		}

		/**
		* Set the matrix to the identity matrix - when appending or prepending this matrix to another there will be no change in the resulting matrix
		* @method identity
		* @return {Kiwi.Geom.Matrix} This object.
		* @public
		*/
		public identity(): Matrix {
			this.a = 1;
			this.b = 0;
			this.c = 0;
			this.d = 1;
			this.tx = 0;
			this.ty = 0;
			return this;
		}

		/**
		* Rotate the matrix by "radians" degrees
		* @method rotate
		* @param radians {Number} The angle (in radians) to rotate this matrix by. 
		* @return {Kiwi.Geom.Matrix} This object.
		* @public
		*/
		public rotate(radians: number): Matrix {
			var cos = Math.cos(radians);
			var sin = Math.sin(radians);

			var a1 = this.a;
			var c1 = this.c;
			var tx1 = this.tx;

			this.a = a1 * cos - this.b * sin;
			this.b = a1 * sin + this.b * cos;
			this.c = c1 * cos - this.d * sin;
			this.d = c1 * sin + this.d * cos;
			this.tx = tx1 * cos - this.ty * sin;
			this.ty = tx1 * sin + this.ty * cos;
			return this;

		}

		/**
		* Translate the matrix by the amount passed.
		* 
		* @method translate
		* @param tx {Number} The amount to translate on the x axis.
		* @param ty {Number} The amount to translate on the y axis.
		* @return {Kiwi.Geom.Matrix} This object.
		* @public
		*/
		public translate(tx: number, ty: number): Matrix {
			this.tx += tx;
			this.ty += ty;
			return this;
		}

		/**
		* Scales the matrix by the amount passed.
		*
		* @method scale
		* @param scaleX {Number} The amount to scale on the x axis.
		* @param scaleY {Number} The amount to scale on the y axis.
		* @return {Kiwi.Geom.Matrix} This object.
		* @public
		*/
		public scale(scaleX: number, scaleY: number): Matrix {
			this.a *= scaleX;
			this.d *= scaleY;
			return this;
		}

		/**
		* Apply this matrix to a an object with x and y properties representing a point and return the transformed point.
		* @method transformPoint
		* @param pt {Object} The point to be translated.
		* @return {Kiwi.Geom.Matrix} This object.
		* @public
		*/
		public transformPoint(pt: any) {
			var x = pt.x;
			var y = pt.y
			pt.x = this.a * x + this.c * y + this.tx;
			pt.y = this.b * x + this.d * y + this.ty;
			return pt;
		}

		/**
		* Invert this matrix so that it represents the opposite of its orginal tranformaation.
		* @method invert
		* @return {Kiwi.Geom.Matrix} This object.
		* @public
		*/
		public invert(): Matrix {
			var a1 = this.a;
			var b1 = this.b;
			var c1 = this.c;
			var d1 = this.d;
			var tx1 = this.tx;
			var n = a1 * d1 - b1 * c1;

			this.a = d1 / n;
			this.b = -b1 / n;
			this.c = -c1 / n;
			this.d = a1 / n;
			this.tx = (c1 * this.ty - d1 * tx1) / n;
			this.ty = -(a1 * this.ty - b1 * tx1) / n;
			return this;
		}

		/**
		* Copy another matrix to this matrix.
		* @method copyFrom
		* @param m {Kiwi.Geom.Matrix} The matrixto be copied from.
		* @return {Kiwi.Geom.Matrix} This object.
		* @public
		*/
		public copyFrom(m: Matrix): Matrix {
			this.a = m.a;
			this.b = m.b;
			this.c = m.c;
			this.d = m.d;
			this.tx = m.tx;
			this.ty = m.ty;

			return this;
		}

		/**
		* Copy this matrix to another matrix.
		* @method copyTo
		* @param m {Kiwi.Geom.Matrix} The matrix to copy to.
		* @return {Kiwi.Geom.Matrix} This object.
		* @public
		*/
		public copyTo(m: Matrix): Matrix {
			m.a = this.a;
			m.b = this.b;
			m.c = this.c;
			m.d = this.d;
			m.tx = this.tx;
			m.ty = this.ty;
			return this;
		}

		/**
		* Clone this matrix and returns a new Matrix object.
		* @method clone
		* @return {Kiwi.Geom.Matrix} 
		* @public
		*/
		public clone(): Matrix {
			return new Kiwi.Geom.Matrix(this.a, this.b, this.c, this.d, this.tx, this.ty);
		}

		/**
		* Returns a string representation of this object.
		* @method toString
		* @return {string} A string representation of the instance.
		* @public
		*/
		public get toString(): string {

			return "[{Matrix (a=" + this.a + " b=" + this.b + " c=" + this.c + " d=" + this.d + " tx=" + this.tx + " ty=" + this.ty + ")}]";

		}

		/**
		* Check whether this matrix equals another matrix.
		*
		* @method equals
		* @param matrix {Kiwi.Geom.Matrix}
		* @return boolean
		* @public
		*/
		public equals( matrix: Matrix ): boolean {

			return (
					this.a === matrix.a &&
					this.b === matrix.b &&
					this.c === matrix.c &&
					this.d === matrix.d &&
					this.tx === matrix.tx &&
					this.ty === matrix.ty );
		}

	}

}