svg-path-simplify 0.4.2 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +7 -4
- package/dist/svg-path-simplify.esm.js +3593 -1279
- package/dist/svg-path-simplify.esm.min.js +2 -2
- package/dist/svg-path-simplify.js +3594 -1278
- package/dist/svg-path-simplify.min.js +2 -2
- package/dist/svg-path-simplify.pathdata.esm.js +1017 -538
- package/dist/svg-path-simplify.pathdata.esm.min.js +2 -2
- package/dist/svg-path-simplify.poly.cjs +9 -8
- package/docs/privacy-webapp.md +24 -0
- package/index.html +331 -152
- package/package.json +1 -1
- package/src/constants.js +4 -0
- package/src/css_parse.js +317 -0
- package/src/detect_input.js +76 -28
- package/src/index.js +8 -0
- package/src/pathData_simplify_cubic.js +26 -16
- package/src/pathData_simplify_harmonize_cpts.js +77 -1
- package/src/pathData_simplify_revertToquadratics.js +0 -1
- package/src/pathSimplify-main.js +304 -276
- package/src/pathSimplify-only-pathdata.js +7 -2
- package/src/pathSimplify-presets.js +254 -0
- package/src/poly-fit-curve-schneider.js +14 -7
- package/src/simplify_poly_RC.js +102 -0
- package/src/simplify_poly_RDP.js +109 -1
- package/src/simplify_poly_radial_distance.js +3 -3
- package/src/string_helpers.js +130 -4
- package/src/svg-getAttributes.js +4 -2
- package/src/svgii/convert_units.js +1 -1
- package/src/svgii/geometry.js +322 -5
- package/src/svgii/geometry_bbox_element.js +1 -1
- package/src/svgii/geometry_deduceRadius.js +116 -27
- package/src/svgii/geometry_length.js +253 -0
- package/src/svgii/pathData_analyze.js +18 -0
- package/src/svgii/pathData_convert.js +193 -89
- package/src/svgii/pathData_fix_directions.js +12 -14
- package/src/svgii/pathData_fromPoly.js +3 -3
- package/src/svgii/pathData_getLength.js +86 -0
- package/src/svgii/pathData_parse.js +2 -0
- package/src/svgii/pathData_parse_els.js +66 -68
- package/src/svgii/pathData_reorder.js +122 -16
- package/src/svgii/pathData_simplify_refineCorners.js +130 -35
- package/src/svgii/pathData_simplify_refine_round.js +420 -0
- package/src/svgii/pathData_split_to_groups.js +168 -0
- package/src/svgii/pathData_stringify.js +26 -64
- package/src/svgii/pathData_toPolygon.js +3 -4
- package/src/svgii/poly_analyze.js +61 -0
- package/src/svgii/poly_normalize.js +11 -2
- package/src/svgii/poly_to_pathdata.js +85 -24
- package/src/svgii/rounding.js +80 -78
- package/src/svgii/svg_cleanup.js +421 -619
- package/src/svgii/svg_cleanup_convertPathLength.js +39 -0
- package/src/svgii/svg_cleanup_general_svg_atts.js +97 -0
- package/src/svgii/svg_cleanup_normalize_transforms.js +83 -0
- package/src/svgii/svg_cleanup_remove_els_and_atts.js +77 -0
- package/src/svgii/svg_cleanup_ungroup.js +36 -0
- package/src/svgii/svg_el_parse_style_props.js +72 -47
- package/src/svgii/svg_getElementLength.js +67 -0
- package/src/svgii/svg_validate.js +220 -0
- package/tests/testSVG.js +14 -1
- package/src/svgii/pathData_refine_round.js +0 -222
|
@@ -1,42 +1,92 @@
|
|
|
1
|
-
import { getDeltaAngle, getDistance } from "./geometry";
|
|
1
|
+
import { checkLineIntersection, getDeltaAngle, getDistance, getDistManhattan, getSquareDistance } from "./geometry";
|
|
2
|
+
import { renderPoint } from "./visualize";
|
|
3
|
+
//import { arcToBezierResolved } from "./pathData_convert";
|
|
4
|
+
//import { renderPoint, renderPoly } from "./visualize";
|
|
2
5
|
|
|
3
|
-
export function getArcFromPoly(pts) {
|
|
6
|
+
export function getArcFromPoly(pts, precise = false) {
|
|
4
7
|
if (pts.length < 3) return false
|
|
5
8
|
|
|
6
9
|
// Pick 3 well-spaced points
|
|
7
|
-
let
|
|
8
|
-
let
|
|
9
|
-
let
|
|
10
|
+
let len = pts.length
|
|
11
|
+
let idx1 = Math.floor(len * 0.333)
|
|
12
|
+
let idx2 = Math.floor(len * 0.666)
|
|
13
|
+
let idx3 = Math.floor(len * 0.5)
|
|
10
14
|
|
|
11
|
-
let x1 = p1.x, y1 = p1.y;
|
|
12
|
-
let x2 = p2.x, y2 = p2.y;
|
|
13
|
-
let x3 = p3.x, y3 = p3.y;
|
|
14
15
|
|
|
15
|
-
let
|
|
16
|
-
let
|
|
17
|
-
let
|
|
18
|
-
let d = y1 - y3;
|
|
16
|
+
let p1 = pts[0];
|
|
17
|
+
let p2 = pts[idx3];
|
|
18
|
+
let p3 = pts[len - 1];
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
let
|
|
20
|
+
// Radius (use start point)
|
|
21
|
+
let pts1 = [p1, p2, p3];
|
|
22
|
+
let centroid = getPolyArcCentroid(pts1);
|
|
22
23
|
|
|
23
|
-
let
|
|
24
|
+
let r = 0, deltaAngle = 0, startAngle = 0, endAngle = 0, angleData = {};
|
|
24
25
|
|
|
25
|
-
if (Math.abs(det) < 1e-10) {
|
|
26
|
-
console.warn("Points are collinear or numerically unstable");
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
26
|
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
// check if radii are consistent
|
|
28
|
+
if (precise) {
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* check multiple centroids
|
|
33
|
+
* if the polyline can be expressed as
|
|
34
|
+
* an arc - all centroids should be close
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
if (len > 3) {
|
|
38
|
+
let centroid1 = getPolyArcCentroid([p1, pts[idx1], p3]);
|
|
39
|
+
let centroid2 = getPolyArcCentroid([p1, pts[idx2], p3]);
|
|
40
|
+
|
|
41
|
+
if (!centroid1 || !centroid2) return false;
|
|
42
|
+
|
|
43
|
+
//let dist0 = getDistManhattan(p1, p3)
|
|
44
|
+
let dist0 = getDistManhattan(centroid, p2)
|
|
45
|
+
let dist1 = getDistManhattan(centroid, centroid1)
|
|
46
|
+
let dist2 = getDistManhattan(centroid, centroid2)
|
|
47
|
+
let errorCentroid = (dist1 + dist2)
|
|
48
|
+
|
|
49
|
+
// centroids diverging too much
|
|
50
|
+
if (errorCentroid > dist0 * 0.05) {
|
|
51
|
+
//renderPoint(markers, centroid, 'magenta')
|
|
52
|
+
return false
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
let rSqMid = getSquareDistance(centroid, p2);
|
|
58
|
+
|
|
59
|
+
//check if radii are close enough
|
|
60
|
+
for (let i = 0; i < len; i++) {
|
|
61
|
+
let pt = pts[i]
|
|
62
|
+
let rSq = getSquareDistance(centroid, pt);
|
|
63
|
+
let error = Math.abs(rSqMid - rSq) / rSqMid
|
|
64
|
+
|
|
65
|
+
if (error > 0.0025) {
|
|
66
|
+
/*
|
|
67
|
+
console.log('error', error, len, idx1, idx2, idx3);
|
|
68
|
+
renderPoint(markers, centroid, 'orange')
|
|
69
|
+
renderPoint(markers, p1, 'green')
|
|
70
|
+
renderPoint(markers, p2)
|
|
71
|
+
renderPoint(markers, p3, 'purple')
|
|
72
|
+
*/
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// calculate proper radius
|
|
78
|
+
r = Math.sqrt(rSqMid);
|
|
79
|
+
angleData = getDeltaAngle(centroid, p1, p3);
|
|
80
|
+
({ deltaAngle, startAngle, endAngle } = angleData);
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
} else {
|
|
84
|
+
r = getDistance(centroid, p1);
|
|
85
|
+
angleData = getDeltaAngle(centroid, p1, p3);
|
|
86
|
+
({ deltaAngle, startAngle, endAngle } = angleData);
|
|
87
|
+
}
|
|
34
88
|
|
|
35
|
-
// Radius (use start point)
|
|
36
|
-
let r = getDistance(centroid, p1);
|
|
37
89
|
|
|
38
|
-
let angleData = getDeltaAngle(centroid, p1, p3)
|
|
39
|
-
let {deltaAngle, startAngle, endAngle} = angleData;
|
|
40
90
|
|
|
41
91
|
return {
|
|
42
92
|
centroid,
|
|
@@ -48,3 +98,42 @@ export function getArcFromPoly(pts) {
|
|
|
48
98
|
}
|
|
49
99
|
|
|
50
100
|
|
|
101
|
+
|
|
102
|
+
export function getPolyArcCentroid(pts = []) {
|
|
103
|
+
|
|
104
|
+
pts = pts.filter(pt => pt !== undefined);
|
|
105
|
+
if (pts.length < 3) return false
|
|
106
|
+
//console.log(pts);
|
|
107
|
+
|
|
108
|
+
let p1 = pts[0];
|
|
109
|
+
let p2 = pts[Math.floor(pts.length / 2)];
|
|
110
|
+
let p3 = pts[pts.length - 1];
|
|
111
|
+
|
|
112
|
+
let x1 = p1.x, y1 = p1.y;
|
|
113
|
+
let x2 = p2.x, y2 = p2.y;
|
|
114
|
+
let x3 = p3.x, y3 = p3.y;
|
|
115
|
+
|
|
116
|
+
let a = x1 - x2;
|
|
117
|
+
let b = y1 - y2;
|
|
118
|
+
let c = x1 - x3;
|
|
119
|
+
let d = y1 - y3;
|
|
120
|
+
|
|
121
|
+
let e = ((x1 * x1 - x2 * x2) + (y1 * y1 - y2 * y2)) / 2;
|
|
122
|
+
let f = ((x1 * x1 - x3 * x3) + (y1 * y1 - y3 * y3)) / 2;
|
|
123
|
+
|
|
124
|
+
let det = a * d - b * c;
|
|
125
|
+
|
|
126
|
+
// colinear points
|
|
127
|
+
if (Math.abs(det) < 1e-10) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// find center of arc
|
|
132
|
+
let cx = (d * e - b * f) / det;
|
|
133
|
+
let cy = (-c * e + a * f) / det;
|
|
134
|
+
let centroid = { x: cx, y: cy };
|
|
135
|
+
return centroid
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { getDistance, getDistManhattan } from "./geometry";
|
|
2
|
+
|
|
3
|
+
// Legendre Gauss weight and abscissa values
|
|
4
|
+
export const waArr_global = [];
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export function getLength(pts, {
|
|
9
|
+
t = 1,
|
|
10
|
+
waArr = []
|
|
11
|
+
} = {}) {
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
const cubicBezierLength = (p0, cp1, cp2, p, t = 0, wa = []) => {
|
|
15
|
+
if (t === 0) {
|
|
16
|
+
return 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
t = t > 1 ? 1 : t < 0 ? 0 : t;
|
|
20
|
+
let t2 = t / 2;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* set higher legendre gauss weight abscissae values
|
|
24
|
+
* by more accurate weight/abscissae lookups
|
|
25
|
+
* https://pomax.github.io/bezierinfo/legendre-gauss.html
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
let sum = 0;
|
|
30
|
+
|
|
31
|
+
let x0 = p0.x, y0 = p0.y, cp1x = cp1.x, cp1y = cp1.y, cp2x = cp2.x, cp2y = cp2.y, px = p.x, py = p.y;
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
for (let i = 0, len = wa.length; i < len; i++) {
|
|
35
|
+
// weight and abscissae
|
|
36
|
+
let [w, a] = [wa[i][0], wa[i][1]];
|
|
37
|
+
let ct1_t = t2 * a;
|
|
38
|
+
let ct0 = -ct1_t + t2;
|
|
39
|
+
|
|
40
|
+
let xbase0 = base3(ct0, x0, cp1x, cp2x, px)
|
|
41
|
+
let ybase0 = base3(ct0, y0, cp1y, cp2y, py)
|
|
42
|
+
|
|
43
|
+
let comb0 = xbase0 * xbase0 + ybase0 * ybase0;
|
|
44
|
+
|
|
45
|
+
sum += w * Math.sqrt(comb0)
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
return t2 * sum;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
const quadraticBezierLength = (p0, cp1, p, t, checkFlat = false) => {
|
|
53
|
+
if (t === 0) {
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
// is flat/linear – treat as line
|
|
57
|
+
if (checkFlat) {
|
|
58
|
+
let l1 = getDistance(p0, cp1) + getDistance(cp1, p);
|
|
59
|
+
let l2 = getDistance(p0, p);
|
|
60
|
+
if (l1 === l2) {
|
|
61
|
+
return l2;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let a, b, c, d, e, e1, d1, v1x, v1y;
|
|
66
|
+
v1x = cp1.x * 2;
|
|
67
|
+
v1y = cp1.y * 2;
|
|
68
|
+
d = p0.x - v1x + p.x;
|
|
69
|
+
d1 = p0.y - v1y + p.y;
|
|
70
|
+
e = v1x - 2 * p0.x;
|
|
71
|
+
e1 = v1y - 2 * p0.y;
|
|
72
|
+
a = 4 * (d * d + d1 * d1);
|
|
73
|
+
b = 4 * (d * e + d1 * e1);
|
|
74
|
+
c = e * e + e1 * e1;
|
|
75
|
+
|
|
76
|
+
const bt = b / (2 * a),
|
|
77
|
+
ct = c / a,
|
|
78
|
+
ut = t + bt,
|
|
79
|
+
//k = ct - bt ** 2;
|
|
80
|
+
k = ct - bt * bt;
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
(Math.sqrt(a) / 2) *
|
|
84
|
+
(ut * Math.sqrt(ut * ut + k) -
|
|
85
|
+
bt * Math.sqrt(bt * bt + k) +
|
|
86
|
+
k *
|
|
87
|
+
Math.log((ut + Math.sqrt(ut * ut + k)) / (bt + Math.sqrt(bt * bt + k))))
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
let length
|
|
93
|
+
if (pts.length === 4) {
|
|
94
|
+
length = cubicBezierLength(pts[0], pts[1], pts[2], pts[3], t, waArr)
|
|
95
|
+
|
|
96
|
+
}
|
|
97
|
+
else if (pts.length === 3) {
|
|
98
|
+
length = quadraticBezierLength(pts[0], pts[1], pts[2], t)
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
length = getDistance(pts[0], pts[1])
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return length;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
// LG weight/abscissae generator
|
|
113
|
+
export function getLegendreGaussValues(n, x1 = -1, x2 = 1) {
|
|
114
|
+
console.log('add new LG', n);
|
|
115
|
+
|
|
116
|
+
let waArr = []
|
|
117
|
+
let z1, z, xm, xl, pp, p3, p2, p1;
|
|
118
|
+
const m = (n + 1) >> 1;
|
|
119
|
+
xm = 0.5 * (x2 + x1);
|
|
120
|
+
xl = 0.5 * (x2 - x1);
|
|
121
|
+
|
|
122
|
+
for (let i = m - 1; i >= 0; i--) {
|
|
123
|
+
z = Math.cos((Math.PI * (i + 0.75)) / (n + 0.5));
|
|
124
|
+
do {
|
|
125
|
+
p1 = 1;
|
|
126
|
+
p2 = 0;
|
|
127
|
+
for (let j = 0; j < n; j++) {
|
|
128
|
+
//Loop up the recurrence relation to get the Legendre polynomial evaluated at z.
|
|
129
|
+
p3 = p2;
|
|
130
|
+
p2 = p1;
|
|
131
|
+
p1 = ((2 * j + 1) * z * p2 - j * p3) / (j + 1);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
pp = (n * (z * p1 - p2)) / (z * z - 1);
|
|
135
|
+
z1 = z;
|
|
136
|
+
z = z1 - p1 / pp; //Newton’s method
|
|
137
|
+
|
|
138
|
+
} while (Math.abs(z - z1) > 1.0e-14);
|
|
139
|
+
|
|
140
|
+
let weight = (2 * xl) / ((1 - z * z) * pp * pp);
|
|
141
|
+
let abscissa = xm + xl * z;
|
|
142
|
+
|
|
143
|
+
waArr.push(
|
|
144
|
+
[weight, -abscissa],
|
|
145
|
+
[weight, abscissa],
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return waArr;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
export function base3(t, p1, p2, p3, p4) {
|
|
157
|
+
let t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4,
|
|
158
|
+
t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3;
|
|
159
|
+
return t * t2 - 3 * p1 + 3 * p2;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
export function getPolygonLength(pts=[], isPoly=false){
|
|
164
|
+
|
|
165
|
+
let len = 0;
|
|
166
|
+
let l=pts.length;
|
|
167
|
+
|
|
168
|
+
for(let i=1; i<l; i++){
|
|
169
|
+
let p1 = pts[i-1]
|
|
170
|
+
let p2 = pts[i]
|
|
171
|
+
len += getDistance(p1, p2)
|
|
172
|
+
}
|
|
173
|
+
if(isPoly){
|
|
174
|
+
len += getDistance(pts[l-1], pts[0])
|
|
175
|
+
}
|
|
176
|
+
return len
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export function getPolygonLengthManhattan(pts=[], isPoly=false){
|
|
180
|
+
|
|
181
|
+
let len = 0;
|
|
182
|
+
let l=pts.length;
|
|
183
|
+
|
|
184
|
+
for(let i=1; i<l; i++){
|
|
185
|
+
let p1 = pts[i-1]
|
|
186
|
+
let p2 = pts[i]
|
|
187
|
+
len += getDistManhattan(p1, p2)
|
|
188
|
+
}
|
|
189
|
+
if(isPoly){
|
|
190
|
+
len += getDistManhattan(pts[l-1], pts[0])
|
|
191
|
+
}
|
|
192
|
+
return len
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Ramanujan approximation
|
|
198
|
+
* based on: https://www.mathsisfun.com/geometry/ellipse-perimeter.html#tool
|
|
199
|
+
*/
|
|
200
|
+
export function getEllipseLength(rx=0, ry=0) {
|
|
201
|
+
// is circle
|
|
202
|
+
if (rx === ry) {
|
|
203
|
+
//console.log('is circle')
|
|
204
|
+
return 2 * Math.PI * rx;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
let c=rx+ry
|
|
208
|
+
let d = (rx - ry) / c;
|
|
209
|
+
let h = d*d
|
|
210
|
+
|
|
211
|
+
let totalLength = Math.PI * c * (1 + 3 * h / (10 + Math.sqrt(4 - 3 * h) ));
|
|
212
|
+
return totalLength;
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* ellipse helpers
|
|
219
|
+
* approximate ellipse length
|
|
220
|
+
* by Legendre-Gauss
|
|
221
|
+
*/
|
|
222
|
+
|
|
223
|
+
export function getCircleArcLength(r = 0, deltaAngle = 0) {
|
|
224
|
+
if(r===0) {
|
|
225
|
+
console.warn('Radius must be positive');
|
|
226
|
+
return 0;
|
|
227
|
+
}
|
|
228
|
+
let len = 2 * Math.PI * r * (1 / 360 * Math.abs(deltaAngle * 180 / Math.PI))
|
|
229
|
+
return len
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export function getEllipseLengthLG(rx, ry, startAngle, endAngle, wa = []) {
|
|
233
|
+
|
|
234
|
+
// Transform [-1, 1] interval to [startAngle, endAngle]
|
|
235
|
+
let halfInterval = (endAngle - startAngle) * 0.5;
|
|
236
|
+
let midpoint = (endAngle + startAngle) * 0.5;
|
|
237
|
+
|
|
238
|
+
// Arc length integral approximation
|
|
239
|
+
let arcLength = 0;
|
|
240
|
+
for (let i = 0; i < wa.length; i++) {
|
|
241
|
+
let [weight, abscissae] = wa[i];
|
|
242
|
+
let theta = midpoint + halfInterval * abscissae;
|
|
243
|
+
|
|
244
|
+
let a = rx * Math.sin(theta);
|
|
245
|
+
let b = ry * Math.cos(theta);
|
|
246
|
+
let integrand = Math.sqrt(
|
|
247
|
+
a * a + b * b
|
|
248
|
+
);
|
|
249
|
+
arcLength += weight * integrand;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return Math.abs(halfInterval * arcLength)
|
|
253
|
+
}
|
|
@@ -67,6 +67,7 @@ export function analyzePathData(pathData = [], {
|
|
|
67
67
|
let { type, values, p0, p, cp1 = null, cp2 = null, squareDist = 0, cptArea = 0, dimA = 0 } = com;
|
|
68
68
|
|
|
69
69
|
//next command
|
|
70
|
+
let comPrev = pathData[c-2];
|
|
70
71
|
let comN = pathData[c] || null;
|
|
71
72
|
|
|
72
73
|
|
|
@@ -93,6 +94,7 @@ export function analyzePathData(pathData = [], {
|
|
|
93
94
|
|
|
94
95
|
// bezier types
|
|
95
96
|
let isBezier = type === 'Q' || type === 'C';
|
|
97
|
+
let isArc = type === 'A';
|
|
96
98
|
let isBezierN = comN && (comN.type === 'Q' || comN.type === 'C');
|
|
97
99
|
|
|
98
100
|
|
|
@@ -149,6 +151,22 @@ export function analyzePathData(pathData = [], {
|
|
|
149
151
|
}
|
|
150
152
|
}
|
|
151
153
|
|
|
154
|
+
// check extremes introduce by small arcs
|
|
155
|
+
else if(isArc && comN && ((comPrev.type==='C' || comPrev.type==='Q') || (comN.type==='C' || comN.type==='Q')) ){
|
|
156
|
+
let distN = comN ? comN.dimA : 0
|
|
157
|
+
let isShort = com.dimA < (comPrev.dimA + distN) * 0.1;
|
|
158
|
+
let smallRadius = com.values[0] === com.values[1] && (com.values[0] < 1)
|
|
159
|
+
|
|
160
|
+
if(isShort && smallRadius){
|
|
161
|
+
let bb = getPolyBBox([comPrev.p0, comN.p])
|
|
162
|
+
if(p.x>bb.right || p.x<bb.x || p.y<bb.y || p.y>bb.bottom){
|
|
163
|
+
hasExtremes = true;
|
|
164
|
+
//renderPoint(markers, p)
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
}
|
|
169
|
+
|
|
152
170
|
if (hasExtremes) com.extreme = true
|
|
153
171
|
|
|
154
172
|
// Corners and semi extremes
|