The line segments that draw the text of an imported drawing in the 3D model, and the width of a string.
How the precision is kept
Glyphs are polylines on a grid where a capital is 9 units high; a string is scaled by height ÷ 9 and the width factor in 64-bit. Round parts of letters are elliptical arcs sampled every 15 degrees, so letter shapes are polygons by design.
Calculations under this policy
3 calculations in 1 source file. The code is read from the released app when this page loads. It is the calculation people run, not a copy kept for this page.
Glyph widths are numbers on the 9-unit grid, added in order and scaled once. A width factor of 0 is taken as 1.
m3d/strokefont.js
lines 151 to 156
CadCraft 0.8.2
/** The advance of a string, in drawing units. */
export function textWidth(text, h = 1, wf = 1) {
let w = 0;
for (const ch of String(text)) w += ((G[ch] || BOX)[0] + GAP);
return Math.max(0, w - GAP) * (h / 9) * (wf || 1);
}
Strokes of a string
64-bit
The polylines of a string at a given height, width factor and slant.
x = x₀ + p_x × s_x + p_y × s × tan(oblique); y = p_y × s; s = h ÷ 9
Each glyph point is scaled and sheared in one expression; the pen position advances by (glyph width + 2) × s_x per character, added character by character. tan(oblique) is not limited, so a slant near 90° gives very large x.
m3d/strokefont.js
lines 158 to 170
CadCraft 0.8.2
/** Polylines of a string (see the header). */
export function textStrokes(text, { h = 1, wf = 1, oblique = 0 } = {}) {
const s = h / 9, sx = s * (wf || 1), sh = Math.tan(oblique || 0);
const lines = [];
let x = 0, missing = 0;
for (const ch of String(text)) {
let g = G[ch];
if (!g) { if (/\s/.test(ch)) g = G[' ']; else { g = BOX; missing++; } }
for (const l of g[1]) lines.push(l.map(([px, py]) => [x + px * sx + py * s * sh, py * s]));
x += (g[0] + GAP) * sx;
}
return { lines, width: Math.max(0, x - GAP * sx), missing };
}
In detail
Method
Glyph polylines scaled and sheared: x = x₀ + p_x·s_x + p_y·s·tan(oblique), y = p_y·s.
Number types
64-bit numbers.
Limits
Arcs in glyphs are sampled every 15 degrees. A character with no glyph is drawn as a box and counted.
Approach: 64-bit, stated limit
The arithmetic is 64-bit, but the method or the data sets the accuracy: a solver tolerance, a mesh, a step size, a datum shift, a table. The limit is stated where the result is shown.