Resources Numerical accuracy Calculation policy

Sheet scale read from the sheet's text

Finds scale notations in a PDF sheet's text and picks the listed scale to offer for the sheet.

How the precision is kept

A notation is turned into a ratio of real inches to paper inches in 64-bit arithmetic, rounded to 3 decimals, and used only to look up one of the app's listed scales. What comes back is the listed scale's key, never a scale computed from the text. A notation that matches no listed scale is ignored. When a sheet shows several scales the most frequent wins and the others are reported.

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.

scaletext.js TakeoffCraft 0.8.1 64-bit 3 calculations Reviewed

Tests bin/test-takeoffcraft.mjs

Paper length of a notation in inches

64-bit

Reads a fraction, a mixed number or a decimal as inches.

1-1/2 → 1 + 1 ÷ 2; 1/4 → 1 ÷ 4

The whole part plus numerator over denominator in 64-bit arithmetic. A zero denominator gives NaN or Infinity; the caller then finds no listed scale for it.

  • scaletext.js
  • lines 24 to 31
  • TakeoffCraft 0.8.1
/** "1/4" → 0.25, "1-1/2" / "1 1/2" → 1.5, "0.25" → 0.25 */
function inches(s) {
  const m = /^(\d+)\s*[- ]\s*(\d+)\s*\/\s*(\d+)$/.exec(s.trim());
  if (m) return +m[1] + +m[2] / +m[3];
  const f = /^(\d+)\s*\/\s*(\d+)$/.exec(s.trim());
  if (f) return +f[2] ? +f[1] / +f[2] : NaN;
  return Number(s.trim());
}

Ratio of a notation and its listed scale

64-bit

Every scale notation in the text, each matched to a listed scale.

ratio = (feet × 12 + inches) ÷ paper inches, rounded to 3 decimals

The ratio is rounded with Math.round(r × 1000) ÷ 1000 and joined to a text key, so after rounding it must equal a listed ratio exactly. A metric notation uses the whole number after 1: as its key. The result is the listed scale's key and label, not a computed scale.

  • scaletext.js
  • lines 38 to 57
  • TakeoffCraft 0.8.1
export function scalesInText(text) {
  const s = String(text || '');
  const out = [];
  const before = (i) => /\bscale\b\s*[:=]?\s*$/i.test(s.slice(Math.max(0, i - 16), i));
  for (const m of s.matchAll(IMPERIAL)) {
    const paper = inches(m[1]), real = +m[2] * 12 + (m[3] ? +m[3] : 0);
    if (!(paper > 0) || !(real > 0)) continue;
    const ratio = Math.round(real / paper * 1000) / 1000;
    const p = byRatio.get('i' + ratio);
    if (!p || p.group === 'Metric') continue;
    // 1" = 1'-0" is architectural (12); 1" = 10' and up engineering — both are imperial presets by ratio
    out.push({ preset: p.key, label: p.label, index: m.index, scaleWord: before(m.index) });
  }
  for (const m of s.matchAll(METRIC)) {
    const p = byRatio.get('m' + +m[1]);
    if (!p) continue;
    out.push({ preset: p.key, label: p.label, index: m.index, scaleWord: before(m.index) });
  }
  return out.sort((a, b) => a.index - b.index);
}

Which scale a sheet gets

Exact

The most frequent scale on the sheet, and the other scales found.

Whole-number votes: 2 for a notation right after the word scale, 1 otherwise. A tie goes to the scale that appears first in the text.

  • scaletext.js
  • lines 59 to 68
  • TakeoffCraft 0.8.1
export function sheetScale(text) {
  const found = scalesInText(text);
  const nts = NTS.test(String(text || ''));
  if (!found.length) return { preset: null, n: 0, others: [], nts, why: nts ? 'nts' : 'none' };
  const score = new Map();
  for (const f of found) score.set(f.preset, (score.get(f.preset) || 0) + (f.scaleWord ? 2 : 1));
  const ranked = [...score.entries()].sort((a, b) => b[1] - a[1] || found.findIndex((f) => f.preset === a[0]) - found.findIndex((f) => f.preset === b[0]));
  const [preset] = ranked[0];
  return { preset, label: PRESETS.get(preset).label, n: found.filter((f) => f.preset === preset).length, others: ranked.slice(1).map(([k]) => k), nts, why: ranked.length > 1 ? 'several' : 'one' };
}

In detail

Method
Regular expressions for imperial notations (paper inches = feet and inches) and metric ones (1:n). ratio = (feet × 12 + inches) ÷ paper inches. Lookup by ratio among the listed scales, then a vote in which a notation written right after the word scale counts double.
Number types
64-bit numbers for the ratio; whole-number votes.
Tolerances
The ratio is rounded to 3 decimals, then must equal a listed ratio exactly.
Limits
Only scales in the app's list are recognized. The result depends on the sheet's text: the function cannot tell a wrong scale note from a right one.

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