Places cabinets one after another along a wall line picked in the plan, finds which cabinets belong to a front view, and prints areas and lengths of the cut list (Cabinet add-on).
How the precision is kept
Cabinet sizes are kept in rule units (millimeters or inches) and the drawing may use another unit. A typed width is multiplied by the number of rule units per drawing unit, positions are added up in rule units, and each position is multiplied by the reciprocal factor to place the cabinet. All of it is 64-bit arithmetic.
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.
The factor between the drawing's unit and the cabinet rules' unit, and its reciprocal.
per = meters per drawing unit ÷ (0.0254 or 0.001); k = 1 ÷ per
per comes from core.js as one division of two decimal constants. k is its reciprocal, so per × k is not always exactly 1.
addons/cabinet/main.js
line 145
CadCraft 0.8.2
const doc = c.doc, u = ruleUnitOf(doc), per = perUnit(doc, u), k = 1 / per;
Placing a cabinet on the run
64-bit
The insertion point and rotation of a new cabinet, and where the next one starts.
w = typed × per; x = runₓ + cos(ang)·pos·k; y = runᵧ + sin(ang)·pos·k; next pos = pos + w
Positions add up in rule units, one addition per cabinet, and each is converted to drawing units once when the cabinet is placed, so the conversion error does not build up along the run. The warning for running past the wall uses 1e-6 rule units, absolute.
Which cabinets stand on a wall line and how far along it, for the front view.
on the run when |sin(rot − ang)| ≤ 1e-6, cos(rot − ang) ≥ 0 and |offset| ≤ 0.5 × depth × k; x = s ÷ k − smallest x, rounded to 6 decimals
The distance along the run is a dot product with the run's direction, divided by k. Positions are measured from the first cabinet and rounded to 6 decimals of the rule unit before they are stored with the front view.
addons/cabinet/main.js
lines 110 to 123
CadCraft 0.8.2
// ---------------------------------------------------------------------------------------------- the front view of a wall line
function elevItems(doc, run) {
const items = [];
for (const { e, d } of readCabs(doc)) {
const rot = e.rot || 0;
if (Math.abs(Math.sin(rot - run.ang)) > 1e-6 || Math.cos(rot - run.ang) < 0 || (e.sx ?? 1) < 0 || (e.sy ?? 1) < 0) continue;
const a = along(run, { x: e.x, y: e.y });
if (Math.abs(a.off) > 0.5 * d.cab.d * d.k) continue;
items.push({ u: d.u, k: d.k, cab: d.cab, rules: d.rules, x: a.s / d.k });
}
const min = items.length ? Math.min(...items.map((i) => i.x)) : 0;
for (const i of items) i.x = Math.round((i.x - min) * 1e6) / 1e6;
return items.sort((a, b) => a.x - b.x || a.cab.elev - b.cab.elev);
}
Area as text
64-bit
The area of a material group on the command line.
in² ÷ 144 = ft²; mm² ÷ 1e6 = m²; 3 decimals
144 and 1e6 are exact factors. The text has at most 3 decimals with trailing zeros removed; the value itself is not changed.
The share of each material's sheets covered by parts, as printed after nesting.
percent = round(efficiency × 100)
Rounded to a whole percent for the printed line only; the efficiency itself comes from the nesting job.
addons/cabinet/main.js
line 363
CadCraft 0.8.2
for (const m of N.job.efficiency) c.print(' ' + t('nest.mat', { mat: m.material, sheets: m.sheets, pct: Math.round(m.efficiency * 100) }));
In detail
Method
Position along the run = sum of the widths before it; point = run start + direction × position × k.
Number types
64-bit numbers.
Tolerances
A cabinet belongs to a run when |sin(angle difference)| ≤ 1e-6 and it lies within half its depth of the line. A run is past its end when position + width > length + 1e-6. Positions in a front view are rounded to 6 decimals.
Limits
k is formed as 1 ÷ per and multiplied in, so a width typed in drawing units and converted back can differ from the typed value in the last bit.
Approach: 64-bit, direct
Every value is a 64-bit number from input to result. Formulas are closed form or a direct solve, and every comparison uses a stated tolerance.