Writes the coordinates, feeds and arc offsets of a machining program as G-code words, using a post definition a person can edit.
How the precision is kept
Tool path values arrive as 64-bit numbers and are rounded to 0.001 only when a word is written, by the helpers q and num in cam-fmt.js. A modal word is left out when the new value equals the last written value after both are rounded to 0.001. Arc center offsets are measured from the last written X and Y after rounding, not from the unrounded position.
Calculations under this policy
6 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.
Decides whether an address word such as X or Z is written on a line, and writes its value.
written when round(v × 1000) ≠ round(last × 1000); text = letter + v to 3 decimals
The comparison rounds both values to 0.001 with q from cam-fmt.js. The slot keeps the unrounded value that was written, and each later comparison rounds both sides again. The text is the value formatted by num: 3 decimals, trailing zeros dropped.
cam-postdef.js
lines 292 to 314
PartCraft 0.8.1
/** A word → {text} or null (left out); a modal word is remembered as it is made, so two in one line see each other. */
word(w) {
const point = this.def.point;
if (w.modal) {
if (w.addr) {
const val = this.ev(w.expr);
if (typeof val === 'number') {
if (!w.force && this.slot[w.addr] != null && q(this.slot[w.addr]) === q(val)) return null;
this.slot[w.addr] = val;
return { text: w.addr + num(val, point) };
}
}
const txt = this.text(w.parts, point);
if (!txt) return null;
const g = this.groupOf.get(txt);
if (!g) return { text: txt };
if (!w.force && this.group[g] === txt) return null;
this.group[g] = txt;
return { text: txt };
}
const txt = this.text(w.parts, point);
return txt ? { text: txt } : null;
}
Numbers in a line template
64-bit
Fills the {variable} holes of a raw, comment or word template with values.
Every number that fills a hole is formatted by num: rounded to 0.001, 3 decimals, trailing zeros dropped. Filters such as pad, cut and int then act on that text, not on the number.
cam-postdef.js
lines 276 to 290
PartCraft 0.8.1
text(parts, point) {
let s = '';
for (const p of parts) {
if (typeof p === 'string') { s += p; continue; }
let v = this.ev(p.e);
if (typeof v === 'number') v = num(v, point);
else if (v === true) v = 'yes'; else if (v === false || v === null || v === undefined) v = '';
v = String(v);
for (const f of p.filters) {
if (f.name === 'pad') v = v.padStart(f.n, '0'); else if (f.name === 'cut') v = v.slice(0, f.n); else v = FILTERS[f.name](v);
}
s += v;
}
return s;
}
Whole-number filter
64-bit
The int filter a post can put on a value, for example a spindle speed.
int(s) = round(number(s))
The filter receives the text already rounded to 3 decimals and rounds it again with Math.round. A value of 2.4996 therefore becomes 2.5 and then 3, where rounding the original once gives 2. Math.round rounds halves toward +∞.
cam-postdef.js
line 71
PartCraft 0.8.1
const FILTERS = { upper: (s) => String(s).toUpperCase(), lower: (s) => String(s).toLowerCase(), safe: safeComment, int: (s) => String(Math.round(+s)) };
Arc center offsets I and J
64-bit
The center of an arc move, written relative to the start point.
I = round₃(cₓ − round₃(X_last)); J = round₃(c_y − round₃(Y_last))
The start point is the last X and Y written, rounded to 0.001, or 0 when none was written yet. The center is unrounded and the difference is rounded to 0.001 again. The moved flag compares the target with the last written values after rounding both.
The == and != tests a post definition can make on two values.
Two numbers are equal when they match after rounding to 0.001. Other values are compared as text.
cam-postdef.js
lines 243 to 247
PartCraft 0.8.1
function same(a, b) {
if (a == null || b == null) return a == null && b == null;
if (typeof a === 'number' && typeof b === 'number') return q(a) === q(b);
return String(a) === String(b);
}
Stock size variables
64-bit
The stock's diameter, side lengths and corners that a post can print in its header.
sx = maxₓ − minₓ; d = 2 × r
Plain 64-bit differences of the stock box corners; a cylinder's diameter is twice its radius. They are rounded to 3 decimals only when written into a line.
Each event of the post definition is run over the program. Numbers in words go through num in cam-fmt.js: rounded to 0.001, written with 3 decimals, trailing zeros dropped.
Number types
64-bit numbers; text with at most 3 decimals in the output.
Tolerances
Two numbers count as the same when they are equal after rounding to 0.001. The step is absolute, in the program's length unit (cam-fmt.js calls it 1 µm).
Limits
The output resolution is 0.001 whatever the size of the part. The int filter rounds a number that was already rounded to 3 decimals.
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.