Files
30-seconds-of-code/node_modules/potrace/lib/utils.js
2019-08-20 15:52:05 +02:00

247 lines
5.0 KiB
JavaScript

'use strict';
var Point = require('./types/Point');
var attrRegexps = {};
function getAttrRegexp(attrName) {
if (attrRegexps[attrName]) {
return attrRegexps[attrName];
}
attrRegexps[attrName] = new RegExp(' ' + attrName + '="((?:\\\\(?=")"|[^"])+)"', 'i');
return attrRegexps[attrName];
}
function setHtmlAttribute(html, attrName, value) {
var attr = ' ' + attrName + '="' + value + '"';
if (html.indexOf(' ' + attrName + '="') === -1) {
html = html.replace(/<[a-z]+/i, function(beginning) { return beginning + attr; });
} else {
html = html.replace(getAttrRegexp(attrName), attr);
}
return html;
}
function fixed(number) {
return number.toFixed(3).replace('.000', '');
}
function mod(a, n) {
return a >= n ? a % n : a>=0 ? a : n-1-(-1-a) % n;
}
function xprod(p1, p2) {
return p1.x * p2.y - p1.y * p2.x;
}
function cyclic(a, b, c) {
if (a <= c) {
return (a <= b && b < c);
} else {
return (a <= b || b < c);
}
}
function sign(i) {
return i > 0 ? 1 : i < 0 ? -1 : 0;
}
function quadform(Q, w) {
var v = new Array(3), i, j, sum;
v[0] = w.x;
v[1] = w.y;
v[2] = 1;
sum = 0.0;
for (i=0; i<3; i++) {
for (j=0; j<3; j++) {
sum += v[i] * Q.at(i, j) * v[j];
}
}
return sum;
}
function interval(lambda, a, b) {
var res = new Point();
res.x = a.x + lambda * (b.x - a.x);
res.y = a.y + lambda * (b.y - a.y);
return res;
}
function dorth_infty(p0, p2) {
var r = new Point();
r.y = sign(p2.x - p0.x);
r.x = -sign(p2.y - p0.y);
return r;
}
function ddenom(p0, p2) {
var r = dorth_infty(p0, p2);
return r.y * (p2.x - p0.x) - r.x * (p2.y - p0.y);
}
function dpara(p0, p1, p2) {
var x1, y1, x2, y2;
x1 = p1.x - p0.x;
y1 = p1.y - p0.y;
x2 = p2.x - p0.x;
y2 = p2.y - p0.y;
return x1 * y2 - x2 * y1;
}
function cprod(p0, p1, p2, p3) {
var x1, y1, x2, y2;
x1 = p1.x - p0.x;
y1 = p1.y - p0.y;
x2 = p3.x - p2.x;
y2 = p3.y - p2.y;
return x1 * y2 - x2 * y1;
}
function iprod(p0, p1, p2) {
var x1, y1, x2, y2;
x1 = p1.x - p0.x;
y1 = p1.y - p0.y;
x2 = p2.x - p0.x;
y2 = p2.y - p0.y;
return x1*x2 + y1*y2;
}
function iprod1(p0, p1, p2, p3) {
var x1, y1, x2, y2;
x1 = p1.x - p0.x;
y1 = p1.y - p0.y;
x2 = p3.x - p2.x;
y2 = p3.y - p2.y;
return x1 * x2 + y1 * y2;
}
function ddist(p, q) {
return Math.sqrt((p.x - q.x) * (p.x - q.x) + (p.y - q.y) * (p.y - q.y));
}
module.exports = {
luminance: function (r, g, b) {
return Math.round(0.2126 * r + 0.7153 * g + 0.0721 * b);
},
between: function(val, min, max) {
return val >= min && val <= max;
},
clamp: function(val, min, max) {
return Math.min(max, Math.max(min, val));
},
isNumber: function(val) {
return typeof val === 'number';
},
setHtmlAttr: setHtmlAttribute,
/**
* Generates path instructions for given curve
*
* @param {Curve} curve
* @param {Number} [scale]
* @returns {string}
*/
renderCurve: function(curve, scale) {
scale = scale || 1;
var startingPoint = curve.c[(curve.n - 1) * 3 + 2];
var path = 'M '
+ fixed(startingPoint.x * scale) + ' '
+ fixed(startingPoint.y * scale) + ' ';
curve.tag.forEach(function(tag, i) {
var i3 = i * 3;
var p0 = curve.c[i3];
var p1 = curve.c[i3 + 1];
var p2 = curve.c[i3 + 2];
if (tag === "CURVE") {
path += 'C ';
path += fixed(p0.x * scale) + ' ' + fixed(p0.y * scale) + ', ';
path += fixed(p1.x * scale) + ' ' + fixed(p1.y * scale) + ', ';
path += fixed(p2.x * scale) + ' ' + fixed(p2.y * scale) + ' ';
} else if (tag === "CORNER") {
path += 'L ';
path += fixed(p1.x * scale) + ' ' + fixed(p1.y * scale) + ' ';
path += fixed(p2.x * scale) + ' ' + fixed(p2.y * scale) + ' ';
}
});
return path;
},
bezier: function bezier(t, p0, p1, p2, p3) {
var s = 1 - t, res = new Point();
res.x = s*s*s*p0.x + 3*(s*s*t)*p1.x + 3*(t*t*s)*p2.x + t*t*t*p3.x;
res.y = s*s*s*p0.y + 3*(s*s*t)*p1.y + 3*(t*t*s)*p2.y + t*t*t*p3.y;
return res;
},
tangent: function tangent(p0, p1, p2, p3, q0, q1) {
var A, B, C, a, b, c, d, s, r1, r2;
A = cprod(p0, p1, q0, q1);
B = cprod(p1, p2, q0, q1);
C = cprod(p2, p3, q0, q1);
a = A - 2 * B + C;
b = -2 * A + 2 * B;
c = A;
d = b * b - 4 * a * c;
if (a===0 || d<0) {
return -1.0;
}
s = Math.sqrt(d);
r1 = (-b + s) / (2 * a);
r2 = (-b - s) / (2 * a);
if (r1 >= 0 && r1 <= 1) {
return r1;
} else if (r2 >= 0 && r2 <= 1) {
return r2;
} else {
return -1.0;
}
},
mod: mod,
xprod: xprod,
cyclic: cyclic,
sign: sign,
quadform: quadform,
interval: interval,
dorth_infty: dorth_infty,
ddenom: ddenom,
dpara: dpara,
cprod: cprod,
iprod: iprod,
iprod1: iprod1,
ddist: ddist
};