Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

nudged

Package Overview
Dependencies
Maintainers
0
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nudged - npm Package Compare versions

Comparing version 2.0.0 to 2.0.1

CHANGELOG.md

8

lib/estimate.js

@@ -12,3 +12,3 @@ const es = require('./estimators')

// Defines the freedom of the transform to compute.
// One of the following:
// Must be one of the following:
// ..'I', 'L', 'X', 'Y', 'T', 'S', 'R', 'TS', 'TR', 'SR', 'TSR'

@@ -55,2 +55,6 @@ // domain

//
if (!params.estimator) {
throw new Error('Unexpected estimator type: ' + params.estimator)
}
switch (params.estimator.toUpperCase()) {

@@ -80,4 +84,4 @@ case 'I':

default:
throw new Error('Unknown estimator type: ' + params.type)
throw new Error('Unexpected estimator type: ' + params.estimator)
}
}

@@ -8,3 +8,6 @@ module.exports = function () {

//
// Why this trivial estimator exists? If the estimator type becomes a variable in your application
// then it is convenient to be able to disable estimation by just switching the estimator type to I.
//
return { a: 1, b: 0, x: 0, y: 0 }
}

@@ -42,5 +42,6 @@ const TOLERANCE = require('../tolerance')

const det = Math.sqrt(p * p + q * q)
// Determinant. Always det >= 0
const det = p * p + q * q
if (Math.abs(det) < TOLERANCE) {
if (det < TOLERANCE) {
// det === 0

@@ -56,4 +57,7 @@ // <=> q === 0 and p === 0.

const ahat = p / det
const bhat = q / det
// Denominator.
const den = Math.sqrt(det)
const ahat = p / den
const bhat = q / den
const xhat = cx - cx * ahat + cy * bhat

@@ -60,0 +64,0 @@ const yhat = cy - cx * bhat - cy * ahat

@@ -20,2 +20,19 @@ const TOLERANCE = require('../tolerance')

// If length is zero, no points provided, thus no estimation can be done.
// We choose the identity transformation be the best quess.
if (N === 0) {
return { a: 1, b: 0, x: 0, y: 0 }
}
// If length is one, only single point pair was provided.
// A translation is the optimal solution.
// The general algorithm resolves single point pair to a translation,
// but translation estimation is numerically much more stable and thus
// worth a few lines of code. See PR#31.
if (N === 1) {
const dx = range[0].x - domain[0].x
const dy = range[0].y - domain[0].y
return { a: 1, b: 0, x: dx, y: dy }
}
let asum = 0 // sum

@@ -46,12 +63,15 @@ let bsum = 0

// Denominator = determinant.
const v = N * (ac + bd) - asum * csum - bsum * dsum
const w = N * (ad - bc) - asum * dsum + bsum * csum
const det = Math.sqrt(v * v + w * w)
// Determinant.
// For numerical stability near the zero determinant, note the order of the terms.
// We want first a,c terms cancel each other and then b,d terms.
// v = N * (ac + bd) - asum * csum - bsum * dsum
// w = N * (ad - bc) - asum * dsum + bsum * csum
// <=>
// v = (N * ac - asum * csum) + (N * bd - bsum * dsum)
// w = (N * ad - asum * dsum) + (bsum * csum - N * bc)
const v = N * ac - asum * csum + (N * bd - bsum * dsum)
const w = N * ad - asum * dsum + (bsum * csum - N * bc)
const det = v * v + w * w
if (det < TOLERANCE) {
// N === 0 => det === 0
if (N === 0) {
return { a: 1, b: 0, x: 0, y: 0 }
} // else
// det === 0 <=> undecidable

@@ -68,5 +88,8 @@ // We guess the translation to the mean of the range to be the best guess.

// Denominator is the square root of determinant.
const den = Math.sqrt(det)
// Estimators
const ahat = v / det
const bhat = w / det
const ahat = v / den
const bhat = w / den
const xhat = (-asum * ahat + bsum * bhat + csum) / N

@@ -73,0 +96,0 @@ const yhat = (-asum * bhat - bsum * ahat + dsum) / N

@@ -20,2 +20,19 @@ const TOLERANCE = require('../tolerance')

// If length is zero, no points provided, thus no estimation can be done.
// We choose the identity transformation be the best quess.
if (N === 0) {
return { a: 1, b: 0, x: 0, y: 0 }
}
// If length is one, only single point pair was provided.
// A translation is the optimal solution.
// The general algorithm resolves single point pair to a translation,
// but translation estimation is numerically much more stable and thus
// worth a few lines of code. See PR#31.
if (N === 1) {
const dx = range[0].x - domain[0].x
const dy = range[0].y - domain[0].y
return { a: 1, b: 0, x: dx, y: dy }
}
let a1 = 0

@@ -50,5 +67,11 @@ let b1 = 0

const b12 = b1 * b1
const p = a2 + b2
const q = ac + bd
const det = N2 * p - N * (a12 + b12)
// For numerical stability near the zero determinant, reorder terms so
// that we evaluate x and y specific terms separately. See PR#31.
// p = a2 + b2
// q = ac + bd
// det = N2 * p - N * (a12 + b12)
// = N2 * (a2 + b2) - N * (a12 + b12)
// = N2 * a2 + N2 * b2 - N * a12 - N * b12
// = N2 * a2 - N * a12 + N2 * b2 - N * b12
const det = N2 * a2 - N * a12 + N2 * b2 - N * b12

@@ -74,2 +97,6 @@ if (Math.abs(det) < TOLERANCE) {

// Shorthand
const p = a2 + b2
const q = ac + bd
// Estimators

@@ -76,0 +103,0 @@ const ahat = (N2 * q - N * (a1 * c1 + b1 * d1)) / det

@@ -22,4 +22,4 @@ const TOLERANCE = require('../tolerance')

// If length is zero, no estimation can be done. We choose the indentity
// transformation be the best quess.
// If length is zero, no points provided, thus no estimation can be done.
// We choose the identity transformation be the best quess.
if (N === 0) {

@@ -29,2 +29,13 @@ return { a: 1, b: 0, x: 0, y: 0 }

// If length is one, only single point pair was provided.
// A translation is the optimal solution.
// The general algorithm resolves single point pair to a translation,
// but translation estimation is numerically much more stable and thus
// worth a few lines of code. See PR#31.
if (N === 1) {
const dx = range[0].x - domain[0].x
const dy = range[0].y - domain[0].y
return { a: 1, b: 0, x: dx, y: dy }
}
let a1 = 0

@@ -62,3 +73,8 @@ let b1 = 0

// In other words, iff all the domain points are the same or there is only one domain point.
const det = N * a2 + N * b2 - a1 * a1 - b1 * b1
//
// Note the term order: first we want to evaluate x-specific terms and then y-specific terms.
// The below term order brings numerical stability to near-zero cases. See PR#31.
// We do not need to use parenthesis because the addition operator '+' in JavaScript is left-associative,
// and thus for example the expression a+b+c+d is evalued like (((a + b) + c) + d).
const det = N * a2 - a1 * a1 + N * b2 - b1 * b1

@@ -65,0 +81,0 @@ if (Math.abs(det) < TOLERANCE) {

@@ -13,6 +13,3 @@ module.exports = (x, y) => {

//
return {
x: x,
y: y
}
return { x, y }
}

@@ -21,8 +21,3 @@ module.exports = function (a, b, x, y) {

//
return {
a: a,
b: b,
x: x,
y: y
}
return { a, b, x, y }
}

@@ -1,2 +0,2 @@

// generated by genversion
module.exports = '2.0.0'
// Generated by genversion.
module.exports = '2.0.1'
{
"name": "nudged",
"version": "2.0.0",
"version": "2.0.1",
"description": "Affine transformation estimator e.g. for multi-touch gestures and calibration",

@@ -12,2 +12,3 @@ "keywords": [

"pinch",
"math",
"affine",

@@ -19,3 +20,6 @@ "multitouch",

"similarity",
"calibration"
"calibration",
"snapping",
"match",
"layout"
],

@@ -35,10 +39,10 @@ "homepage": "https://github.com/axelpale/nudged",

"async": "^3.2.0",
"browserify": "^17.0.0",
"browserify": "^17.0.1",
"component-emitter": "^1.2.0",
"genversion": "^3.0.0",
"genversion": "^3.2.0",
"hammerjs": "^2.0.4",
"loadimages": "^1.0.0",
"lodash": "^4.17.21",
"standard": "^16.0.3",
"tap-spec": "^5.0.0",
"standard": "^17.1.2",
"tap-arc": "^1.3.2",
"tape": "^5.2.2"

@@ -50,3 +54,4 @@ },

"test": "npm run test:lint && npm run test:unit",
"test:unit": "node test/index.test.js | tap-spec",
"test:unit": "node test/index.test.js",
"test:pretty": "node test/index.test.js | tap-arc",
"test:lint": "standard index.js 'lib/**/*.js' 'test/**/*.js'",

@@ -53,0 +58,0 @@ "test:lint:fix": "standard --fix index.js 'lib/**/*.js' 'test/**/*.js'",

# nudged
[![NPM Version](https://img.shields.io/npm/v/nudged.svg)](https://www.npmjs.com/package/nudged)
[![Build Status](https://img.shields.io/travis/com/axelpale/nudged)](https://travis-ci.com/github/axelpale/nudged)
![Dependency status](https://img.shields.io/badge/dependencies-none-lightgrey)
[![License](https://img.shields.io/npm/l/nudged)](#license)
[![GitHub Actions workflow status](https://img.shields.io/github/actions/workflow/status/axelpale/nudged/nudged-ci.yml)](https://github.com/axelpale/nudged/actions/workflows/nudged-ci.yml)
![Nudged logo](doc/nudged-logo-2021-512.png)
*Nudged* is **a JavaScript module** to efficiently estimate translation, scale, and/or rotation between two sets of 2D points. It has already been applied to **user interfaces, multi-touch recognition, geography, and eye tracker calibration**.
*Nudged* is **a JavaScript module** to efficiently estimate translation, scale, and rotation between two sets of 2D points. It enables you to **capture transformations** that you can use for **motion dynamics, calibration, geometry snapping, and mapping between coordinate spaces**. It has already been applied to **user interface geometry [[1]](https://github.com/taataa/tapspace), multi-touch recognition [[1]](https://github.com/taataa/tapspace), and eye tracker calibration [[2]](https://github.com/infant-cognition-tampere/gazeanalysislib)**.

@@ -21,2 +23,3 @@ ### Table of contents

- [Licence](#licence)
- [See also](#see-also)

@@ -28,3 +31,3 @@

Install the functional nudged 2.0.0-beta:
Install the functional nudged 2:

@@ -42,3 +45,3 @@ $ npm install nudged

In general, you can apply Nudged in any situation where you want to capture a 2D transformation based on a movement of any number of control points. See the image below for the available transformations Nudged can estimate.
In general, you can apply Nudged in any situation where you want to capture a 2D transformation based on a movement of any number of control points. You have a set of points, and they move from some source coordinates to some target coordinates. You want to capture the movement pattern between the source and the target as a 2D transformation. You may want to capture the pattern in order to apply it to something else, such as a photo or some other object. See the image below for the available transformations Nudged can estimate, illustrated with two control points and a photo.

@@ -269,6 +272,8 @@ <img src="doc/transformation-types.jpg" alt="Types of transformation estimators"/><br>

Nudged source code is located at [GitHub](https://github.com/axelpale/nudged).
Guidelines:
- ES6
- [Standard style](https://standardjs.com/)
- Use [ECMAScript 2015](https://en.wikipedia.org/wiki/ECMAScript) syntax with [CommonJS](https://en.wikipedia.org/wiki/CommonJS) module format.
- Follow [Standard](https://standardjs.com/) style:
- 2 space indent

@@ -279,7 +284,7 @@ - max 80 chars per line

- namespaces and functions instead of classes and methods
- immutable and stateless data handling; no in-place manipulation.
- immutable and stateless data handling; no in-place manipulation of arguments.
- Minimal run-time type checking
- Nudged is designed to be a low-level module with high performance.
- Instead of run-time checks, the geometries provide a dedicated .validate function.
- Write rich comments that answer the question why.
- Write rich comments that answer the question "why".

@@ -324,3 +329,4 @@ Run lint & unit tests:

- Tanja for math photos.
- Vilkku, Xiao, and Krista for finger photos.
- Vilkku, Xiao, and Krista for illustrative finger photos.
- All who have contributed to the codebase and issue resolution over the years.

@@ -330,8 +336,14 @@

[Semantic Versioning 2.0.0](http://semver.org/)
The versioning convention of the package follows [Semantic Versioning 2.0.0](http://semver.org/) and [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/).
## Licence
[MIT Licence](LICENSE)
The nudged source code is open source and free to use. It is released under a [MIT licence](LICENSE).
## See also
- [Affineplane](https://axelpale.github.io/affineplane/) geometry library is directly compatible with Nudged object interfaces. It provides further tools to transform geometry and manipulate transformations in 2D and 3D.
- [Tapspace.js](https://github.com/taataa/tapspace) is a toolkit for zoomable user interfaces. Tapspace.js heavily depends on the nudged algorithm in multi-touch recognition, web content layout, and tensor geometry.
- [Apollonius](https://axelpale.github.io/apollonius/) is another math-heavy geometry package from the author of Nudged. Apollonius considers finding a circle that is simultaneously tangent to three other circles.

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc