1
0
mirror of https://github.com/svg/svgo.git synced 2025-07-31 07:44:22 +03:00

Fix applying transform to arc with zero radius

Ref https://github.com/svg/svgo/issues/1500
This commit is contained in:
Bogdan Chadkin
2021-08-27 01:03:11 +03:00
parent 1b02799e18
commit ac8edbaf41
2 changed files with 40 additions and 25 deletions

View File

@ -309,12 +309,14 @@ const transformToMatrix = (transform) => {
exports.transformArc = (cursor, arc, transform) => {
const x = arc[5] - cursor[0];
const y = arc[6] - cursor[1];
var a = arc[0],
b = arc[1],
rot = (arc[2] * Math.PI) / 180,
cos = Math.cos(rot),
sin = Math.sin(rot),
h =
let a = arc[0];
let b = arc[1];
const rot = (arc[2] * Math.PI) / 180;
const cos = Math.cos(rot);
const sin = Math.sin(rot);
// skip if radius is 0
if (a > 0 && b > 0) {
let h =
Math.pow(x * cos + y * sin, 2) / (4 * a * a) +
Math.pow(y * cos - x * sin, 2) / (4 * b * b);
if (h > 1) {
@ -322,27 +324,27 @@ exports.transformArc = (cursor, arc, transform) => {
a *= h;
b *= h;
}
var ellipse = [a * cos, a * sin, -b * sin, b * cos, 0, 0],
m = multiplyTransformMatrices(transform, ellipse),
}
const ellipse = [a * cos, a * sin, -b * sin, b * cos, 0, 0];
const m = multiplyTransformMatrices(transform, ellipse);
// Decompose the new ellipse matrix
lastCol = m[2] * m[2] + m[3] * m[3],
squareSum = m[0] * m[0] + m[1] * m[1] + lastCol,
root =
Math.hypot(m[0] - m[3], m[1] + m[2]) *
Math.hypot(m[0] + m[3], m[1] - m[2]);
const lastCol = m[2] * m[2] + m[3] * m[3];
const squareSum = m[0] * m[0] + m[1] * m[1] + lastCol;
const root =
Math.hypot(m[0] - m[3], m[1] + m[2]) * Math.hypot(m[0] + m[3], m[1] - m[2]);
if (!root) {
// circle
arc[0] = arc[1] = Math.sqrt(squareSum / 2);
arc[2] = 0;
} else {
var majorAxisSqr = (squareSum + root) / 2,
minorAxisSqr = (squareSum - root) / 2,
major = Math.abs(majorAxisSqr - lastCol) > 1e-6,
sub = (major ? majorAxisSqr : minorAxisSqr) - lastCol,
rowsSum = m[0] * m[2] + m[1] * m[3],
term1 = m[0] * sub + m[2] * rowsSum,
term2 = m[1] * sub + m[3] * rowsSum;
const majorAxisSqr = (squareSum + root) / 2;
const minorAxisSqr = (squareSum - root) / 2;
const major = Math.abs(majorAxisSqr - lastCol) > 1e-6;
const sub = (major ? majorAxisSqr : minorAxisSqr) - lastCol;
const rowsSum = m[0] * m[2] + m[1] * m[3];
const term1 = m[0] * sub + m[2] * rowsSum;
const term2 = m[1] * sub + m[3] * rowsSum;
arc[0] = Math.sqrt(majorAxisSqr);
arc[1] = Math.sqrt(minorAxisSqr);
arc[2] =

View File

@ -0,0 +1,13 @@
Applying transform to arc with zero radius should not produce NaNs
===
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 31.6 31.6">
<path d="m5.25,2.2H25.13a0,0,0,0,1-.05-.05V14.18Z" transform="translate(0 0)"/>
</svg>
@@@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 31.6 31.6">
<path d="M5.25 2.2h19.88l-.05-.05v12.03Z"/>
</svg>