svg-path-simplify 0.1.3 → 0.2.2

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.
Files changed (43) hide show
  1. package/README.md +10 -0
  2. package/dist/svg-path-simplify.esm.js +3905 -1533
  3. package/dist/svg-path-simplify.esm.min.js +13 -1
  4. package/dist/svg-path-simplify.js +3923 -1551
  5. package/dist/svg-path-simplify.min.js +13 -1
  6. package/dist/svg-path-simplify.min.js.gz +0 -0
  7. package/index.html +61 -31
  8. package/package.json +3 -5
  9. package/src/constants.js +3 -0
  10. package/src/index-node.js +0 -1
  11. package/src/index.js +26 -0
  12. package/src/pathData_simplify_cubic.js +74 -31
  13. package/src/pathData_simplify_cubicsToArcs.js +566 -0
  14. package/src/pathData_simplify_harmonize_cpts.js +170 -0
  15. package/src/pathData_simplify_revertToquadratics.js +21 -0
  16. package/src/pathSimplify-main.js +253 -86
  17. package/src/poly-fit-curve-schneider.js +570 -0
  18. package/src/simplify_poly_RDP.js +146 -0
  19. package/src/simplify_poly_radial_distance.js +100 -0
  20. package/src/svg_getViewbox.js +1 -1
  21. package/src/svgii/geometry.js +389 -63
  22. package/src/svgii/geometry_area.js +2 -1
  23. package/src/svgii/pathData_analyze.js +259 -212
  24. package/src/svgii/pathData_convert.js +91 -663
  25. package/src/svgii/pathData_fromPoly.js +12 -0
  26. package/src/svgii/pathData_parse.js +90 -89
  27. package/src/svgii/pathData_parse_els.js +3 -0
  28. package/src/svgii/pathData_parse_fontello.js +449 -0
  29. package/src/svgii/pathData_remove_collinear.js +44 -37
  30. package/src/svgii/pathData_reorder.js +2 -1
  31. package/src/svgii/pathData_simplify_redraw.js +343 -0
  32. package/src/svgii/pathData_simplify_refineCorners.js +18 -9
  33. package/src/svgii/pathData_simplify_refineExtremes.js +19 -78
  34. package/src/svgii/pathData_split.js +42 -45
  35. package/src/svgii/pathData_toPolygon.js +130 -4
  36. package/src/svgii/poly_analyze.js +470 -14
  37. package/src/svgii/poly_to_pathdata.js +224 -19
  38. package/src/svgii/rounding.js +55 -112
  39. package/src/svgii/svg_cleanup.js +13 -1
  40. package/src/svgii/visualize.js +8 -3
  41. package/{debug.cjs → tests/debug.cjs} +3 -0
  42. /package/{test.js → tests/test.js} +0 -0
  43. /package/{testSVG.js → tests/testSVG.js} +0 -0
@@ -0,0 +1,343 @@
1
+ import { checkLineIntersection, getDistManhattan, pointAtT } from "./geometry";
2
+ import { pathDataToD } from "./pathData_stringify";
3
+ import { renderPath, renderPoint } from "./visualize";
4
+
5
+ export function redrawPathData(pathData, {
6
+ tolerance = 1
7
+
8
+ } = {}) {
9
+
10
+ let pathDataN = [];
11
+ let chunks = [];
12
+ let chunk = [];
13
+ let idx = 0;
14
+
15
+
16
+ let l = pathData.length;
17
+ //return pathData
18
+
19
+ //console.log('pathData', pathData);
20
+
21
+ //let d0 = pathDataToD(pathData)
22
+ //console.log(d0);
23
+
24
+ for (let i = 1; i < l; i++) {
25
+ let com = pathData[i];
26
+ let { type, values, p0, cp1 = null, cp2 = null, p, extreme = null, semiExtreme = null, corner = null, directionChange } = com;
27
+
28
+ let comN = pathData[i + 1] || null;
29
+
30
+ /*
31
+ if (extreme || corner || semiExtreme || directionChange) {
32
+
33
+ if (extreme) renderPoint(markers, com.p, 'cyan', '1%', '0.5')
34
+ //if(directionChange) renderPoint(markers, com.p, 'blue', '1.75%', '0.5')
35
+ if (semiExtreme) renderPoint(markers, com.p, 'orange', '1%', '0.5')
36
+ if (corner) renderPoint(markers, com.p, 'magenta', '1.75%', '0.5')
37
+ }
38
+ */
39
+
40
+
41
+ //start new chunk
42
+ if (extreme || corner || (comN && comN.type !== type)) {
43
+ chunk.push(com)
44
+ chunks.push(chunk)
45
+ chunk = []
46
+ continue
47
+ }
48
+
49
+ chunk.push(com)
50
+
51
+ }
52
+
53
+ console.log('!!!chunks', chunks);
54
+
55
+ renderChunks(chunks)
56
+
57
+
58
+
59
+ // cleanup chunks
60
+ //let chunksClean = [];
61
+
62
+ let chunksLen = chunks.length;
63
+
64
+
65
+
66
+
67
+ for (let c = 0; c < chunksLen; c++) {
68
+ let chunk = chunks[c];
69
+ let chunkN = chunks[c + 1] || null;
70
+
71
+ let chunkLen = chunk.length;
72
+
73
+ if(c===chunksLen-1){
74
+ // renderPoint(markers, chunk[chunkLen-1].p, 'magenta', '0.5%', '0.5')
75
+ }
76
+
77
+ if (chunkLen === 1 && chunkN && chunkN[0].type === 'C') {
78
+ //renderPoint(markers, chunk[0].p, 'red', '0.5%', '0.5')
79
+ //renderPoint(markers, chunkN[0].cp1, 'magenta', '0.5%', '0.5')
80
+ //chunkN[0].p0 = chunk[0].p0
81
+ //chunks[c] = null
82
+ }
83
+
84
+ //chunksClean.push(chunk)
85
+ }
86
+
87
+ chunks = chunks.filter(Boolean)
88
+
89
+ // test render
90
+ //renderChunks(chunks)
91
+
92
+
93
+
94
+
95
+ let pathDataC = [pathData[0]];
96
+ let stroke = 'green';
97
+
98
+
99
+ /**
100
+ * combine chunk based
101
+ */
102
+ for (let c = 0; c < chunks.length; c++) {
103
+ let chunk = chunks[c]
104
+ let chunkLen = chunk.length;
105
+
106
+ stroke = c % 2 === 0 ? 'orange' : 'green';
107
+ let comChunk0 = chunk[0]
108
+ let comChunk1 = chunk[chunkLen - 1]
109
+ let thresh = getDistManhattan(comChunk0.p0, comChunk1.p) * 0.05
110
+
111
+
112
+ // commands in chunk
113
+ for (let i = 0, l = chunkLen; i < l; i++) {
114
+ let com = chunk[i];
115
+ let comN = chunk[i + 1];
116
+ let comL = chunk[l - 1];
117
+
118
+ let isBezier = comChunk0.type === 'C' && comChunk1.type === 'C'
119
+
120
+ //console.log(com);
121
+ let { type, values, p0, cp1 = null, cp2 = null, p = null, extreme, semiExtreme = null, corner = null } = com;
122
+
123
+ let pI1 = null, pI2 = null;
124
+ let cp1_S = null, cp2_S = null;
125
+ let cp2_M = null;
126
+ let cp1_M = null;
127
+ let pathDataS = [];
128
+ let tSplit = 0.666
129
+ let comMid = null;
130
+
131
+ // 0. adjust Extreme cpts
132
+ if (isBezier) {
133
+ let dx1 = Math.abs(comChunk0.p0.x - comChunk0.cp1.x)
134
+ let dy1 = Math.abs(comChunk0.p0.y - comChunk0.cp1.y)
135
+ let dx2 = Math.abs(comChunk1.p.x - comChunk1.cp2.x)
136
+ let dy2 = Math.abs(comChunk1.p.y - comChunk1.cp2.y)
137
+
138
+
139
+ let vertical1 = dx1 < thresh && dx1 < dy1;
140
+ let horizontal1 = dy1 < thresh && dx1 > dy1;
141
+
142
+ let vertical2 = dx2 < thresh && dx2 < dy2;
143
+ let horizontal2 = dy2 < thresh && dx2 > dy2;
144
+
145
+ if (horizontal1) comChunk0.cp1.y = comChunk0.p0.y
146
+ if (horizontal2) comChunk1.cp2.y = comChunk1.p.y
147
+ if (vertical1) comChunk0.cp1.x = comChunk0.p0.x
148
+ if (vertical2) comChunk1.cp2.x = comChunk1.p.x
149
+ }
150
+
151
+
152
+ // test render - original pathdata
153
+ let pathDataChunk = [
154
+ { type: 'M', values: [com.p0.x, com.p0.y] },
155
+ { type, values },
156
+ ];
157
+
158
+
159
+ let d = pathDataToD(pathDataChunk);
160
+ // renderPath(markers, d, stroke, '1%', '0.5')
161
+ // continue
162
+ /*
163
+
164
+ */
165
+
166
+
167
+ // 1. only one command in chunk - nothing to simplify
168
+ if (chunkLen === 1 || type !== 'C') {
169
+ stroke = 'red'
170
+ pathDataC.push(com)
171
+ }
172
+
173
+
174
+
175
+ // 2. could be simplified
176
+ else {
177
+ // 2.1 has semi extreme - extrapolate
178
+ // 2.2 has sdirection change
179
+ let semiExtremes = chunk.filter(ch => ch.semiExtreme);
180
+ let comsDirectionChange = chunk.filter(ch => ch.directionChange)
181
+
182
+
183
+ if (semiExtremes.length || comsDirectionChange.length) {
184
+ stroke = c % 2 === 0 ? 'purple' : 'magenta';
185
+
186
+ // semiExtreme command
187
+ comMid = semiExtremes.length ? semiExtremes[0] : comsDirectionChange[0];
188
+
189
+ // zero length cpt vectors
190
+ if (comChunk0.p0.x === comChunk0.cp1.x && comChunk0.p0.y === comChunk0.cp1.y) {
191
+ comChunk0.cp1 = pointAtT([comChunk0.p0, comChunk0.cp1, comChunk0.cp2, comChunk0.p], 0.5)
192
+ }
193
+ else if (comChunk1.p.x === comChunk1.cp2.x && comChunk1.p.y === comChunk1.cp2.y) {
194
+ comChunk1.cp2 = pointAtT([comChunk1.p0, comChunk1.cp1, comChunk1.cp2, comChunk1.p], 0.5)
195
+ }
196
+
197
+
198
+ pI1 = checkLineIntersection(comMid.p, comMid.cp2, comChunk0.p0, comChunk0.cp1, false)
199
+ pI2 = checkLineIntersection(comMid.p, comMid.cp2, comChunk1.p, comChunk1.cp2, false)
200
+
201
+
202
+ // intersections try to extrapolate cpts
203
+ if (pI1 && pI2) {
204
+
205
+ cp1_S = pointAtT([comChunk0.p0, pI1], tSplit)
206
+ cp2_S = pointAtT([comChunk1.p, pI2], tSplit)
207
+
208
+ cp2_M = pointAtT([comMid.p, pI1], tSplit)
209
+ cp1_M = pointAtT([comMid.p, pI2], tSplit)
210
+
211
+ /*
212
+ renderPoint(markers, cp1_S, 'magenta', '1%', '1' )
213
+ */
214
+
215
+ pathDataS = [
216
+ { type: 'M', values: [comChunk0.p0.x, comChunk0.p0.y] },
217
+ {
218
+ type: 'C', values: [
219
+ cp1_S.x, cp1_S.y,
220
+ cp2_M.x, cp2_M.y,
221
+ comMid.p.x,
222
+ comMid.p.y
223
+ ]
224
+ },
225
+ {
226
+ type: 'C', values: [
227
+ cp1_M.x, cp1_M.y,
228
+ cp2_S.x, cp2_S.y,
229
+ comChunk1.p.x,
230
+ comChunk1.p.y,
231
+ ]
232
+ },
233
+ ];
234
+
235
+ stroke = c % 2 === 0 ? 'green' : 'gold'
236
+ d = pathDataToD(pathDataS)
237
+
238
+ //renderPath(markers, d, 'green', '1%', '0.5')
239
+
240
+
241
+ pathDataC.push(
242
+ {
243
+ type: 'C', values: [
244
+ cp1_S.x, cp1_S.y,
245
+ cp2_M.x, cp2_M.y,
246
+ comMid.p.x,
247
+ comMid.p.y
248
+ ],
249
+ p0: comChunk0.p0,
250
+ cp1: cp1_S,
251
+ cp2: cp2_M,
252
+ p: comMid.p,
253
+ dimA: getDistManhattan(comChunk0.p0, comMid.p)
254
+ },
255
+
256
+ {
257
+ type: 'C', values: [
258
+ cp1_M.x, cp1_M.y,
259
+ cp2_S.x, cp2_S.y,
260
+ comChunk1.p.x,
261
+ comChunk1.p.y,
262
+ ],
263
+ p0: comMid.p,
264
+ cp1: cp1_M,
265
+ cp2: cp2_S,
266
+ p: comChunk1.p,
267
+ extreme: true,
268
+ dimA: getDistManhattan(comMid.p, comChunk1.p)
269
+
270
+ }
271
+ )
272
+ break
273
+
274
+ }
275
+ } else {
276
+ pathDataC.push(com)
277
+ }
278
+
279
+ }
280
+
281
+ }
282
+
283
+ }
284
+
285
+ /*
286
+ // render
287
+ let d = pathDataToD(pathDataC)
288
+ console.log(d);
289
+ renderPath(markers, d, 'red', '1%', '0.5')
290
+ */
291
+
292
+
293
+ return pathDataC
294
+
295
+ }
296
+
297
+
298
+
299
+ function renderChunks(chunks) {
300
+
301
+ console.log('chunks', chunks);
302
+
303
+ let stroke = 'green';
304
+
305
+ /**
306
+ * combine chunk based
307
+ */
308
+ for (let c = 0; c < chunks.length; c++) {
309
+ let chunk = chunks[c]
310
+ let chunkLen = chunk.length;
311
+
312
+ stroke = c % 2 === 0 ? 'orange' : 'green';
313
+ let comChunk0 = chunk[0]
314
+ let comChunk1 = chunk[chunkLen - 1]
315
+
316
+ let pathDataChunk = [
317
+ { type: 'M', values: [comChunk0.p0.x, comChunk0.p0.y] }
318
+ ]
319
+
320
+ // commands in chunk
321
+ for (let i = 0, l = chunkLen; i < l; i++) {
322
+ let com = chunk[i];
323
+ let comN = chunk[i + 1];
324
+ let comL = chunk[l - 1];
325
+ let isBezier = comChunk0.type === 'C' && comChunk1.type === 'C'
326
+
327
+ //console.log(com);
328
+ let { type, values, p0, cp1 = null, cp2 = null, p = null, extreme, semiExtreme = null, corner = null } = com;
329
+
330
+
331
+ // test render - original pathdata
332
+ pathDataChunk.push(
333
+ { type, values },
334
+ );
335
+
336
+ }
337
+
338
+ let d = pathDataToD(pathDataChunk);
339
+ renderPath(markers, d, stroke, '1%', '0.5')
340
+
341
+
342
+ }
343
+ }
@@ -1,4 +1,4 @@
1
- import { checkLineIntersection, getDistAv, getSquareDistance, interpolate, pointAtT } from "./geometry";
1
+ import { checkLineIntersection, getDistManhattan, getSquareDistance, interpolate, pointAtT } from "./geometry";
2
2
  import { getPolygonArea } from "./geometry_area";
3
3
  import { commandIsFlat } from "./geometry_flatness";
4
4
  import { renderPoint } from "./visualize";
@@ -33,7 +33,7 @@ export function refineRoundedCorners(pathData, {
33
33
  //console.log('lastIsLine', lastIsLine, 'firstIsLine', firstIsLine, 'lastIsBez', lastIsBez, 'firstIsBez', firstIsBez, 'isClosed', isClosed, 'comLast1', comLast1);
34
34
 
35
35
  let normalizeClose = isClosed && firstIsBez && (lastIsLine || zIsLineto);
36
- let adjustStart = false
36
+ //let adjustStart = false
37
37
  //normalizeClose = false
38
38
  //console.log('normalizeClose', normalizeClose);
39
39
 
@@ -96,13 +96,14 @@ export function refineRoundedCorners(pathData, {
96
96
  if (comL1) {
97
97
 
98
98
  // linetos
99
- let len1 = getDistAv(comL0.p0, comL0.p)
100
- let len2 = getDistAv(comL1.p0, comL1.p)
99
+ let len1 = getDistManhattan(comL0.p0, comL0.p)
100
+ let len2 = getDistManhattan(comL1.p0, comL1.p)
101
101
 
102
102
  // bezier
103
103
  //comBez = comBez[0];
104
104
  let comBezLen = comBez.length;
105
- let len3 = getDistAv(comBez[0].p0, comBez[comBezLen - 1].p)
105
+ //let len3 = getDistManhattan(comBez[0].p0, comBez[comBezLen - 1].p)
106
+ let len3 = getDistManhattan(comL0.p, comL1.p0)
106
107
 
107
108
  // check concaveness by area sign change
108
109
  let area1 = getPolygonArea([comL0.p0, comL0.p, comL1.p0, comL1.p], false)
@@ -115,6 +116,7 @@ export function refineRoundedCorners(pathData, {
115
116
  let bezThresh = len3*0.5 * tolerance
116
117
  let isSmall = bezThresh < len1 && bezThresh < len2 ;
117
118
 
119
+
118
120
  //len1 > len3 && len2 > len3
119
121
  if (comBez.length && !signChange && isSmall ) {
120
122
 
@@ -125,17 +127,21 @@ export function refineRoundedCorners(pathData, {
125
127
 
126
128
  // final check: mid point proximity
127
129
  let ptM = pointAtT([comL0.p, ptQ, comL1.p0], 0.5)
128
- //renderPoint(markers, ptM, 'red', '0.5%', '0.5')
129
130
 
130
131
  let ptM_bez = comBez.length===1 ? pointAtT( [comBez[0].p0, comBez[0].cp1, comBez[0].cp2, comBez[0].p], 0.5 ) : comBez[0].p ;
131
132
 
132
- let dist1 = getDistAv(ptM, ptM_bez)
133
+ let dist1 = getDistManhattan(ptM, ptM_bez) * 0.75
134
+
135
+ //renderPoint(markers, ptM, 'red', '0.5%', '0.5')
136
+ //renderPoint(markers, ptM_bez, 'green', '0.5%', '0.5')
133
137
 
134
- // not in tolerance – rturn original command
135
- if(dist1>len3){
138
+ // not in tolerance – return original command
139
+ if(bezThresh && dist1>bezThresh && dist1>len3*0.3){
136
140
  //renderPoint(markers, ptM_bez, 'cyan', '0.5%', '0.5')
137
141
  //renderPoint(markers, ptQ, 'magenta', '0.5%', '0.5')
138
142
  pathDataN.push(com);
143
+ continue;
144
+
139
145
  } else{
140
146
 
141
147
  //renderPoint(markers, ptQ, 'magenta', '0.5%', '0.5')
@@ -148,6 +154,9 @@ export function refineRoundedCorners(pathData, {
148
154
  // add quadratic command
149
155
  pathDataN.push(comL0, comQ);
150
156
  i += offset;
157
+ //i++
158
+
159
+ //offset++
151
160
  continue;
152
161
  }
153
162
 
@@ -1,6 +1,6 @@
1
1
  import { findSplitT, getExtrapolatedCommand } from "../pathData_simplify_cubic";
2
2
  import { getCombinedByDominant } from "../pathData_simplify_cubic_extrapolate";
3
- import { getDistAv, interpolate } from "./geometry";
3
+ import { bezierhasExtreme, checkLineIntersection, getDistAv, getDistManhattan, getSquareDistance, interpolate } from "./geometry";
4
4
  import { getPathArea, getPolygonArea } from "./geometry_area";
5
5
  import { getPathDataBBox } from "./geometry_bbox";
6
6
  import { interpolatedPathData } from "./pathData_interpolate";
@@ -11,10 +11,14 @@ export function refineAdjacentExtremes(pathData, {
11
11
  threshold = null, tolerance = 1
12
12
  } = {}) {
13
13
 
14
+ //console.log('!!!refineAdjacentExtremes', pathData);
15
+
16
+
14
17
  //dimA = dimA ? dimA :
15
18
  if (!threshold) {
16
19
  let bb = getPathDataBBox(pathData);
17
- threshold = (bb.width + bb.height) / 2 * 0.05
20
+ //threshold = (bb.width + bb.height) / 2 * 0.05
21
+ threshold = (bb.width + bb.height) * 0.05
18
22
  //console.log('new threshold', threshold);
19
23
  }
20
24
 
@@ -32,29 +36,31 @@ export function refineAdjacentExtremes(pathData, {
32
36
 
33
37
 
34
38
  // check dist
35
- let diff = comN ? getDistAv(p, comN.p) : Infinity;
39
+ //threshold = threshold*1.05
40
+ let diff = comN ? getDistManhattan(p, comN.p) : Infinity;
36
41
  let isCose = diff < threshold;
37
42
 
38
- let diff2 = comN2 ? getDistAv(comN2.p, comN.p) : Infinity
39
- let isCose2 = diff2 < threshold;
43
+ let diff2 = comN2 ? getDistManhattan(comN2.p, comN.p) : Infinity
44
+ let isCose2 = diff2 < threshold*1;
40
45
 
46
+ //let selfIntersecting = false
41
47
 
42
48
  // next is extreme
43
- if (comN && type === 'C' && comN.type === 'C' && extreme && comN2 && comN2.extreme) {
49
+ if (comN && comN2 && type === 'C' && comN.type === 'C' && extreme && comN2.extreme) {
44
50
 
51
+ //renderPoint(markers, comN.p)
45
52
 
46
53
  if (isCose2 || isCose) {
47
54
 
48
55
  // extrapolate
49
56
  let comEx = getCombinedByDominant(comN, comN2, threshold, tolerance, false)
50
- //console.log('comEx', comEx);
51
- //renderPoint(markers, comN.p)
52
57
 
53
58
  if (comEx.length === 1) {
54
59
 
55
- pathData[i + 1] = null;
56
60
  comEx = comEx[0]
57
61
 
62
+ pathData[i + 1] = null;
63
+
58
64
  pathData[i + 2].values = [comEx.cp1.x, comEx.cp1.y, comEx.cp2.x, comEx.cp2.y, comEx.p.x, comEx.p.y]
59
65
  pathData[i + 2].cp1 = comEx.cp1
60
66
  pathData[i + 2].cp2 = comEx.cp2
@@ -71,79 +77,22 @@ export function refineAdjacentExtremes(pathData, {
71
77
 
72
78
 
73
79
  // short after extreme
74
-
75
- if (comN && type === 'C' && comN.type === 'C' && extreme ) {
80
+ if (comN && type === 'C' && comN.type === 'C' && extreme) {
76
81
 
77
82
  if (isCose) {
78
83
 
79
- //renderPoint(markers, com.p, 'cyan', '1%', '0.5')
80
- //renderPoint(markers, comN.p, 'cyan', '1%', '0.5')
81
- //console.log(comN);
82
- //console.log(diff, threshold);
83
-
84
- let dx1 = (com.cp1.x - comN.p0.x)
85
- let dy1 = (com.cp1.y - comN.p0.y)
86
-
87
- let horizontal = Math.abs(dy1) < Math.abs(dx1);
88
-
89
- let pN = comN.p;
90
- let ptI;
91
- let t = 1;
92
-
93
- let area0 = getPolygonArea([com.p0, com.p , comN.p])
84
+ let area0 = getPolygonArea([com.p0, com.p, comN.p])
94
85
  // cpts area
95
86
  let area1 = getPolygonArea([com.p0, com.cp1, com.cp2, com.p])
96
87
 
97
88
  // sign change: is corner => skip
98
- if ( (area0<0 && area1>0) || (area0>0 && area1<0)) {
89
+ if ((area0 < 0 && area1 > 0) || (area0 > 0 && area1 < 0)) {
99
90
  //renderPoint(markers, com.p, 'orange', '1%', '0.5')
100
91
  continue;
101
92
  }
102
-
103
-
104
- if (comN.extreme) {
105
-
106
- // extend cp2
107
- if (horizontal) {
108
- t = Math.abs(Math.abs(comN.cp2.x - comN.p.x) / Math.abs(com.cp2.x - com.p.x))
109
- t = Math.min(1, t)
110
- //console.log('t', t);
111
-
112
- ptI = interpolate(comN.p, com.cp2, 1 + t)
113
- com.cp2.x = ptI.x
114
- //renderPoint(markers, com.cp2, 'cyan', '1%', '0.5')
115
- //renderPoint(markers, ptI, 'orange', '1%', '0.5')
116
- }
117
- else {
118
- //renderPoint(markers, comN.p0, 'cyan', '1%', '0.5')
119
- t = Math.abs(Math.abs(comN.cp2.y - comN.p.y) / Math.abs(com.cp2.y - com.p.y))
120
- t = Math.min(1, t)
121
- //console.log('t v', t);
122
-
123
- ptI = interpolate(comN.p, com.cp2, 1 + t)
124
- com.cp2.y = ptI.y
125
- }
126
-
127
- //merge commands
128
- pathData[i + 1].values = [com.cp1.x, com.cp1.y, com.cp2.x, com.cp2.y, pN.x, pN.y]
129
- pathData[i + 1].cp1 = com.cp1
130
- pathData[i + 1].cp2 = com.cp2
131
- pathData[i + 1].p0 = com.p0
132
- pathData[i + 1].p = pN
133
- pathData[i + 1].extreme = true
134
-
135
- // nullify 1st
136
- pathData[i] = null;
137
- continue
138
-
139
- }
140
-
141
93
  }
142
94
  }
143
95
 
144
- /*
145
- */
146
-
147
96
 
148
97
  }
149
98
 
@@ -175,21 +124,13 @@ export function refineAdjacentExtremes(pathData, {
175
124
 
176
125
 
177
126
 
178
- let diff = getDistAv(lastCom.p0, lastCom.p)
127
+ let diff = getDistManhattan(lastCom.p0, lastCom.p)
179
128
  let isCose = diff < threshold;
180
129
 
181
130
 
182
131
  if (penultimateCom && penultimateCom.type === 'C' && isCose && isClosingTo && fistExt) {
183
132
 
184
- //let dx1 = Math.abs(fistExt.cp1.x - M.x)
185
- //let dy1 = Math.abs(fistExt.cp1.y - M.y)
186
-
187
- //let horizontal = dy1 < dx1;
188
- //console.log(dx1, dx2);
189
- //console.log('isCose', isCose, diff, dimA);
190
-
191
133
  let comEx = getCombinedByDominant(penultimateCom, lastCom, threshold, tolerance, false)
192
- //console.log('comEx', comEx);
193
134
 
194
135
  if (comEx.length === 1) {
195
136
  pathData[lastIdx - 1] = comEx[0];