forked from enviPath/enviPy
Current Dev State
This commit is contained in:
102
static/js/ketcher2/node_modules/svgpath/lib/ellipse.js
generated
vendored
Normal file
102
static/js/ketcher2/node_modules/svgpath/lib/ellipse.js
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
'use strict';
|
||||
|
||||
/* eslint-disable space-infix-ops */
|
||||
|
||||
// The precision used to consider an ellipse as a circle
|
||||
//
|
||||
var epsilon = 0.0000000001;
|
||||
|
||||
// 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;
|
||||
return this;
|
||||
}
|
||||
|
||||
// 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 = (Math.abs(L) < epsilon && Math.abs(l1 - K) < epsilon) ?
|
||||
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;
|
||||
Reference in New Issue
Block a user