You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
3.7 KiB
125 lines
3.7 KiB
4 weeks ago
|
import * as vec2 from './vector.js';
|
||
|
import * as curve from './curve.js';
|
||
|
var mathMin = Math.min;
|
||
|
var mathMax = Math.max;
|
||
|
var mathSin = Math.sin;
|
||
|
var mathCos = Math.cos;
|
||
|
var PI2 = Math.PI * 2;
|
||
|
var start = vec2.create();
|
||
|
var end = vec2.create();
|
||
|
var extremity = vec2.create();
|
||
|
export function fromPoints(points, min, max) {
|
||
|
if (points.length === 0) {
|
||
|
return;
|
||
|
}
|
||
|
var p = points[0];
|
||
|
var left = p[0];
|
||
|
var right = p[0];
|
||
|
var top = p[1];
|
||
|
var bottom = p[1];
|
||
|
for (var i = 1; i < points.length; i++) {
|
||
|
p = points[i];
|
||
|
left = mathMin(left, p[0]);
|
||
|
right = mathMax(right, p[0]);
|
||
|
top = mathMin(top, p[1]);
|
||
|
bottom = mathMax(bottom, p[1]);
|
||
|
}
|
||
|
min[0] = left;
|
||
|
min[1] = top;
|
||
|
max[0] = right;
|
||
|
max[1] = bottom;
|
||
|
}
|
||
|
export function fromLine(x0, y0, x1, y1, min, max) {
|
||
|
min[0] = mathMin(x0, x1);
|
||
|
min[1] = mathMin(y0, y1);
|
||
|
max[0] = mathMax(x0, x1);
|
||
|
max[1] = mathMax(y0, y1);
|
||
|
}
|
||
|
var xDim = [];
|
||
|
var yDim = [];
|
||
|
export function fromCubic(x0, y0, x1, y1, x2, y2, x3, y3, min, max) {
|
||
|
var cubicExtrema = curve.cubicExtrema;
|
||
|
var cubicAt = curve.cubicAt;
|
||
|
var n = cubicExtrema(x0, x1, x2, x3, xDim);
|
||
|
min[0] = Infinity;
|
||
|
min[1] = Infinity;
|
||
|
max[0] = -Infinity;
|
||
|
max[1] = -Infinity;
|
||
|
for (var i = 0; i < n; i++) {
|
||
|
var x = cubicAt(x0, x1, x2, x3, xDim[i]);
|
||
|
min[0] = mathMin(x, min[0]);
|
||
|
max[0] = mathMax(x, max[0]);
|
||
|
}
|
||
|
n = cubicExtrema(y0, y1, y2, y3, yDim);
|
||
|
for (var i = 0; i < n; i++) {
|
||
|
var y = cubicAt(y0, y1, y2, y3, yDim[i]);
|
||
|
min[1] = mathMin(y, min[1]);
|
||
|
max[1] = mathMax(y, max[1]);
|
||
|
}
|
||
|
min[0] = mathMin(x0, min[0]);
|
||
|
max[0] = mathMax(x0, max[0]);
|
||
|
min[0] = mathMin(x3, min[0]);
|
||
|
max[0] = mathMax(x3, max[0]);
|
||
|
min[1] = mathMin(y0, min[1]);
|
||
|
max[1] = mathMax(y0, max[1]);
|
||
|
min[1] = mathMin(y3, min[1]);
|
||
|
max[1] = mathMax(y3, max[1]);
|
||
|
}
|
||
|
export function fromQuadratic(x0, y0, x1, y1, x2, y2, min, max) {
|
||
|
var quadraticExtremum = curve.quadraticExtremum;
|
||
|
var quadraticAt = curve.quadraticAt;
|
||
|
var tx = mathMax(mathMin(quadraticExtremum(x0, x1, x2), 1), 0);
|
||
|
var ty = mathMax(mathMin(quadraticExtremum(y0, y1, y2), 1), 0);
|
||
|
var x = quadraticAt(x0, x1, x2, tx);
|
||
|
var y = quadraticAt(y0, y1, y2, ty);
|
||
|
min[0] = mathMin(x0, x2, x);
|
||
|
min[1] = mathMin(y0, y2, y);
|
||
|
max[0] = mathMax(x0, x2, x);
|
||
|
max[1] = mathMax(y0, y2, y);
|
||
|
}
|
||
|
export function fromArc(x, y, rx, ry, startAngle, endAngle, anticlockwise, min, max) {
|
||
|
var vec2Min = vec2.min;
|
||
|
var vec2Max = vec2.max;
|
||
|
var diff = Math.abs(startAngle - endAngle);
|
||
|
if (diff % PI2 < 1e-4 && diff > 1e-4) {
|
||
|
min[0] = x - rx;
|
||
|
min[1] = y - ry;
|
||
|
max[0] = x + rx;
|
||
|
max[1] = y + ry;
|
||
|
return;
|
||
|
}
|
||
|
start[0] = mathCos(startAngle) * rx + x;
|
||
|
start[1] = mathSin(startAngle) * ry + y;
|
||
|
end[0] = mathCos(endAngle) * rx + x;
|
||
|
end[1] = mathSin(endAngle) * ry + y;
|
||
|
vec2Min(min, start, end);
|
||
|
vec2Max(max, start, end);
|
||
|
startAngle = startAngle % (PI2);
|
||
|
if (startAngle < 0) {
|
||
|
startAngle = startAngle + PI2;
|
||
|
}
|
||
|
endAngle = endAngle % (PI2);
|
||
|
if (endAngle < 0) {
|
||
|
endAngle = endAngle + PI2;
|
||
|
}
|
||
|
if (startAngle > endAngle && !anticlockwise) {
|
||
|
endAngle += PI2;
|
||
|
}
|
||
|
else if (startAngle < endAngle && anticlockwise) {
|
||
|
startAngle += PI2;
|
||
|
}
|
||
|
if (anticlockwise) {
|
||
|
var tmp = endAngle;
|
||
|
endAngle = startAngle;
|
||
|
startAngle = tmp;
|
||
|
}
|
||
|
for (var angle = 0; angle < endAngle; angle += Math.PI / 2) {
|
||
|
if (angle > startAngle) {
|
||
|
extremity[0] = mathCos(angle) * rx + x;
|
||
|
extremity[1] = mathSin(angle) * ry + y;
|
||
|
vec2Min(min, extremity, min);
|
||
|
vec2Max(max, extremity, max);
|
||
|
}
|
||
|
}
|
||
|
}
|