diff --git a/src/type/p5.Font.js b/src/type/p5.Font.js index 1ffa018185..e5179a0a94 100644 --- a/src/type/p5.Font.js +++ b/src/type/p5.Font.js @@ -234,7 +234,7 @@ export class Font { * path and are more precise. * * `simplifyThreshold` removes collinear points if it's set to a number other - * than 0. The value represents the threshold angle to use when determining + * than 0. The value represents the threshold angle in radians to use when determining * whether two edges are collinear. * * @param {String} str string of text. @@ -242,7 +242,7 @@ export class Font { * @param {Number} y y-coordinate of the text. * @param {Object} [options] Configuration: * @param {Number} [options.sampleFactor=0.1] The ratio of the text's path length to the number of samples. - * @param {Number} [options.simplifyThreshold=0] A minmum angle between two segments. Segments with a shallower angle will be merged. + * @param {Number} [options.simplifyThreshold=0] A minmum angle in radian sbetween two segments. Segments with a shallower angle will be merged. * @return {Array} array of point objects, each with `x`, `y`, and `alpha` (path angle) properties. * * @example @@ -306,7 +306,7 @@ export class Font { * path and are more precise. * * `simplifyThreshold` removes collinear points if it's set to a number other - * than 0. The value represents the threshold angle to use when determining + * than 0. The value represents the threshold angle in radians to use when determining * whether two edges are collinear. * * @param {String} str string of text. @@ -314,7 +314,7 @@ export class Font { * @param {Number} y y-coordinate of the text. * @param {Object} [options] Configuration options: * @param {Number} [options.sampleFactor=0.1] The ratio of the text's path length to the number of samples. - * @param {Number} [options.simplifyThreshold=0] A minmum angle between two segments. Segments with a shallower angle will be merged. + * @param {Number} [options.simplifyThreshold=0] A minmum angle in radians between two segments. Segments with a shallower angle will be merged. * @return {Array>} array of point objects, each with `x`, `y`, and `alpha` (path angle) properties. * * @example @@ -1092,6 +1092,35 @@ function pathToPoints(cmds, options, font) { return num; }; + const collinear = (a, b, c, thresholdAngle) => { + if (!thresholdAngle) { + return areaTriangle(a, b, c) === 0; + } + + if (typeof collinear.tmpPoint1 === 'undefined') { + collinear.tmpPoint1 = []; + collinear.tmpPoint2 = []; + } + + const ab = collinear.tmpPoint1, + bc = collinear.tmpPoint2; + ab.x = b.x - a.x; + ab.y = b.y - a.y; + bc.x = c.x - b.x; + bc.y = c.y - b.y; + + const dot = ab.x * bc.x + ab.y * bc.y, + magA = Math.sqrt(ab.x * ab.x + ab.y * ab.y), + magB = Math.sqrt(bc.x * bc.x + bc.y * bc.y), + angle = Math.acos(dot / (magA * magB)); + + return angle < thresholdAngle; + }; + + const areaTriangle = (a, b, c) => { + return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]); + }; + const path = createFromCommands(arrayCommandsToObjects(cmds)); let opts = parseOpts(options, { sampleFactor: 0.1, diff --git a/test/unit/type/p5.Font.js b/test/unit/type/p5.Font.js index 395dd9dc03..59ac525b53 100644 --- a/test/unit/type/p5.Font.js +++ b/test/unit/type/p5.Font.js @@ -60,6 +60,14 @@ suite('p5.Font', function () { expect(pt.y).not.toBeNaN(); } }); + + test('simplifies collinear points', async () => { + const font = await myp5.loadFont(fontFile); + myp5.textSize(50); + const pts = font.textToPoints('T', 0, 0); + const simplifiedPts = font.textToPoints('T', 0, 0, { simplifyThreshold: Math.PI * 0.01 }); + expect(pts.length).toBeGreaterThan(simplifiedPts.length); + }); }); });