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:
@ -309,40 +309,42 @@ const transformToMatrix = (transform) => {
|
|||||||
exports.transformArc = (cursor, arc, transform) => {
|
exports.transformArc = (cursor, arc, transform) => {
|
||||||
const x = arc[5] - cursor[0];
|
const x = arc[5] - cursor[0];
|
||||||
const y = arc[6] - cursor[1];
|
const y = arc[6] - cursor[1];
|
||||||
var a = arc[0],
|
let a = arc[0];
|
||||||
b = arc[1],
|
let b = arc[1];
|
||||||
rot = (arc[2] * Math.PI) / 180,
|
const rot = (arc[2] * Math.PI) / 180;
|
||||||
cos = Math.cos(rot),
|
const cos = Math.cos(rot);
|
||||||
sin = Math.sin(rot),
|
const sin = Math.sin(rot);
|
||||||
h =
|
// skip if radius is 0
|
||||||
|
if (a > 0 && b > 0) {
|
||||||
|
let h =
|
||||||
Math.pow(x * cos + y * sin, 2) / (4 * a * a) +
|
Math.pow(x * cos + y * sin, 2) / (4 * a * a) +
|
||||||
Math.pow(y * cos - x * sin, 2) / (4 * b * b);
|
Math.pow(y * cos - x * sin, 2) / (4 * b * b);
|
||||||
if (h > 1) {
|
if (h > 1) {
|
||||||
h = Math.sqrt(h);
|
h = Math.sqrt(h);
|
||||||
a *= h;
|
a *= h;
|
||||||
b *= h;
|
b *= h;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var ellipse = [a * cos, a * sin, -b * sin, b * cos, 0, 0],
|
const ellipse = [a * cos, a * sin, -b * sin, b * cos, 0, 0];
|
||||||
m = multiplyTransformMatrices(transform, ellipse),
|
const m = multiplyTransformMatrices(transform, ellipse);
|
||||||
// Decompose the new ellipse matrix
|
// Decompose the new ellipse matrix
|
||||||
lastCol = m[2] * m[2] + m[3] * m[3],
|
const lastCol = m[2] * m[2] + m[3] * m[3];
|
||||||
squareSum = m[0] * m[0] + m[1] * m[1] + lastCol,
|
const squareSum = m[0] * m[0] + m[1] * m[1] + lastCol;
|
||||||
root =
|
const root =
|
||||||
Math.hypot(m[0] - m[3], m[1] + m[2]) *
|
Math.hypot(m[0] - m[3], m[1] + m[2]) * Math.hypot(m[0] + m[3], m[1] - m[2]);
|
||||||
Math.hypot(m[0] + m[3], m[1] - m[2]);
|
|
||||||
|
|
||||||
if (!root) {
|
if (!root) {
|
||||||
// circle
|
// circle
|
||||||
arc[0] = arc[1] = Math.sqrt(squareSum / 2);
|
arc[0] = arc[1] = Math.sqrt(squareSum / 2);
|
||||||
arc[2] = 0;
|
arc[2] = 0;
|
||||||
} else {
|
} else {
|
||||||
var majorAxisSqr = (squareSum + root) / 2,
|
const majorAxisSqr = (squareSum + root) / 2;
|
||||||
minorAxisSqr = (squareSum - root) / 2,
|
const minorAxisSqr = (squareSum - root) / 2;
|
||||||
major = Math.abs(majorAxisSqr - lastCol) > 1e-6,
|
const major = Math.abs(majorAxisSqr - lastCol) > 1e-6;
|
||||||
sub = (major ? majorAxisSqr : minorAxisSqr) - lastCol,
|
const sub = (major ? majorAxisSqr : minorAxisSqr) - lastCol;
|
||||||
rowsSum = m[0] * m[2] + m[1] * m[3],
|
const rowsSum = m[0] * m[2] + m[1] * m[3];
|
||||||
term1 = m[0] * sub + m[2] * rowsSum,
|
const term1 = m[0] * sub + m[2] * rowsSum;
|
||||||
term2 = m[1] * sub + m[3] * rowsSum;
|
const term2 = m[1] * sub + m[3] * rowsSum;
|
||||||
arc[0] = Math.sqrt(majorAxisSqr);
|
arc[0] = Math.sqrt(majorAxisSqr);
|
||||||
arc[1] = Math.sqrt(minorAxisSqr);
|
arc[1] = Math.sqrt(minorAxisSqr);
|
||||||
arc[2] =
|
arc[2] =
|
||||||
|
13
test/plugins/convertPathData.26.svg
Normal file
13
test/plugins/convertPathData.26.svg
Normal 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>
|
Reference in New Issue
Block a user