Resources Numerical accuracy Calculation policy

Corner cabinets: parts and solids

Builds the cut list, door sizes, hardware counts and 3D solids of L-shaped, diagonal and lazy-susan corner cabinets (CabinetCraft add-on).

How the precision is kept

Part sizes are sums and differences of the cabinet's width, depth, board thickness and reveals in 64-bit numbers, rounded to 6 decimals of the job's unit when they enter the cut list. The diagonal door uses Math.SQRT2. Round shelves are drawn as 20-sided solids and listed as a square blank of their diameter. Fixed hardware clearances are written in millimeters and converted for inch jobs by multiplying with 1 ÷ 25.4.

Open item. Multiply the pole's half width of 15 by the same millimeter factor as the 70 and 12 next to it, so an inch job does not get a 30 inch pole.

Calculations under this policy

11 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.

addons/cabinetcraft/lib/corner.js CadCraft 0.8.2 64-bit 11 calculations Reviewed

Tests None found by the review

A board along a slanted line

64-bit

The four corners of a door or plinth board that runs along a diagonal.

n = (−Δy, Δx) ÷ L; corner = point + n × offset, rounded to 6 decimals

The unit normal divides by the length of the line, which is not checked for zero here. Each corner is rounded to 6 decimals.

  • addons/cabinetcraft/lib/corner.js
  • lines 29 to 34
  • CadCraft 0.8.2
const slab = (role, p, q, from, to, z0, z1) => {
  // a board along p→q (the room is on the left), covering offsets from…to along the outward normal (positive = into the room)
  const dx = q[0] - p[0], dy = q[1] - p[1], L = Math.hypot(dx, dy), nx = -dy / L, ny = dx / L;
  const P = (pt, o) => [r6(pt[0] + nx * o), r6(pt[1] + ny * o)];
  return { role, kind: 'prism', pts: [P(p, from), P(q, from), P(q, to), P(p, to)], z0, z1 };
};

Round shelf solid

64-bit

The outline of a lazy-susan shelf as drawn in 3D.

20 points at (cx + r·cos(2πi ÷ 20), cy + r·sin(2πi ÷ 20))

A regular 20-sided polygon inscribed in the shelf's circle, so the drawn solid is slightly smaller than a true disc. The cut list does not use it: the shelf is listed as a square blank of its diameter.

  • addons/cabinetcraft/lib/corner.js
  • line 35
  • CadCraft 0.8.2
const circle = (cx, cy, r, z0, z1, role, n = 20) => ({ role, kind: 'prism', pts: Array.from({ length: n }, (_, i) => [r6(cx + r * Math.cos((2 * Math.PI * i) / n)), r6(cy + r * Math.sin((2 * Math.PI * i) / n))]), z0, z1 });

Open leg of a corner cabinet

64-bit

The basic sizes of a corner cabinet: width, depth, open leg and top height.

a = w − d; top = kick + box height

One subtraction and one addition on the cabinet's sizes; the box sizes come from boxOf in model.js.

  • addons/cabinetcraft/lib/corner.js
  • lines 37 to 41
  • CadCraft 0.8.2
function geometry(cell, R) {
  const cab = cell.cab, w = cab.w, d = cab.d;
  const b = boxOf(cab, R);
  return { w, d, a: w - d, ...b, t: R.t, top: b.kick + b.boxH, rv: R.reveal };
}

Lazy-susan shelf size and place

64-bit

The diameter and center of the round shelves and the pole they turn on.

diameter = max(1, w − 2·(t + 70 mm)); clearance = back setback + back thickness + 12 mm; center = (w − r − clearance, r + clearance); pole = center ± 15

The 70 and 12 are millimeters and are multiplied by 1 ÷ 25.4 in an inch job, which can differ from dividing by 25.4 in the last bit. The pole's 15 is used as is, so in an inch job the pole is drawn 30 inches square.

  • addons/cabinetcraft/lib/corner.js
  • lines 60 to 63
  • CadCraft 0.8.2
const dia = Math.max(1, w - 2 * (t + 70 * (R.unit === 'in' ? 1 / 25.4 : 1))), r = dia / 2, c = bs + bt + 12 * (R.unit === 'in' ? 1 / 25.4 : 1);
const cx = w - r - c, cy = r + c;
out.push({ role: 'plinth', kind: 'box', x0: r6(cx - 15), y0: r6(cy - 15), z0: r6(kick + t), x1: r6(cx + 15), y1: r6(cy + 15), z1: r6(top - t) });
for (let i = 0; i < 2; i++) { const z = kick + t + ((top - t) - (kick + t)) * (i + 1) / 3 - t / 2; out.push(circle(cx, cy, r, r6(z), r6(z + t), 'shelf')); }

Shelf heights

64-bit

The height of each shelf inside the cabinet.

z = kick + t + (inside height) × (i + 1) ÷ (n + 1) − t ÷ 2

Each shelf's height is computed from the whole inside height and its own index, not by adding a step again and again, so no error builds up from shelf to shelf.

  • addons/cabinetcraft/lib/corner.js
  • lines 65 to 67
  • CadCraft 0.8.2
for (let i = 0; i < shelves; i++) {
  const z = kick + t + ((top - t) - (kick + t)) * (i + 1) / (shelves + 1) - t / 2;
  box('shelf', t + R.shelfClear, bs + bt, z, w - bs - bt, d - R.shelfFront, z + t);

Sizes entered in the cut list

64-bit

The length and width of each board as they go into the cut list.

length, width → round(v × 1e6) ÷ 1e6

Every length and width is rounded to 6 decimals of the job's unit when the part is added. A part with a length or width of 0 or less is left out.

  • addons/cabinetcraft/lib/corner.js
  • lines 102 to 105
  • CadCraft 0.8.2
const add = (role, name, length, width, thickness, material, extra = {}) => {
  if (!(length > 0 && width > 0)) return;
  parts.push({ role, name, group: cell.no, length: r6(length), width: r6(width), thickness, material, grain: 'length', qty: 1, band: {}, ...extra });
};

Back panels

64-bit

The size of the two back panels for a grooved, between or applied back.

grooved: height = box height − 2t + 2·groove, length + groove; between: height = box height − 2t; applied: full height and width

Sums and differences of the rule sizes in 64-bit numbers; rounded to 6 decimals when added to the cut list.

  • addons/cabinetcraft/lib/corner.js
  • lines 113 to 117
  • CadCraft 0.8.2
const grooved = R.back === 'groove', between = R.back === 'between';
const bh = grooved ? boxH - 2 * t + 2 * R.groove : between ? boxH - 2 * t : boxH;
const bl = (len, dl) => (grooved ? len + R.groove : len) + dl;
add('back', 'part.back', R.back === 'applied' ? w : bl(w - t, 0), bh, R.backT, R.backMat, { grain: 'none' });
add('back', 'part.back', R.back === 'applied' ? a : bl(w - d - t, 0), bh, R.backT, R.backMat, { grain: 'none' });

Door and plinth sizes at a right-angled corner

64-bit

The door height and width and the plinth length of a corner cabinet.

door height = box height − reveal; door width = a − reveal (L) or a·√2 − reveal (diagonal); plinth = a or a·√2

√2 is Math.SQRT2, the nearest 64-bit number to the square root of 2, not a shortened decimal.

  • addons/cabinetcraft/lib/corner.js
  • lines 128 to 130
  • CadCraft 0.8.2
const doorH = boxH - rv, doorW = turn === 'l' ? a - rv : a * S2 - rv, nd = turn === 'l' ? 2 : 1;
add('door', 'part.corner-door', doorH, doorW, R.frontT, R.frontMat, { qty: nd, band: all(R.bandFront) });
if (hasKick) add('plinth', 'part.plinth', turn === 'l' ? a : a * S2, kick, t, R.carcass, { qty: turn === 'l' ? 2 : 1 });

Blank for the triangle of an angled corner

64-bit

The smallest rectangle the triangular filler of an angled corner cabinet can be cut from, and the true front length.

axes along the triangle's first leg and across it; L = largest coordinate along, W = largest across; front = |F_B − F_A|

The triangle's corners were rounded to 6 decimals where they were made, so the blank and the front length are measured between rounded points. The division by the leg's length is not guarded against 0.

  • addons/cabinetcraft/lib/corner.js
  • lines 191 to 199
  • CadCraft 0.8.2
const triBox = (() => {
  const ux = { x: (Q[0] - FA2[0]) / ell, y: (Q[1] - FA2[1]) / ell };
  const cr = ux.x * (FB2[1] - FA2[1]) - ux.y * (FB2[0] - FA2[0]);
  const uy = cr >= 0 ? { x: -ux.y, y: ux.x } : { x: ux.y, y: -ux.x };
  const xs = T.map((p) => (p[0] - FA2[0]) * ux.x + (p[1] - FA2[1]) * ux.y), ys = T.map((p) => (p[0] - FA2[0]) * uy.x + (p[1] - FA2[1]) * uy.y);
  return { o: FA2, ux, uy, L: Math.max(...xs), W: Math.max(...ys) };
})();
void ex; void ey;
const frontLen = Math.hypot(FB2[0] - FA2[0], FB2[1] - FA2[1]);

Door and plinth sizes at an angled corner

64-bit

The door and plinth of a diagonal corner cabinet at a corner that is not a right angle.

door width = front length − reveal; plinth = front length

The front length is the distance between the two front corners, computed with Math.hypot.

  • addons/cabinetcraft/lib/corner.js
  • lines 222 to 224
  • CadCraft 0.8.2
const doorH = boxH - rv, doorW = frontLen - rv;
add('door', 'part.corner-door', doorH, doorW, R.frontT, R.frontMat, { band: all(R.bandFront), note: say('note.corner.door.angled', { len: String(r6(frontLen)) }) });
if (hasKick) add('plinth', 'part.plinth', frontLen, kick, t, R.carcass, { qty: 1 });

Mirrored corner cabinet

64-bit

The same cabinet for a corner at the start of a run.

x → w − x, rounded to 6 decimals

One subtraction per x coordinate, rounded to 6 decimals; y and z are unchanged. Prism points are reversed so they still run counter-clockwise.

  • addons/cabinetcraft/lib/corner.js
  • line 89
  • CadCraft 0.8.2
const mirror = (s, w) => (s.kind === 'box' ? { ...s, x0: r6(w - s.x1), x1: r6(w - s.x0) } : { ...s, pts: s.pts.map(([x, y]) => [r6(w - x), y]).reverse() });

In detail

Method
Open leg a = w − d; diagonal front = a × √2 (right angle) or the distance between the two front corners (other angles); shelves at equal divisions of the inside height.
Number types
64-bit numbers; solids are boxes and prisms with points as arrays [x, y].
Tolerances
Cut list lengths and widths rounded to 1e-6. A box thinner than 1e-9 in any direction is left out. Triangle fillers are added only when a − t > 1 in the job's unit.
Limits
The round shelf solid is a 20-sided polygon. The lazy-susan pole is drawn 30 units square in the job's unit without the millimeter conversion the lines beside it use.

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.

Every policy that takes this approach