Skip to content

Commit

Permalink
Fix error computing Bézier curves bounding boxes (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
mondeja authored May 26, 2022
1 parent 4407f31 commit d735a9f
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 22 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## [1.2.2] - 2022-05-26

- Fixed edge case computing cubic Bézier curves bounding boxes.

## [1.2.1] - 2022-05-12

- Fixed error computing cubic Bézier curves bounding boxes.
Expand Down
10 changes: 5 additions & 5 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ function minmaxQ(A) {
}
// https://github.com/kpym/SVGPathy/blob/acd1a50c626b36d81969f6e98e8602e128ba4302/lib/box.js#L127
function minmaxC(A) {
if (A[0] === A[1] && A[0] === A[3]) {
// no curve, point targeting same location
return [A[0], A[3]];
}
// if the polynomial is (almost) quadratic and not cubic
var K = A[0] - 3 * A[1] + 3 * A[2] - A[3];
// if the polynomial is (almost) quadratic and not cubic
if (Math.abs(K) < CBEZIER_MINMAX_EPSILON) {
if (A[0] === A[3] && A[0] === A[1]) {
// no curve, point targeting same location
return [A[0], A[3]];
}
return minmaxQ([
A[0],
-0.5 * A[0] + 1.5 * A[1],
Expand Down
18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "svg-path-bbox",
"version": "1.2.1",
"version": "1.2.2",
"description": "Compute bounding boxes of SVG paths.",
"keywords": [
"svg",
Expand Down Expand Up @@ -62,7 +62,7 @@
"prettier": "2.6.2",
"puppeteer": "14.0.0",
"rimraf": "3.0.2",
"simple-icons": "6.21.0",
"simple-icons": "6.23.0",
"svg-path-bounding-box": "1.0.4",
"ts-jest": "28.0.2",
"ts-node": "10.7.0",
Expand Down
8 changes: 7 additions & 1 deletion scripts/si-benchmark.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import * as icons from "simple-icons/icons";
import type { SimpleIcon } from "simple-icons";

import runLibrariesBenchmark from "./benchmark";

const EPOCHS = [1000];

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const FILTER = (icon: SimpleIcon) => true;

if (require.main === module) {
runLibrariesBenchmark(
Object.values(icons).map((icon) => [icon.title, icon.path]),
Object.values(icons)
.filter(FILTER)
.map((icon) => [icon.title, icon.path]),
EPOCHS
);
}
11 changes: 6 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@ function minmaxQ(A: [number, number, number]): minMax {

// https://github.com/kpym/SVGPathy/blob/acd1a50c626b36d81969f6e98e8602e128ba4302/lib/box.js#L127
function minmaxC(A: [number, number, number, number]): minMax {
if (A[0] === A[1] && A[0] === A[3]) {
// no curve, point targeting same location
return [A[0], A[3]];
}
const K = A[0] - 3 * A[1] + 3 * A[2] - A[3];

// if the polynomial is (almost) quadratic and not cubic
const K = A[0] - 3 * A[1] + 3 * A[2] - A[3];
if (Math.abs(K) < CBEZIER_MINMAX_EPSILON) {
if (A[0] === A[3] && A[0] === A[1]) {
// no curve, point targeting same location
return [A[0], A[3]];
}

return minmaxQ([
A[0],
-0.5 * A[0] + 1.5 * A[1],
Expand Down
8 changes: 8 additions & 0 deletions tests/cases/bbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,14 @@ export const pathologicalCases: CasesTuple = [
[209.59000000000003, 339.90999999999764, 452.7900000000486, 896.1],
// svg-path-bounding-box: [ 209.59, 339.91, 452.79, 896.1 ]
],

// Tapas
// https://github.com/simple-icons/simple-icons/pull/7442#issuecomment-1137971253
[
"M7.67 1.56c.282-.134.542-.338.81-.513.253-.163.54-.436.894-.33.103.296-.162.503-.331.662-.538.511-1.154.975-1.72 1.456A240.349 240.349 0 0 1 1.5 7.598a7.406 7.406 0 0 1-.612.445c-.183.118-.456.359-.71.165.071-.337.306-.567.512-.778.213-.216.414-.446.629-.66-.248-.427-.473-.821-.662-1.274-.186-.449-.378-.971-.38-1.554-.002-1.109.635-2.043 1.34-2.68C2.34.61 3.306.066 4.429.006 6.015-.078 6.933.71 7.67 1.56zm5.012 18.075v.198c-.278.01-.532-.01-.795-.016v-.198c.277-.008.535.006.795.016zm-1.59 0v.198c-.282-.012-.52.021-.792.018v-.198a9.53 9.53 0 0 1 .793-.018zm3.177.05c-.007.067.013.158-.017.199-.251-.02-.518-.024-.778-.033v-.198c.275.003.542.009.795.032zm-4.763 0v.199c-.274.002-.512.039-.795.032v-.197c.28.001.516-.036.795-.034zm5.555.034c.255.033.544.029.793.064.013.084-.014.129-.015.2-.255-.033-.544-.03-.794-.067a.703.703 0 0 0 .016-.197zm-7.142.065v.2c-.26.02-.517.046-.778.065-.022-.05-.018-.126-.017-.198.265-.024.521-.053.795-.067zm8.73.067c.269.023.537.048.793.082-.02.058-.004.148-.032.199-.25-.036-.518-.053-.778-.083-.01-.083.017-.128.017-.198zm-10.319.082c-.006.08.03.113.017.199-.259.022-.568.082-.793.082.012-.077-.02-.114-.018-.182.252-.045.529-.066.794-.099zm12.684.199c.012.084-.027.114-.017.196-.256-.044-.54-.063-.794-.114.01-.058.025-.109.017-.182.228.008.545.062.795.1zm-14.288 0c.06.022.033.133.05.196-.259.04-.517.08-.777.117a.68.68 0 0 1-.034-.197c.253-.038.515-.072.761-.116zm15.86.233a.628.628 0 0 1-.034.213c-.247-.055-.52-.083-.777-.132a.702.702 0 0 1 .034-.197c.263.032.503.09.776.116zm-17.414.016c.02.057.036.116.034.196-.263.04-.503.105-.778.133-.004-.073-.034-.12-.033-.197.275-.028.515-.092.777-.132zm18.208.132c.255.052.508.109.778.148-.004.072-.034.119-.034.197-.28-.021-.495-.11-.778-.133-.018-.041.016-.15.034-.212zM22.669 16.726c.156.092.47.098.595.246.099.115.144.486.182.744.203 1.296.287 2.808.332 4.219.008.266.016.583.016.891 0 .298.06.704 0 .91-.041.147-.24.194-.363.264a56.558 56.558 0 0 0-.065-2.843c-.124-.101-.444-.047-.464-.166-.044-.252.267-.09.447-.065-.045-1.272-.177-2.46-.33-3.623-.147-.074-.336-.105-.498-.164-.252.259-.636.939-1.223.81-.22-.047-.363-.342-.464-.545a3.243 3.243 0 0 1-.265-.744c-4.88-.936-11.589-1.016-16.502-.05-.153.655-.43 2.053-1.34 1.52a2.014 2.014 0 0 1-.81-.991 8.31 8.31 0 0 1-.547.133c-.192 1.084-.288 2.268-.346 3.489.166.01.416-.122.595-.1.004.066.028.114.033.18-.166.106-.437.105-.645.166a45.286 45.286 0 0 0-.066 2.976c-.08.022-.273-.122-.347-.213.064-2.301.179-4.553.363-6.732.28-.087.568-.17.844-.264-.04-.383-.117-.827.05-1.09.14-.224.531-.352.81-.432.99-.28 1.979-.05 2.63.413.14.102.247.239.396.299.025-.09-.094-.15-.149-.199-.567-.511-1.498-.958-2.612-.761-.348-1.09-.79-2.142-.794-3.538-.005-1.553.562-2.899 1.205-3.953.66-1.078 1.541-1.954 2.498-2.645a11.504 11.504 0 0 1 8.087-2.051c3.01.369 5.008 1.79 6.45 3.853.69.99 1.248 2.174 1.62 3.524.374 1.352.378 3.098-.05 4.53-1.383-.283-2.637.15-3.125 1.026-.004.015-.016.017-.016.033.498-.678 1.736-1.168 2.976-.86.328.082.746.2.908.43.224.317.122.989-.016 1.373zM16.22 9.382c.055.383.227.783.445.944.376.27.602.001.63-.38.035-.504-.174-1.1-.431-1.324-.105-.09-.299-.145-.412-.115-.256.065-.283.528-.232.875zm-8.649 1.092c-.033.556.16 1.277.529 1.472.43.227.633-.095.661-.495.045-.626-.273-1.714-.86-1.605-.25.047-.313.339-.33.628zm6.83 2.579c-.266.06-.633-.058-.926-.117a22.333 22.333 0 0 0-.91-.164c-.567-.088-1.344-.211-1.9.1-.198.11-.444.351-.465.662-.027.46.342.791.612.993.323.237.663.399 1.092.527.917.278 2.293.353 3.075.017.735-.316 1.706-1.062 1.72-2.05.01-.59-.272-1.119-.859-1.042-.65.085-.882.951-1.44 1.074z",
[0.17800000000000005, -0.00016249501660449533, 23.82066666666666, 24],
// svg-path-bounding-box: [ 0.17800000000000005, -0.00016249501660449477, 23.82066666666666, 24 ]
],
];

export default [...linealCases, ...pathologicalCases];

0 comments on commit d735a9f

Please sign in to comment.