Comparing version 1.0.1 to 1.2.0
@@ -81,6 +81,8 @@ (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
// For each moved touch. | ||
pointers[id].rx = x; | ||
pointers[id].ry = y; | ||
updateTransform(); | ||
this.emit('update', totalTransform); | ||
if (pointers.hasOwnProperty(id)) { | ||
pointers[id].rx = x; | ||
pointers[id].ry = y; | ||
updateTransform(); | ||
this.emit('update', totalTransform); | ||
} | ||
}; | ||
@@ -282,2 +284,44 @@ | ||
exports.create = function (scale, rotation, tx, ty) { | ||
// Create a nudged.Transform instance by using more meaningful parameters | ||
// than directly calling 'new nudged.Transform(...)' | ||
// | ||
// Parameters: | ||
// scale | ||
// number, the scaling factor | ||
// rotation | ||
// number, rotation in radians from positive x axis towards pos. y axis. | ||
// tx | ||
// translation toward pos. x | ||
// ty | ||
// translation toward pos. y | ||
if (typeof scale !== 'number') { scale = 1; } | ||
if (typeof rotation !== 'number') { rotation = 0; } | ||
if (typeof tx !== 'number') { tx = 0; } | ||
if (typeof ty !== 'number') { ty = 0; } | ||
var s = scale * Math.cos(rotation); | ||
var r = scale * Math.sin(rotation); | ||
return new exports.Transform(s, r, tx, ty); | ||
}; | ||
exports.createFromArray = function (arr) { | ||
// Create a nudged.Transform instance from an array that was | ||
// previously created with nudged.Transform#toArray(). | ||
// | ||
// Together with nudged.Transform#toArray(), this method makes an easy | ||
// serialization and deserialization to and from JSON possible. | ||
// | ||
// Parameter: | ||
// arr | ||
// array with four elements | ||
var s = arr[0]; | ||
var r = arr[1]; | ||
var tx = arr[2]; | ||
var ty = arr[3]; | ||
return new exports.Transform(s, r, tx, ty); | ||
}; | ||
exports.estimate = function (type, domain, range, pivot) { | ||
@@ -314,18 +358,2 @@ // Parameter | ||
this.transform = function (p) { | ||
// p | ||
// point [x, y] or array of points [[x1,y1], [x2, y2], ...] | ||
if (typeof p[0] === 'number') { | ||
// Single point | ||
return [s * p[0] - r * p[1] + tx, r * p[0] + s * p[1] + ty]; | ||
} // else | ||
var i, c = []; | ||
for (i = 0; i < p.length; i += 1) { | ||
c.push([s * p[i][0] - r * p[i][1] + tx, r * p[i][0] + s * p[i][1] + ty]); | ||
} | ||
return c; | ||
}; | ||
this.getMatrix = function () { | ||
@@ -355,5 +383,36 @@ // Get the transformation matrix in the format common to | ||
this.getTranslation = function () { | ||
// Current translation as a point. | ||
return [tx, ty]; | ||
}; | ||
this.toArray = function () { | ||
// Return an array representation of the transformation. | ||
// | ||
// Together with nudged.createFromArray(...), this method makes an easy | ||
// serialization and deserialization to and from JSON possible. | ||
return [s, r, tx, ty]; | ||
}; | ||
// Methods that return new points | ||
this.transform = function (p) { | ||
// p | ||
// point [x, y] or array of points [[x1,y1], [x2, y2], ...] | ||
if (typeof p[0] === 'number') { | ||
// Single point | ||
return [s * p[0] - r * p[1] + tx, r * p[0] + s * p[1] + ty]; | ||
} // else | ||
var i, c = []; | ||
for (i = 0; i < p.length; i += 1) { | ||
c.push([s * p[i][0] - r * p[i][1] + tx, r * p[i][0] + s * p[i][1] + ty]); | ||
} | ||
return c; | ||
}; | ||
// Methods that return new Transformations | ||
this.inverse = function () { | ||
@@ -843,3 +902,3 @@ // Return inversed transform instance | ||
},{"./Transform":5}],13:[function(require,module,exports){ | ||
module.exports = '1.0.0'; | ||
module.exports = '1.2.0'; | ||
@@ -852,3 +911,5 @@ },{}],14:[function(require,module,exports){ | ||
module.exports = Emitter; | ||
if (typeof module !== 'undefined') { | ||
module.exports = Emitter; | ||
} | ||
@@ -855,0 +916,0 @@ /** |
@@ -80,6 +80,8 @@ var Emitter = require('component-emitter'); | ||
// For each moved touch. | ||
pointers[id].rx = x; | ||
pointers[id].ry = y; | ||
updateTransform(); | ||
this.emit('update', totalTransform); | ||
if (pointers.hasOwnProperty(id)) { | ||
pointers[id].rx = x; | ||
pointers[id].ry = y; | ||
updateTransform(); | ||
this.emit('update', totalTransform); | ||
} | ||
}; | ||
@@ -86,0 +88,0 @@ |
42
index.js
@@ -14,2 +14,44 @@ /* | ||
exports.create = function (scale, rotation, tx, ty) { | ||
// Create a nudged.Transform instance by using more meaningful parameters | ||
// than directly calling 'new nudged.Transform(...)' | ||
// | ||
// Parameters: | ||
// scale | ||
// number, the scaling factor | ||
// rotation | ||
// number, rotation in radians from positive x axis towards pos. y axis. | ||
// tx | ||
// translation toward pos. x | ||
// ty | ||
// translation toward pos. y | ||
if (typeof scale !== 'number') { scale = 1; } | ||
if (typeof rotation !== 'number') { rotation = 0; } | ||
if (typeof tx !== 'number') { tx = 0; } | ||
if (typeof ty !== 'number') { ty = 0; } | ||
var s = scale * Math.cos(rotation); | ||
var r = scale * Math.sin(rotation); | ||
return new exports.Transform(s, r, tx, ty); | ||
}; | ||
exports.createFromArray = function (arr) { | ||
// Create a nudged.Transform instance from an array that was | ||
// previously created with nudged.Transform#toArray(). | ||
// | ||
// Together with nudged.Transform#toArray(), this method makes an easy | ||
// serialization and deserialization to and from JSON possible. | ||
// | ||
// Parameter: | ||
// arr | ||
// array with four elements | ||
var s = arr[0]; | ||
var r = arr[1]; | ||
var tx = arr[2]; | ||
var ty = arr[3]; | ||
return new exports.Transform(s, r, tx, ty); | ||
}; | ||
exports.estimate = function (type, domain, range, pivot) { | ||
@@ -16,0 +58,0 @@ // Parameter |
@@ -14,18 +14,2 @@ | ||
this.transform = function (p) { | ||
// p | ||
// point [x, y] or array of points [[x1,y1], [x2, y2], ...] | ||
if (typeof p[0] === 'number') { | ||
// Single point | ||
return [s * p[0] - r * p[1] + tx, r * p[0] + s * p[1] + ty]; | ||
} // else | ||
var i, c = []; | ||
for (i = 0; i < p.length; i += 1) { | ||
c.push([s * p[i][0] - r * p[i][1] + tx, r * p[i][0] + s * p[i][1] + ty]); | ||
} | ||
return c; | ||
}; | ||
this.getMatrix = function () { | ||
@@ -55,5 +39,36 @@ // Get the transformation matrix in the format common to | ||
this.getTranslation = function () { | ||
// Current translation as a point. | ||
return [tx, ty]; | ||
}; | ||
this.toArray = function () { | ||
// Return an array representation of the transformation. | ||
// | ||
// Together with nudged.createFromArray(...), this method makes an easy | ||
// serialization and deserialization to and from JSON possible. | ||
return [s, r, tx, ty]; | ||
}; | ||
// Methods that return new points | ||
this.transform = function (p) { | ||
// p | ||
// point [x, y] or array of points [[x1,y1], [x2, y2], ...] | ||
if (typeof p[0] === 'number') { | ||
// Single point | ||
return [s * p[0] - r * p[1] + tx, r * p[0] + s * p[1] + ty]; | ||
} // else | ||
var i, c = []; | ||
for (i = 0; i < p.length; i += 1) { | ||
c.push([s * p[i][0] - r * p[i][1] + tx, r * p[i][0] + s * p[i][1] + ty]); | ||
} | ||
return c; | ||
}; | ||
// Methods that return new Transformations | ||
this.inverse = function () { | ||
@@ -60,0 +75,0 @@ // Return inversed transform instance |
@@ -1,1 +0,1 @@ | ||
module.exports = '1.0.1'; | ||
module.exports = '1.2.0'; |
{ | ||
"name": "nudged", | ||
"version": "1.0.1", | ||
"version": "1.2.0", | ||
"description": "Affine transformation estimator e.g. for multi-touch gestures and calibration", | ||
@@ -28,16 +28,13 @@ "keywords": [ | ||
}, | ||
"license": { | ||
"type": "MIT", | ||
"url": "https://github.com/axelpale/nudged/blob/master/LICENSE" | ||
}, | ||
"license": "MIT", | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"jshint": "^2.8.0", | ||
"mocha": "^2.3.3", | ||
"should": "^7.1.0", | ||
"mocha": "^3.1.2", | ||
"should": "^11.1.1", | ||
"loadimages": "^0.2.2", | ||
"browserify": "^11.2.0", | ||
"browserify": "^13.1.1", | ||
"hammerjs": "^2.0.4", | ||
"component-emitter": "^1.2.0", | ||
"lodash": "^3.10.1" | ||
"lodash": "^4.17.2" | ||
}, | ||
@@ -54,4 +51,4 @@ "scripts": { | ||
"test:nudged-taataa": "jshint examples/nudged-taataa/src/*.js", | ||
"build:nudged-taataa": "npm run test:nudged-taataa && browserify examples/nudged-taataa/src/index.js -o examples/nudged-taataa/app.js", | ||
"test:nudged-map": "jshint examples/nudged-map/src/*.js", | ||
"build:nudged-map": "npm run test:nudged-map && browserify examples/nudged-map/src/index.js -o examples/nudged-map/app.js", | ||
@@ -64,5 +61,5 @@ "test:nudged-gesture": "jshint examples/nudged-gesture/src/*.js", | ||
"build:examples": "npm run build:nudged-editor && npm run build:nudged-gesture && npm run build:typical-gesture && npm run build:nudged-taataa", | ||
"build:examples": "npm run build:nudged-editor && npm run build:nudged-gesture && npm run build:typical-gesture && npm run build:nudged-map", | ||
"build:standalone": "browserify index.js --standalone nudged -o nudged.js" | ||
} | ||
} |
251
README.md
@@ -1,2 +0,2 @@ | ||
# nudged<sup>1.0.1</sup> | ||
# nudged<sup>1.2.0</sup> | ||
@@ -6,3 +6,3 @@ [![NPM Version](https://img.shields.io/npm/v/nudged.svg)](https://www.npmjs.com/package/nudged) | ||
A JavaScript lib to efficiently estimate translation, scale, and/or rotation between two sets of 2D points. Applicable for example where one wants to move objects by multiple fingers or where data from an eye tracker device are wanted to be corrected based on a few calibration points. In general, you can apply *nudged* in any situation where you want to transform a number of points based on a few sample points and optionally one fixed pivot point. See the image below for visual explanation. | ||
**A JavaScript lib** to efficiently estimate translation, scale, and/or rotation between two sets of 2D points. We have found it to be useful in **graphics, user interfaces, multi-touch recognition, and eye tracker calibration**. In general, you can apply *nudged* in any situation where you want to move a number of points based on a few sample points and optionally one fixed pivot point. See the image below for visual explanation. | ||
@@ -13,8 +13,6 @@ <img src="https://rawgit.com/axelpale/nudged/master/doc/figure-pointset.png" alt="Example transformation" width="500"/> | ||
Mathematically speaking, *nudged* is an optimal least squares estimator for [affine transformation matrices](https://en.wikipedia.org/wiki/Affine_transformation) with translation, rotation, and/or uniform scaling, and without reflection or shearing. The estimation has time complexity of O(*n*), where *n* is the cardinality (size) of the point sets. In other words, *nudged* solves an affine 2D to 2D point set registration problem (alias [Procrustes superimposition](https://en.wikipedia.org/wiki/Procrustes_analysis)) in linear time. | ||
**Mathematically speaking**, *nudged* is a set of optimal least squares estimators for nonreflective similarity transformation matrices. Such transformations are [affine transformations](https://en.wikipedia.org/wiki/Affine_transformation) with translation, rotation, and/or uniform scaling, and without reflection or shearing. The estimation has time complexity of O(*n*), where *n* is the cardinality (size) of the point sets. In other words, *nudged* solves a 2D to 2D point set registration problem (alias [Procrustes superimposition](https://en.wikipedia.org/wiki/Procrustes_analysis)) in linear time. The algorithms and their efficiency are thoroughly described in a **M.Sc. thesis** [Advanced algorithms for manipulating 2D objects on touch screens](http://URN.fi/URN:NBN:fi:tty-201605264186). | ||
For a proof of optimality, see [the derivation of the main algorithm](https://rawgit.com/axelpale/nudged/master/doc/nudged-panor-2015-10-16.jpg). | ||
**The development has been supported** by [Infant Cognition Laboratory](http://www.uta.fi/med/icl/index.html) at [University of Tampere](http://www.uta.fi/en/) where it is used to correct eye tracking data. | ||
The development of *nudged* has been supported by [Infant Cognition Laboratory](http://www.uta.fi/med/icl/index.html) at [University of Tampere](http://www.uta.fi/en/) where it is used to correct eye tracking data. | ||
Available also [in Python](https://pypi.python.org/pypi/nudged). | ||
@@ -45,3 +43,9 @@ | ||
### Tokyo metro map viewer | ||
[<img src="https://rawgit.com/axelpale/nudged/master/examples/nudged-map/screenshot.png" alt="A screenshot of Nudged map viewer example" width="600"/>](https://rawgit.com/axelpale/nudged/master/examples/nudged-map/index.html) | ||
In this [map viewer demo](https://rawgit.com/axelpale/nudged/master/examples/nudged-map/index.html), nudged is used to recognize multi-touch gestures to scale, rotate, and translate [a large image](https://commons.wikimedia.org/wiki/File:Tokyo_metro_map.png) on HTML5 canvas. | ||
## Install | ||
@@ -57,2 +61,7 @@ | ||
Let `domain` and `range` be point sets before and after transformation as illustrated in the figure below: | ||
> var domain = [[0,0], [2,0], [ 1,2]] | ||
> var range = [[1,1], [1,3], [-1,2]] | ||
<img src="https://rawgit.com/axelpale/nudged/master/doc/simple-example-pointset.png" alt="The transformation" width="500"/> | ||
@@ -62,36 +71,36 @@ | ||
Let `domain` and `range` be point sets before and after transformation as illustrated in the figure above: | ||
var domain = [[0,0], [2,0], [ 1,2]] | ||
var range = [[1,1], [1,3], [-1,2]] | ||
Compute an optimal transformation based on the points: | ||
var trans = nudged.estimate('TSR', domain, range) | ||
> var trans = nudged.estimate('TSR', domain, range) | ||
Examine the transformation matrix: | ||
trans.getMatrix() | ||
-> { a: 0, c: -1, e: 1, | ||
b: 1, d: 0, f: 1 } | ||
trans.getRotation() | ||
-> 1.5707... = π / 2 | ||
trans.getScale() | ||
-> 1.0 | ||
trans.getTranslation() | ||
-> [1, 1] | ||
> trans.getMatrix() | ||
{ a: 0, c: -1, e: 1, | ||
b: 1, d: 0, f: 1 } | ||
> trans.getRotation() | ||
1.5707... = π / 2 | ||
> trans.getScale() | ||
1.0 | ||
> trans.getTranslation() | ||
[1, 1] | ||
Apply the transformation to other points: | ||
trans.transform([2,2]) | ||
-> [-1,3] | ||
> trans.transform([2,2]) | ||
[-1,3] | ||
Inverse the transformation: | ||
var inv = trans.inverse() | ||
inv.transform([-1,3]) | ||
-> [2,2] | ||
> var inv = trans.inverse() | ||
> inv.transform([-1,3]) | ||
[2,2] | ||
### Pivoted transformation | ||
See [API](#api) for more. | ||
### Using pivoted transformations | ||
You can think the pivot point as a pin pushed through a paper. The pin keeps its location intact regardless of the transformation around it, as illustrated in the figure below. | ||
<img src="https://rawgit.com/axelpale/nudged/master/doc/simple-example-fixed.png" alt="A fixed point transformation" width="500"/> | ||
@@ -101,13 +110,15 @@ | ||
Alternatively, in addition to the domain and range, set a fixed pivot point that will stay intact in the transformation as illustrated in the figure above. | ||
In the following example we estimate an optimal scaling and rotation around point `[-1,0]`: | ||
var pivot = [-1,0] | ||
var domain = [[0,0], [2,0], [ 1,2]] | ||
var range = [[1,1], [1,3], [-1,2]] | ||
var pivotTrans = nudged.estimate('SR', domain, range, pivot) | ||
> var pivot = [-1,0] | ||
> var domain = [[0,0], [2,0], [ 1,2]] | ||
> var range = [[1,1], [1,3], [-1,2]] | ||
> var pivotTrans = nudged.estimate('SR', domain, range, pivot) | ||
Now the domain points can be transformed: | ||
If we now apply the transformation to the domain, we see that the result is close to the range. Also, if we apply it to the pivot, the point stays the same. | ||
pivotTrans.transform(domain) | ||
-> [[-0.33, 0.77], [0.99, 2.33], [-1.22, 2.88]] | ||
> pivotTrans.transform(domain) | ||
[[-0.33, 0.77], [0.99, 2.33], [-1.22, 2.88]] | ||
> pivotTrans.transform(pivot) | ||
[-1,0] | ||
@@ -118,5 +129,47 @@ | ||
Nudged provides 7 types of estimators, one for each combination of translation, scaling, and rotation. The ones without translation allow an optional fixed point. | ||
Nudged API provides a class for nonreflective similarity transformations and 7 types of estimators, one for each combination of translation, scaling, and rotation. The ones without translation allow an optional fixed point. | ||
### nudged.create(scale, rotation, translationX, translationY) | ||
Create a transformation that scales, rotates, and translates as specified. | ||
**Parameters:** | ||
- *scale*: a number; the scaling factor. | ||
- *rotation*: a number; the rotation in radians from positive x axis toward positive y axis. | ||
- *translationX*: a number; translation after rotation, toward positive x axis. | ||
- *translationY*: a number; translation after rotation, toward positive y axis. | ||
The parameters are optional and default to the identity transformation. | ||
**Return** a new `nudged.Transform` instance. | ||
**Examples:** | ||
> var t0 = nudged.create() | ||
> t0.transform([3, 1]) | ||
[3, 1] | ||
> var t1 = nudged.create(2) | ||
> t1.transform([3, 1]) | ||
[6, 2] | ||
> var t2 = nudged.create(1, Math.PI / 2) | ||
> t2.transform([3, 1]) | ||
[-1, 3] | ||
> var t3 = nudged.create(1, 0, 20.2, 0) | ||
> t3.transform([3, 1]) | ||
[23.2, 1] | ||
### nudged.createFromArray(arr) | ||
Create a `nudged.Transform` instance from an array created by nudged.Transform#toArray(). Together with `nudged.Transform#toArray()` this method makes an easy **serialization and deserialization** to and from JSON possible. | ||
> var t1 = nudged.create(1, 2, 3, 4) | ||
> var arr = trans.toArray() | ||
> var t2 = nudged.createFromArray(arr) | ||
> t1.equals(t2) | ||
true | ||
### nudged.estimate(type, domain, range, pivot?) | ||
@@ -126,7 +179,7 @@ | ||
**Parameters** | ||
**Parameters:** | ||
- *type*: string, freedom of the transformation. Types available: `'T'`, `'S'`, `'R'`, `'TS'`, `'TR'`, `'SR'`, `'TSR'` | ||
- *domain*: array of [x,y] points | ||
- *range*: array of [x,y] points | ||
- *pivot*: optional [x,y] point. Defaults to the origin [0,0]. | ||
- *pivot*: optional [x,y] point. Defaults to the origin [0,0] with types `'S'`, `'R'`, and `'SR'`. | ||
@@ -150,39 +203,69 @@ The *domain* and *range* should have equal length. Different lengths are allowed but additional points in the longer array are ignored. | ||
Contains the module version string equal to the version in *package.json*. | ||
Contains the module version string identical to the version in *package.json*. | ||
> nudged.version | ||
'1.2.3' | ||
### nudged.Transform(s, r, tx, ty) | ||
A `nudged.Transform` instance is returned by the `nudged.estimate(...)`. | ||
A constructor for a nonreflective similarity transformation. You usually do not need to call it directly because both `nudged.create(...)` and `nudged.estimate(...)` create and return instances for you. Nevertheless, if you need to create one: | ||
In addition to the methods below, it has properties *s*, *r*, *tx*, *ty* that define the [augmented transformation matrix](https://en.wikipedia.org/wiki/Affine_transformation#Augmented_matrix): | ||
> var trans = new nudged.Transform(0.5, 0, 20, 0) | ||
|s -r tx| | ||
|r s ty| | ||
|0 0 1| | ||
The `nudged.Transform` instance is designed to be immutable. | ||
#### nudged.Transform#transform(points) | ||
**Parameters** `s`, `r`, `tx`, and `ty` define the elements of an [augmented transformation matrix](https://en.wikipedia.org/wiki/Affine_transformation#Augmented_matrix) in the following manner: | ||
Apply the transform to a point or an array of points. | ||
| s -r tx | | ||
| r s ty | | ||
| 0 0 1 | | ||
**Return** an array of transformed points or single point if only a point was given. For example: | ||
Note that `s` and `r` do **not** represent scaling and rotation but instead `s = scalingFactor * Math.cos(rotationRads)` and `r = scalingFactor * Math.sin(rotationRads)`. The parameters `tx` and `ty` represent horizontal and vertical translation after rotation. | ||
trans.transform([1,1]) // [2,2] | ||
trans.transform([[1,1]]) // [[2,2]] | ||
trans.transform([[1,1], [2,3]]) // [[2,2], [3,4]] | ||
#### nudged.Transform#getMatrix() | ||
### nudged.Transform.IDENTITY | ||
**Return** the transformation matrix in the following format: | ||
A default instance of `nudged.Transform` that represents the identity transformation i.e. transformation without an effect. You can use it in building new transformations: | ||
{ a: s, c: -r, e: tx, | ||
b: r, d: s, f: ty } | ||
> var trans = nudged.Transform.IDENTITY.scaleBy(0.6).rotateBy(0.3); | ||
For example: | ||
### nudged.Transform#s, #r, #tx, #ty | ||
Elements of the internal transformation matrix. Direct use of these properties is not recommended. | ||
> var t = nudged.create(2, Math.PI / 2, 10, 20) | ||
> t.s | ||
1.2246e-16 | ||
> t.r | ||
2 | ||
> t.tx | ||
10 | ||
> t.ty | ||
20 | ||
### nudged.Transform#equals(tr) | ||
**Parameter** `tr` is an instance of `nudged.Transform`. | ||
**Return** true if the parameters of the two transformations are equal and false otherwise. | ||
### nudged.Transform#getMatrix() | ||
Get the transformation matrix in a format compatible with [kld-affine](https://www.npmjs.com/package/kld-affine). | ||
**Return** an object with properties `a`, `b`, `c`, `d`, `e`, and `f`. | ||
> trans.getMatrix() | ||
{ a: 0.48, c: -0.52, e: 205.04, | ||
b: 0.52, d: 0.48, f: 4.83 } | ||
#### nudged.Transform#getRotation() | ||
The properties represent the following matrix: | ||
| a c e | | ||
| b d f | | ||
| 0 0 1 | | ||
### nudged.Transform#getRotation() | ||
Get clockwise rotation from the positive x-axis. | ||
@@ -192,12 +275,33 @@ | ||
#### nudged.Transform#getScale() | ||
### nudged.Transform#getScale() | ||
**Return** scaling multiplier, e.g. `0.333` for a threefold shrink. | ||
#### nudged.Transform#getTranslation() | ||
### nudged.Transform#getTranslation() | ||
**Return** `[tx, ty]` where `tx` and `ty` denotes movement along x-axis and y-axis accordingly. | ||
#### nudged.Transform#inverse() | ||
### nudged.Transform#toArray() | ||
Together with `nudged.createFromArray(...)` this method makes an easy serialization and deserialization to and from JSON possible. | ||
**Return** an array representation of the transformation: `[s, r, tx, ty]`. Note that `s` and `r` do not represent scaling and rotation but elements of the matrix. | ||
### nudged.Transform#transform(points) | ||
Apply the transform to a point or an array of points. | ||
**Parameter** `points` is an array of points `[[x, y], ...]` or a single point `[x, y]`. | ||
**Return** an array of transformed points or single point if only a point was given. For example: | ||
> trans.transform([1,1]) | ||
[2,2] | ||
> trans.transform([[1,1]]) | ||
[[2,2]] | ||
> trans.transform([[1,1], [2,3]]) | ||
[[2,2], [3,4]] | ||
### nudged.Transform#inverse() | ||
**Return** a new `nudged.Transform` instance that is the inverse of the original transformation. | ||
@@ -207,8 +311,10 @@ | ||
#### nudged.Transform#translateBy(dx, dy) | ||
### nudged.Transform#translateBy(dx, dy) | ||
**Return** a new `nudged.Transform` instance where the image of the original has been translated. | ||
#### nudged.Transform#scaleBy(multiplier, pivot?) | ||
### nudged.Transform#scaleBy(multiplier, pivot?) | ||
**Parameter** `multiplier` is a number. Optional parameter `pivot` is a point `[x, y]`. | ||
**Return** a new `nudged.Transform` instance where the image of the original has been scaled. | ||
@@ -218,4 +324,6 @@ | ||
#### nudged.Transform#rotateBy(radians, pivot?) | ||
### nudged.Transform#rotateBy(radians, pivot?) | ||
**Parameter** `radians` is a number. Optional parameter `pivot` is a point `[x, y]`. | ||
**Return** a new `nudged.Transform` instance where the image of the original has been rotated. | ||
@@ -225,4 +333,12 @@ | ||
### nudged.Transform#multiplyBy(tr) | ||
**Parameter** `tr` is an instance of `nudged.Transform`. | ||
**Return** a new `nudged.Transform` instance where the original transformation matrix is multiplied from the right with the transformation matrix of `tr`. | ||
The resulting transformation is equal to first transforming with `tr` and then with the instance. More precisely, the image of the resulting transformation is the image of `tr` transformed by the instance. | ||
## For developers | ||
@@ -244,6 +360,9 @@ | ||
- Bump version and run tests. | ||
- Create release branch. See [tutorial](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow). | ||
- `$ git checkout -b release-7.7.7 development` | ||
- Update the [badge urls](http://shields.io/) in README. | ||
- Update the rawgit urls in README. | ||
- Update the rawgit urls in README: | ||
- Replace 'nudged/development' with 'nudged/master' | ||
- Commit: `$ git commit -a -m "Clean release 7.7.7"` | ||
- Merge (see the tut above): | ||
@@ -261,9 +380,7 @@ - `$ git checkout master` | ||
## Roadmap | ||
- Example apps for SR, TS, and other cases. | ||
## Thanks | ||
- [Infant Cognition Laboratory at University of Tampere](http://www.uta.fi/med/icl/index.html) for funding. | ||
- [3D Media Group at Tampere University of Technology](http://www.tut.fi/en/about-tut/departments/signal-processing/research/3d-media/) for testing devices. | ||
- Tanja for math photos. | ||
@@ -270,0 +387,0 @@ - Vilkku, Xiao, and Krista for fingers. |
@@ -15,2 +15,10 @@ var should = require('should'); | ||
var samples = { | ||
// Info about the properties | ||
// id: description | ||
// a: domain | ||
// b: range | ||
// fixed: a fixed pivot point used in applicable estimations | ||
// t: result of translation estimation | ||
// ts: result of translation scaling estimation | ||
// fsr: result of scaling rotation estimation with a specified fixed pivot. | ||
'z-00': { | ||
@@ -186,2 +194,31 @@ id: 'should allow arrays of length zero', | ||
describe('.create', function () { | ||
it('should be able to create identity', function () { | ||
var t = nudged.create(1, 0, 0, 0); | ||
assertIdentity(t); | ||
}); | ||
it('should default to identity', function () { | ||
assertIdentity(nudged.create()); | ||
}); | ||
it('should be consistent with previous methods', function () { | ||
var a = nudged.create(2.0, 3, 1, 2); | ||
var b = nudged.Transform.IDENTITY | ||
.scaleBy(2) | ||
.rotateBy(3) | ||
.translateBy(1, 2); | ||
assertTransform(a, b); | ||
}); | ||
}); | ||
describe('.createFromArray', function () { | ||
it('should work with toArray', function () { | ||
var t1 = nudged.create(0.4, 2.2, 10, 10); | ||
var arr = t1.toArray(); | ||
var t2 = nudged.createFromArray(arr); | ||
assertTransform(t1, t2); | ||
}); | ||
}); | ||
describe('.estimate', function () { | ||
@@ -188,0 +225,0 @@ it('should estimate correct transformation type', function () { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
10208
384
2438496
50