-
-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #15 from kpym/arctransformfix
New version of bug #13 fix
- Loading branch information
Showing
3 changed files
with
129 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
'use strict'; | ||
|
||
// The precision used to consider an ellipse as a circle | ||
// | ||
var epsilon = 0.0001; | ||
|
||
// To convert degree in radians | ||
// | ||
var torad = Math.PI / 180; | ||
|
||
// Class constructor : | ||
// an ellipse centred at 0 with radii rx,ry and x - axis - angle ax. | ||
// | ||
function Ellipse(rx, ry, ax) { | ||
if (!(this instanceof Ellipse)) { return new Ellipse(rx, ry, ax); } | ||
this.rx = rx; | ||
this.ry = ry; | ||
this.ax = ax; | ||
} | ||
|
||
// Apply a linear transform m to the ellipse | ||
// m is an array representing a matrix : | ||
// - - | ||
// | m[0] m[2] | | ||
// | m[1] m[3] | | ||
// - - | ||
// | ||
Ellipse.prototype.transform = function (m) { | ||
// We consider the current ellipse as image of the unit circle | ||
// by first scale(rx,ry) and then rotate(ax) ... | ||
// So we apply ma = m x rotate(ax) x scale(rx,ry) to the unit circle. | ||
var c = Math.cos(this.ax * torad), s = Math.sin(this.ax * torad); | ||
var ma = [ this.rx * (m[0] * c + m[2] * s), | ||
this.rx * (m[1] * c + m[3] * s), | ||
this.ry * (-m[0] * s + m[2] * c), | ||
this.ry * (-m[1] * s + m[3] * c) ]; | ||
// ma * transpose(ma) = [ J L ] | ||
// [ L K ] | ||
// L is calculated later (if the image is not a circle) | ||
var J = ma[0] * ma[0] + ma[2] * ma[2], K = ma[1] * ma[1] + ma[3] * ma[3]; | ||
|
||
// the discriminant of the characteristic polynomial of ma * transpose(ma) | ||
var D = ((ma[0] - ma[3]) * (ma[0] - ma[3]) + (ma[2] + ma[1]) * (ma[2] + ma[1])) * | ||
((ma[0] + ma[3]) * (ma[0] + ma[3]) + (ma[2] - ma[1]) * (ma[2] - ma[1])); | ||
// the "mean eigenvalue" | ||
var JK = (J + K) / 2; | ||
// check if the image is (almost) a circle | ||
if (D < epsilon * JK) { | ||
// if it is | ||
this.rx = this.ry = Math.sqrt(JK); | ||
this.ax = 0; | ||
} else { | ||
// if it is not a circle | ||
var L = ma[0] * ma[1] + ma[2] * ma[3]; | ||
D = Math.sqrt(D); | ||
// {l1,l2} = the two eigen values of ma * transpose(ma) | ||
var l1 = JK + D / 2, | ||
l2 = JK - D / 2; | ||
// the x - axis - rotation angle is the argument of the l1 - eigenvector | ||
this.ax = (L === 0 && l1 === K) ? 90 : Math.atan( | ||
Math.abs(L) > Math.abs(l1 - K) ? (l1 - J) / L : L / (l1 - K) | ||
) * 180 / Math.PI; | ||
// if ax > 0 => rx = sqrt(l1), ry = sqrt(l2), else exchange axes and ax += 90 | ||
if (this.ax >= 0) { // if ax in [0,90] | ||
this.rx = Math.sqrt(l1); | ||
this.ry = Math.sqrt(l2); | ||
} else { // if ax in ]-90,0[ => exchange axes | ||
this.ax += 90; | ||
this.rx = Math.sqrt(l2); | ||
this.ry = Math.sqrt(l1); | ||
} | ||
} | ||
|
||
return this; | ||
}; | ||
|
||
// Check if the ellipse is (almost) degenerate, i.e. rx = 0 or ry = 0 | ||
// | ||
Ellipse.prototype.isDegenerate = function () { | ||
return (this.rx < epsilon * this.ry || this.ry < epsilon * this.rx); | ||
}; | ||
|
||
module.exports = Ellipse; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters