Proposes a connection for every joint that has none: bolt size and count, plate sizes and rod spacing, from the shapes and an optional end shear.
How the precision is kept
64-bit arithmetic on rules of thumb and two tabulated strengths. The bolt count comes from one bolt's single-shear design strength with φ = 0.75 and Fnv = 372 MPa or 457 MPa, which the file cites from AISC 360-16 Table J3.2. Sizes are then rounded on purpose to shop increments (2, 5, 10 and 25 mm). The file says these are starting values, not a connection design.
Open item. Give the bolt count the same small tolerance as the other round-ups, so a shear equal to a whole number of bolts does not round up by one.
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 end shear of a beam when only a uniform load per meter is given.
R = w × L ÷ 1000 ÷ 2
L is the distance between the member's drawn start and end points (Math.hypot), not its cut length. A typed reaction is used as given.
autopilot.js
lines 41 to 48
DetailCraft 0.8.1
/** The end shear of a beam (kN) from the options, or null when none is known. */
function reactionOf(beam, opts) {
const r = opts.reactionKN;
if (typeof r === 'number' && r > 0) return r;
if (r && Number(r[beam.id]) > 0) return Number(r[beam.id]);
if (Number(opts.uniformKNm) > 0) return Number(opts.uniformKNm) * dist(beam.start, beam.end) / 1000 / 2;
return null;
}
Shear tab rows and plate
64-bit
Bolt diameter, number of rows, edge distance and plate thickness for a shear tab.
The bolt count is Math.ceil(R ÷ per) with no tolerance, so a shear that should be exactly n bolts can come out as n + 1 if the division lands just above n. Without a shear the count is a rule: one row per 150 mm of clear web, rounded.
autopilot.js
lines 50 to 63
DetailCraft 0.8.1
/** A shear tab for a beam end: bolts in one column, as many as the end shear needs and the web depth takes. */
export function sizeShearTab(beam, opts, custom) {
const s = sec(beam, custom);
if (!s) return null;
const boltD = boltFor(s.d), edge = boltD >= 22 ? 45 : 38, pitch = 75;
const clear = s.d - 2 * (s.tf + s.r); // the straight part of the web
const maxRows = Math.max(1, Math.floor((clear - 2 * edge) / pitch) + 1);
const R = reactionOf(beam, opts);
const per = boltShearKN(boltD, opts.grade);
const need = R == null ? Math.max(2, Math.min(maxRows, Math.round((clear - 2 * edge) / 150) + 1)) : Math.max(2, Math.ceil(R / per));
const fits = need <= maxRows;
const rows = Math.min(need, maxRows);
return { fits, need, maxRows, R, per, params: { ...SHEARTAB_DEFAULTS, boltD, hole: holeFor(boltD), edge, pitch, rows, tp: Math.max(8, Math.min(16, 2 * Math.round(boltD / 4))), grade: opts.grade || 'A325' } };
}
End plate rows and plate
64-bit
Bolt rows, plate width, thickness and gauge for an end plate.
Rows come in pairs of two bolts. Width and thickness are rounded up to 10 mm and 2 mm steps, the gauge to the nearest 5 mm; these rounded values are what the connection stores.
autopilot.js
lines 64 to 75
DetailCraft 0.8.1
/** An end plate: as wide as the beam's flange (rounded up to 10); rows of two bolts, four rows at least, more when the end shear needs them and the depth takes them. */
export function sizeEndPlate(beam, opts, custom) {
const s = sec(beam, custom);
if (!s) return null;
const boltD = boltFor(s.d), pitch = 75;
const R = reactionOf(beam, opts);
const per = boltShearKN(boltD, opts.grade);
const maxRows = Math.max(2, Math.floor((s.d - 2 * 40) / pitch) + 1);
const wanted = Math.max(4, R == null ? 4 : 2 * Math.ceil(R / per / 4)); // two bolts a row
const rows = Math.min(maxRows - (maxRows % 2), wanted);
return { fits: wanted <= maxRows - (maxRows % 2), need: wanted, maxRows, R, per, params: { ...ENDPLATE_DEFAULTS, boltD, hole: holeFor(boltD), pitch, rows: Math.max(2, rows), tp: Math.max(16, up(boltD, 2)), width: Math.max(150, up(s.bf, 10)), gauge: Math.max(90, Math.round((s.bf * 0.55) / 5) * 5), grade: opts.grade || 'A325' } };
}
Base plate size and rod spacing
64-bit
Plate length and width, rod diameter, hole and rod spacing for a column base.
length = max(300, (depth + 150) rounded up to 25); sx = length − 100
The hole diameter is the Design Guide 1 table value converted to millimeters and then rounded to a whole millimeter with Math.round, so 1 5/16 in (33.3375 mm) is stored as 33.
autopilot.js
lines 76 to 85
DetailCraft 0.8.1
/** A base plate: the column's footprint plus 75 mm each way (rounded up to 25), rods inside it. */
export function sizeBasePlate(col, custom) {
const s = sec(col, custom);
if (!s) return null;
const length = Math.max(300, up(s.depth + 150, 25)), width = Math.max(300, up(s.width + 150, 25));
const rodD = s.depth >= 400 ? 24 : 20;
const row = dg1Row(rodD);
const tp = s.depth >= 400 ? 32 : 25;
return { ...BASEPLATE_DEFAULTS, length, width, tp, rodD, hole: row ? Math.round(row.hole) : BASEPLATE_DEFAULTS.hole, sx: length - 100, sy: width - 100 };
}
Rounding up to a step
64-bit
Rounds a size up to the next multiple of a step.
⌈v ÷ step − 1e-9⌉ × step
The 1e-9 keeps a value that is already a multiple from jumping a whole step because of a division error. It is absolute on the ratio v ÷ step.
φ·Fnv·Ab per bolt; bolt count = end shear ÷ that, rounded up; plate and rod sizes by fixed rules from the section depth and width.
Number types
64-bit numbers.
Tolerances
Rounding up to a step uses Math.ceil(v ÷ step − 1e-9); the 1e-9 is absolute on the ratio. The bolt count uses Math.ceil with no tolerance.
Limits
Only bolt shear is counted. Bearing, block shear, plate and weld strength are not, as the file header states.
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.