diff --git a/editor/math.js b/editor/math.js index b2d766c2..73913ff9 100644 --- a/editor/math.js +++ b/editor/math.js @@ -11,6 +11,14 @@ // Dependencies: // None. + +/** +* @typedef AngleCoord45 +* @type {object} +* @property {number} x - The angle-snapped x value +* @property {number} y - The angle-snapped y value +* @property {number} a - The angle at which to snap +*/ (function() {'use strict'; @@ -24,44 +32,37 @@ var NEAR_ZERO = 1e-14; // Throw away SVGSVGElement used for creating matrices/transforms. var svg = document.createElementNS(svgedit.NS.SVG, 'svg'); -// Function: svgedit.math.transformPoint -// A (hopefully) quicker function to transform a point by a matrix -// (this function avoids any DOM calls and just does the math) -// -// Parameters: -// x - Float representing the x coordinate -// y - Float representing the y coordinate -// m - Matrix object to transform the point with -// Returns a x,y object representing the transformed point -svgedit.math.transformPoint = function(x, y, m) { +/** + * A (hopefully) quicker function to transform a point by a matrix + * (this function avoids any DOM calls and just does the math) + * @param {number} x - Float representing the x coordinate + * @param {number} y - Float representing the y coordinate + * @param {SVGMatrix} m - Matrix object to transform the point with + * @returns {object} An x, y object representing the transformed point +*/ +svgedit.math.transformPoint = function (x, y, m) { return { x: m.a * x + m.c * y + m.e, y: m.b * x + m.d * y + m.f}; }; -// Function: svgedit.math.isIdentity -// Helper function to check if the matrix performs no actual transform -// (i.e. exists for identity purposes) -// -// Parameters: -// m - The matrix object to check -// -// Returns: -// Boolean indicating whether or not the matrix is 1,0,0,1,0,0 -svgedit.math.isIdentity = function(m) { +/** + * Helper function to check if the matrix performs no actual transform + * (i.e. exists for identity purposes) + * @param {SVGMatrix} m - The matrix object to check + * @returns {boolean} Indicates whether or not the matrix is 1,0,0,1,0,0 +*/ +svgedit.math.isIdentity = function (m) { return (m.a === 1 && m.b === 0 && m.c === 0 && m.d === 1 && m.e === 0 && m.f === 0); }; -// Function: svgedit.math.matrixMultiply -// This function tries to return a SVGMatrix that is the multiplication m1*m2. -// We also round to zero when it's near zero -// -// Parameters: -// >= 2 Matrix objects to multiply -// -// Returns: -// The matrix object resulting from the calculation -svgedit.math.matrixMultiply = function() { +/** + * This function tries to return a SVGMatrix that is the multiplication m1*m2. + * We also round to zero when it's near zero + * @param {...SVGMatrix} matr - Two or more matrix objects to multiply + * @returns {SVGMatrix} The matrix object resulting from the calculation +*/ +svgedit.math.matrixMultiply = function (matr) { var args = arguments, i = args.length, m = args[i-1]; while (i-- > 1) { @@ -78,15 +79,12 @@ svgedit.math.matrixMultiply = function() { return m; }; -// Function: svgedit.math.hasMatrixTransform -// See if the given transformlist includes a non-indentity matrix transform -// -// Parameters: -// tlist - The transformlist to check -// -// Returns: -// Boolean on whether or not a matrix transform was found -svgedit.math.hasMatrixTransform = function(tlist) { +/** + * See if the given transformlist includes a non-indentity matrix transform + * @param {object} [tlist] - The transformlist to check + * @returns {boolean} Whether or not a matrix transform was found +*/ +svgedit.math.hasMatrixTransform = function (tlist) { if (!tlist) {return false;} var num = tlist.numberOfItems; while (num--) { @@ -96,28 +94,25 @@ svgedit.math.hasMatrixTransform = function(tlist) { return false; }; -// Function: svgedit.math.transformBox -// Transforms a rectangle based on the given matrix -// -// Parameters: -// l - Float with the box's left coordinate -// t - Float with the box's top coordinate -// w - Float with the box width -// h - Float with the box height -// m - Matrix object to transform the box by -// -// Returns: -// An object with the following values: -// * tl - The top left coordinate (x,y object) -// * tr - The top right coordinate (x,y object) -// * bl - The bottom left coordinate (x,y object) -// * br - The bottom right coordinate (x,y object) -// * aabox - Object with the following values: -// * Float with the axis-aligned x coordinate -// * Float with the axis-aligned y coordinate -// * Float with the axis-aligned width coordinate -// * Float with the axis-aligned height coordinate -svgedit.math.transformBox = function(l, t, w, h, m) { +/** + * Transforms a rectangle based on the given matrix + * @param {number} l - Float with the box's left coordinate + * @param {number} t - Float with the box's top coordinate + * @param {number} w - Float with the box width + * @param {number} h - Float with the box height + * @param {SVGMatrix} m - Matrix object to transform the box by + * @returns {object} An object with the following values: + * tl - The top left coordinate (x,y object) + * tr - The top right coordinate (x,y object) + * bl - The bottom left coordinate (x,y object) + * br - The bottom right coordinate (x,y object) + * aabox - Object with the following values: + * x - Float with the axis-aligned x coordinate + * y - Float with the axis-aligned y coordinate + * width - Float with the axis-aligned width coordinate + * height - Float with the axis-aligned height coordinate +*/ +svgedit.math.transformBox = function (l, t, w, h, m) { var transformPoint = svgedit.math.transformPoint, tl = transformPoint(l, t, m), @@ -144,20 +139,18 @@ svgedit.math.transformBox = function(l, t, w, h, m) { }; }; -// Function: svgedit.math.transformListToTransform -// This returns a single matrix Transform for a given Transform List -// (this is the equivalent of SVGTransformList.consolidate() but unlike -// that method, this one does not modify the actual SVGTransformList) -// This function is very liberal with its min,max arguments -// -// Parameters: -// tlist - The transformlist object -// min - Optional integer indicating start transform position -// max - Optional integer indicating end transform position -// -// Returns: -// A single matrix transform object -svgedit.math.transformListToTransform = function(tlist, min, max) { +/** + * This returns a single matrix Transform for a given Transform List + * (this is the equivalent of SVGTransformList.consolidate() but unlike + * that method, this one does not modify the actual SVGTransformList) + * This function is very liberal with its min, max arguments + * @param {object} tlist - The transformlist object + * @param {integer} [min=0] - Optional integer indicating start transform position + * @param {integer} [max] - Optional integer indicating end transform position; + * defaults to one less than the tlist's numberOfItems + * @returns {object} A single matrix transform object +*/ +svgedit.math.transformListToTransform = function (tlist, min, max) { if (tlist == null) { // Or should tlist = null have been prevented before this? return svg.createSVGTransformFromMatrix(svg.createSVGMatrix()); @@ -180,42 +173,33 @@ svgedit.math.transformListToTransform = function(tlist, min, max) { }; -// Function: svgedit.math.getMatrix -// Get the matrix object for a given element -// -// Parameters: -// elem - The DOM element to check -// -// Returns: -// The matrix object associated with the element's transformlist -svgedit.math.getMatrix = function(elem) { +/** + * Get the matrix object for a given element + * @param {Element} elem - The DOM element to check + * @returns {SVGMatrix} The matrix object associated with the element's transformlist +*/ +svgedit.math.getMatrix = function (elem) { var tlist = svgedit.transformlist.getTransformList(elem); return svgedit.math.transformListToTransform(tlist).matrix; }; -// Function: svgedit.math.snapToAngle -// Returns a 45 degree angle coordinate associated with the two given -// coordinates -// -// Parameters: -// x1 - First coordinate's x value -// x2 - Second coordinate's x value -// y1 - First coordinate's y value -// y2 - Second coordinate's y value -// -// Returns: -// Object with the following values: -// x - The angle-snapped x value -// y - The angle-snapped y value -// snapangle - The angle at which to snap -svgedit.math.snapToAngle = function(x1, y1, x2, y2) { - var snap = Math.PI/4; // 45 degrees +/** + * Returns a 45 degree angle coordinate associated with the two given + * coordinates + * @param {number} x1 - First coordinate's x value + * @param {number} x2 - Second coordinate's x value + * @param {number} y1 - First coordinate's y value + * @param {number} y2 - Second coordinate's y value + * @returns {AngleCoord45} +*/ +svgedit.math.snapToAngle = function (x1, y1, x2, y2) { + var snap = Math.PI / 4; // 45 degrees var dx = x2 - x1; var dy = y2 - y1; var angle = Math.atan2(dy, dx); var dist = Math.sqrt(dx * dx + dy * dy); - var snapangle = Math.round(angle/snap) * snap; + var snapangle = Math.round(angle / snap) * snap; return { x: x1 + dist * Math.cos(snapangle), @@ -225,20 +209,17 @@ svgedit.math.snapToAngle = function(x1, y1, x2, y2) { }; -// Function: rectsIntersect -// Check if two rectangles (BBoxes objects) intersect each other -// -// Paramaters: -// r1 - The first BBox-like object -// r2 - The second BBox-like object -// -// Returns: -// Boolean that's true if rectangles intersect -svgedit.math.rectsIntersect = function(r1, r2) { - return r2.x < (r1.x+r1.width) && - (r2.x+r2.width) > r1.x && - r2.y < (r1.y+r1.height) && - (r2.y+r2.height) > r1.y; +/** + * Check if two rectangles (BBoxes objects) intersect each other + * @param {SVGRect} r1 - The first BBox-like object + * @param {SVGRect} r2 - The second BBox-like object + * @returns {boolean} True if rectangles intersect + */ +svgedit.math.rectsIntersect = function (r1, r2) { + return r2.x < (r1.x + r1.width) && + (r2.x + r2.width) > r1.x && + r2.y < (r1.y + r1.height) && + (r2.y + r2.height) > r1.y; }; -}()); \ No newline at end of file +}());