Skip to content

Commit 69536d8

Browse files
authored
Merge pull request #8178 from processing/fix/simplifythreshold
Fix errors in simplifyThreshold in textToPoints
2 parents 65a8008 + 093b2e9 commit 69536d8

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

src/type/p5.Font.js

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,15 +234,15 @@ export class Font {
234234
* path and are more precise.
235235
*
236236
* `simplifyThreshold` removes collinear points if it's set to a number other
237-
* than 0. The value represents the threshold angle to use when determining
237+
* than 0. The value represents the threshold angle in radians to use when determining
238238
* whether two edges are collinear.
239239
*
240240
* @param {String} str string of text.
241241
* @param {Number} x x-coordinate of the text.
242242
* @param {Number} y y-coordinate of the text.
243243
* @param {Object} [options] Configuration:
244244
* @param {Number} [options.sampleFactor=0.1] The ratio of the text's path length to the number of samples.
245-
* @param {Number} [options.simplifyThreshold=0] A minmum angle between two segments. Segments with a shallower angle will be merged.
245+
* @param {Number} [options.simplifyThreshold=0] A minmum angle in radian sbetween two segments. Segments with a shallower angle will be merged.
246246
* @return {Array<Object>} array of point objects, each with `x`, `y`, and `alpha` (path angle) properties.
247247
*
248248
* @example
@@ -306,15 +306,15 @@ export class Font {
306306
* path and are more precise.
307307
*
308308
* `simplifyThreshold` removes collinear points if it's set to a number other
309-
* than 0. The value represents the threshold angle to use when determining
309+
* than 0. The value represents the threshold angle in radians to use when determining
310310
* whether two edges are collinear.
311311
*
312312
* @param {String} str string of text.
313313
* @param {Number} x x-coordinate of the text.
314314
* @param {Number} y y-coordinate of the text.
315315
* @param {Object} [options] Configuration options:
316316
* @param {Number} [options.sampleFactor=0.1] The ratio of the text's path length to the number of samples.
317-
* @param {Number} [options.simplifyThreshold=0] A minmum angle between two segments. Segments with a shallower angle will be merged.
317+
* @param {Number} [options.simplifyThreshold=0] A minmum angle in radians between two segments. Segments with a shallower angle will be merged.
318318
* @return {Array<Array<Object>>} array of point objects, each with `x`, `y`, and `alpha` (path angle) properties.
319319
*
320320
* @example
@@ -1092,6 +1092,35 @@ function pathToPoints(cmds, options, font) {
10921092
return num;
10931093
};
10941094

1095+
const collinear = (a, b, c, thresholdAngle) => {
1096+
if (!thresholdAngle) {
1097+
return areaTriangle(a, b, c) === 0;
1098+
}
1099+
1100+
if (typeof collinear.tmpPoint1 === 'undefined') {
1101+
collinear.tmpPoint1 = [];
1102+
collinear.tmpPoint2 = [];
1103+
}
1104+
1105+
const ab = collinear.tmpPoint1,
1106+
bc = collinear.tmpPoint2;
1107+
ab.x = b.x - a.x;
1108+
ab.y = b.y - a.y;
1109+
bc.x = c.x - b.x;
1110+
bc.y = c.y - b.y;
1111+
1112+
const dot = ab.x * bc.x + ab.y * bc.y,
1113+
magA = Math.sqrt(ab.x * ab.x + ab.y * ab.y),
1114+
magB = Math.sqrt(bc.x * bc.x + bc.y * bc.y),
1115+
angle = Math.acos(dot / (magA * magB));
1116+
1117+
return angle < thresholdAngle;
1118+
};
1119+
1120+
const areaTriangle = (a, b, c) => {
1121+
return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]);
1122+
};
1123+
10951124
const path = createFromCommands(arrayCommandsToObjects(cmds));
10961125
let opts = parseOpts(options, {
10971126
sampleFactor: 0.1,

test/unit/type/p5.Font.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ suite('p5.Font', function () {
6060
expect(pt.y).not.toBeNaN();
6161
}
6262
});
63+
64+
test('simplifies collinear points', async () => {
65+
const font = await myp5.loadFont(fontFile);
66+
myp5.textSize(50);
67+
const pts = font.textToPoints('T', 0, 0);
68+
const simplifiedPts = font.textToPoints('T', 0, 0, { simplifyThreshold: Math.PI * 0.01 });
69+
expect(pts.length).toBeGreaterThan(simplifiedPts.length);
70+
});
6371
});
6472
});
6573

0 commit comments

Comments
 (0)