feat(rebar): add downward 90° hooks (135 mm) to P6 crossties in 3D rebar model
This commit is contained in:
1 parent
4aa8dbb3cb
commit
a2317caf6c
15 files changed
+740
-133
No files matched your search
+219
-39
@@ -1,10 +1,11 @@
|
||||
import * as THREE from 'three';
|
||||
import type { PierModel } from '../core/geometry';
|
||||
import { grid, layers } from '../core/rebar/footing';
|
||||
import { widthLayout } from '../core/rebar/coping-main';
|
||||
import { shearBars, shearBarsMulti, shearUHeight, sideRows } from '../core/rebar/coping';
|
||||
import { assemblyEndOffset, assemblyJs, b10Levels, b9Bars, FOOTING_DEFAULTS, gridPositions, grid, layers, legLength, legOffsets, sideDepth } from '../core/rebar/footing';
|
||||
import { bottomPiece, MAIN, widthLayout } from '../core/rebar/coping-main';
|
||||
import { C14_INSET, c14Bars, CAP, COPING_REBAR, shearBars, shearBarsMulti, shearUHeight, copingSideBars, SIDE_HOOK_LEG, stairBars, undersideAt } from '../core/rebar/coping';
|
||||
import { columnRebar, COLUMN_P1 } from '../core/rebar/column';
|
||||
import { NOMINAL_DIAMETER } from '../core/rebar/common';
|
||||
import { barsAcross, BLOCK_REBAR } from '../core/rebar/bearing-block';
|
||||
import { hookLength, NOMINAL_DIAMETER } from '../core/rebar/common';
|
||||
import { stretchMatrix } from './scene';
|
||||
|
||||
/**
|
||||
@@ -61,51 +62,131 @@ export function buildRebar3D(m: PierModel): RebarScene {
|
||||
const w = widthLayout(B * 1000);
|
||||
const xs = [w.yE, ...Array.from({ length: w.n + 1 }, (_, i) => w.yE + w.g + 125 * i), B * 1000 - w.yE].map((v) => mm(v) - B / 2);
|
||||
const cover = 0.1;
|
||||
// Top rows C1–C6: row k is 3 bars per cycle; the even positions are cycle 1 (C1–C3), the odd cycle 2 (C4–C6).
|
||||
// Top rows C1–C6 (코핑철근.md §5.1, §5.3): counted from the left, the even (1-based) positions are cycle 1 (C1–C3),
|
||||
// the odd cycle 2 (C4–C6). In 0-based j that is odd j → cycle 1. Each row turns down 472 at both ends, and the
|
||||
// k-th row's ends sit (k − 1)·57.2 further in.
|
||||
const topEl = m.copingRefTop;
|
||||
const hookTop = MAIN.hook / 1000;
|
||||
for (let k = 1; k <= 3; k++) {
|
||||
const z = topEl - 0.127 - (k - 1) * 0.057;
|
||||
const xk = cover + ((k - 1) * MAIN.layHorizontal) / 1000;
|
||||
xs.forEach((n, j) => {
|
||||
const name = `C${k + (j % 2 === 1 ? 3 : 0)}`;
|
||||
addBar(name, 0, [cover, z, n], [L - cover, z, n], NOMINAL_DIAMETER.H29, COLOR.coping);
|
||||
const name = `C${k + (j % 2 === 1 ? 0 : 3)}`;
|
||||
const pts: [number, number, number][] = [
|
||||
[xk, z - hookTop, n],
|
||||
[xk, z, n],
|
||||
[L - xk, z, n],
|
||||
[L - xk, z - hookTop, n],
|
||||
];
|
||||
for (let s = 0; s + 1 < pts.length; s++) addBar(name, 0, pts[s], pts[s + 1], NOMINAL_DIAMETER.H29, COLOR.coping);
|
||||
});
|
||||
}
|
||||
// Bottom bars C7 / C8 along the Level height.
|
||||
// Bottom bars C7 / C8 (코핑철근.md §5.2–5.3): they follow the sloped underside, 127 above it, with a vertical leg up
|
||||
// at each end to the C1 level. Each bar is two pieces spliced at the column centre (overlap l_s). The slope runs x_L0 from each end (T형).
|
||||
const xL0 = L / 2 - COPING_REBAR.levelWidth / 2000;
|
||||
const under = (x: number) => undersideAt(L * 1000, x * 1000, m.endBottom, m.levelBottom);
|
||||
const lap = bottomPiece().ls / 2000;
|
||||
xs.forEach((n, j) => {
|
||||
const z = m.levelBottom + 0.127;
|
||||
addBar(j % 2 === 0 ? 'C7' : 'C8', 0, [cover, z, n], [L - cover, z, n], NOMINAL_DIAMETER.H29, COLOR.coping);
|
||||
const z = (x: number) => under(x) + 0.127;
|
||||
const left: [number, number, number][] = [
|
||||
[cover, topEl - 0.127, n],
|
||||
[cover, z(cover), n],
|
||||
[xL0, z(xL0), n],
|
||||
[L / 2 + lap, z(L / 2 + lap), n],
|
||||
];
|
||||
const right = left.map(([x, y, zz]): [number, number, number] => [L - x, y, zz]);
|
||||
const name = j % 2 === 1 ? 'C7' : 'C8';
|
||||
for (const pts of [left, right]) {
|
||||
for (let k = 0; k + 1 < pts.length; k++) addBar(name, 0, pts[k], pts[k + 1], NOMINAL_DIAMETER.H29, COLOR.coping);
|
||||
}
|
||||
});
|
||||
// Shear loops C9 / C10 / C11 and the gaps between columns: a closed U at each position.
|
||||
const colS = m.columns.map((c) => c.s * 1000);
|
||||
const sh = colS.length > 1 ? shearBarsMulti(L * 1000, colS) : { ...shearBars(L * 1000), between: [] as number[] };
|
||||
const loops: [string, number[]][] = [['C9', sh.c9], ['C10', sh.c10], ['C11', sh.c11], ['C9·C11 사이', sh.between]];
|
||||
const ne = B / 2 - 0.1;
|
||||
// Each position has three 폐합 (코핑철근.md §4.1): legs at y_i = c + i·s_leg (i = 0 … 5), 폐합 i = legs i and i + 3,
|
||||
// 1740 wide. Each 폐합 is a 하부 U (base at the bottom, legs up to the top) and a 상부 삿갓 (top bar, legs down
|
||||
// l_cap = h − c) that sits 25.4 beside the U along the coping.
|
||||
const top = topEl - 0.1;
|
||||
const dShear = NOMINAL_DIAMETER.H25;
|
||||
const sLeg = (B * 1000 - 2 * CAP.cover) / 5 / 1000;
|
||||
const legN = (i: number) => -B / 2 + 0.1 + i * sLeg;
|
||||
for (const [name, list] of loops) {
|
||||
for (const x of list) {
|
||||
const xm = mm(x);
|
||||
const bot = top - shearUHeight(x, L * 1000) / 1000;
|
||||
const d = NOMINAL_DIAMETER.H25;
|
||||
addBar(name, 0, [xm, top, -ne], [xm, top, ne], d, COLOR.shear);
|
||||
addBar(name, 0, [xm, bot, -ne], [xm, bot, ne], d, COLOR.shear);
|
||||
addBar(name, 0, [xm, top, -ne], [xm, bot, -ne], d, COLOR.shear);
|
||||
addBar(name, 0, [xm, top, ne], [xm, bot, ne], d, COLOR.shear);
|
||||
const h = shearUHeight(x, L * 1000) / 1000;
|
||||
const bot = top - h;
|
||||
const capBot = top - (h - CAP.cover / 1000);
|
||||
const xc = xm + mm(NOMINAL_DIAMETER.S25);
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const a = legN(i);
|
||||
const b = legN(i + 3);
|
||||
addBar(name, 0, [xm, bot, a], [xm, bot, b], dShear, COLOR.shear);
|
||||
addBar(name, 0, [xm, bot, a], [xm, top, a], dShear, COLOR.shear);
|
||||
addBar(name, 0, [xm, bot, b], [xm, top, b], dShear, COLOR.shear);
|
||||
addBar(name, 0, [xc, top, a], [xc, top, b], dShear, COLOR.shear);
|
||||
addBar(name, 0, [xc, top, a], [xc, capBot, a], dShear, COLOR.shear);
|
||||
addBar(name, 0, [xc, top, b], [xc, capBot, b], dShear, COLOR.shear);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Side horizontal bars C12 / C13 at both side faces.
|
||||
const side = sideRows(41.288, 42.538);
|
||||
// Side horizontal bars C12 / C13 (코핑철근.md §6.2): per row, two 일자 at the side faces from x_w to L − x_w,
|
||||
// and two ㄷ bars: a body across the width at x_w, 25.4 above the row, with legs 1525 inward along the faces.
|
||||
const sideFace = B / 2 - 0.127;
|
||||
const dSide = NOMINAL_DIAMETER.H25;
|
||||
const side = copingSideBars(L * 1000, 41.288, 42.538);
|
||||
for (const [name, rows] of [['C12', side.c12], ['C13', side.c13]] as const) {
|
||||
for (const z of rows) {
|
||||
addBar(name, 0, [cover, z, -sideFace], [L - cover, z, -sideFace], NOMINAL_DIAMETER.H25, COLOR.shear);
|
||||
addBar(name, 0, [cover, z, sideFace], [L - cover, z, sideFace], NOMINAL_DIAMETER.H25, COLOR.shear);
|
||||
for (const r of rows) {
|
||||
const xw = mm(r.xw);
|
||||
addBar(name, 0, [xw, r.z, -sideFace], [L - xw, r.z, -sideFace], dSide, COLOR.shear);
|
||||
addBar(name, 0, [xw, r.z, sideFace], [L - xw, r.z, sideFace], dSide, COLOR.shear);
|
||||
const zh = r.z + mm(dSide);
|
||||
for (const x0 of [xw, L - xw]) {
|
||||
const leg = mm(SIDE_HOOK_LEG) * Math.sign(L / 2 - x0);
|
||||
addBar(name, 0, [x0, zh, -sideFace], [x0, zh, sideFace], dSide, COLOR.shear);
|
||||
addBar(name, 0, [x0, zh, -sideFace], [x0 + leg, zh, -sideFace], dSide, COLOR.shear);
|
||||
addBar(name, 0, [x0, zh, sideFace], [x0 + leg, zh, sideFace], dSide, COLOR.shear);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// C14 ⊓ (코핑철근.md §8): across the width at each x, both ends down 15.5·d_b.
|
||||
const c14Hook = mm(hookLength('main90', NOMINAL_DIAMETER.H19));
|
||||
const c14Na = -B / 2 + mm(C14_INSET);
|
||||
const c14Nb = B / 2 - mm(C14_INSET);
|
||||
for (const b of c14Bars(L * 1000, topEl, [...side.c12, ...side.c13], (x) => undersideAt(L * 1000, x, m.endBottom, m.levelBottom))) {
|
||||
const xm = mm(b.x);
|
||||
addBar('C14', 0, [xm, b.z, c14Na], [xm, b.z, c14Nb], NOMINAL_DIAMETER.H19, COLOR.coping);
|
||||
// 연직 발 below the coping underside is left out (코핑철근.md §8).
|
||||
if (b.legs) {
|
||||
addBar('C14', 0, [xm, b.z - c14Hook, c14Na], [xm, b.z, c14Na], NOMINAL_DIAMETER.H19, COLOR.coping);
|
||||
addBar('C14', 0, [xm, b.z, c14Nb], [xm, b.z - c14Hook, c14Nb], NOMINAL_DIAMETER.H19, COLOR.coping);
|
||||
}
|
||||
}
|
||||
// C15 (거꾸로 된 U) and C16 (L형) on the stair (코핑철근.md §7): 11 bars each across the width.
|
||||
const stairs = stairBars(L * 1000, B * 1000, topEl);
|
||||
for (const s of stairs.c15) {
|
||||
const n = mm(s.n);
|
||||
const ld = mm(s.leg);
|
||||
const x0 = mm(s.x0);
|
||||
const x1 = mm(s.x1);
|
||||
addBar('C15', 0, [x0, s.z - ld, n], [x0, s.z, n], NOMINAL_DIAMETER.H19, COLOR.coping);
|
||||
addBar('C15', 0, [x0, s.z, n], [x1, s.z, n], NOMINAL_DIAMETER.H19, COLOR.coping);
|
||||
addBar('C15', 0, [x1, s.z, n], [x1, s.z - ld, n], NOMINAL_DIAMETER.H19, COLOR.coping);
|
||||
}
|
||||
for (const s of stairs.c16) {
|
||||
const n = mm(s.n);
|
||||
const ld = mm(s.leg);
|
||||
const x0 = mm(s.x0);
|
||||
const x1 = mm(s.x1);
|
||||
addBar('C16', 0, [x0, s.z - ld, n], [x0, s.z, n], NOMINAL_DIAMETER.H19, COLOR.coping);
|
||||
addBar('C16', 0, [x0, s.z, n], [x1, s.z, n], NOMINAL_DIAMETER.H19, COLOR.coping);
|
||||
}
|
||||
}
|
||||
|
||||
// Columns: P1 / P2 main bars on their radii, ties P3 / P5 / P4 as rings, P6 crossties across the column.
|
||||
const col = columnRebar(COLUMN_P1);
|
||||
const zBot = -1697.5;
|
||||
const zBot = col.zBot; // mm
|
||||
const ring = (name: string, k: number, sc: number, y: number, r: number, d: number) => {
|
||||
const N = 36;
|
||||
for (let i = 0; i < N; i++) {
|
||||
@@ -122,16 +203,30 @@ export function buildRebar3D(m: PierModel): RebarScene {
|
||||
const th = (2 * Math.PI * i) / COLUMN_P1.nDiv;
|
||||
const r1 = mm(col.r1);
|
||||
addBar('P1', c.k, [sc + r1 * Math.cos(th), base + mm(zBot), r1 * Math.sin(th)], [sc + r1 * Math.cos(th), base + mm(col.zTop1), r1 * Math.sin(th)], NOMINAL_DIAMETER.S32, COLOR.column);
|
||||
// 90° bottom hook of P1, outward (기둥철근.md §3.2, Q-C5): the 12·d tail is drawn, the bend is approximated by the tail's start.
|
||||
const tail = mm(12 * NOMINAL_DIAMETER.S32);
|
||||
const rOut = r1 + tail;
|
||||
addBar('P1', c.k, [sc + r1 * Math.cos(th), base + mm(zBot), r1 * Math.sin(th)], [sc + rOut * Math.cos(th), base + mm(zBot), rOut * Math.sin(th)], NOMINAL_DIAMETER.S32, COLOR.column);
|
||||
const r2 = mm(col.r2);
|
||||
addBar('P2', c.k, [sc + r2 * Math.cos(th), base + mm(zBot), r2 * Math.sin(th)], [sc + r2 * Math.cos(th), base + mm(col.zTop2), r2 * Math.sin(th)], NOMINAL_DIAMETER.S32, COLOR.column);
|
||||
}
|
||||
for (const z of col.p3) ring('P3', c.k, sc, base + mm(z), rt, NOMINAL_DIAMETER.H19);
|
||||
for (const z of col.p5) ring('P5', c.k, sc, base + mm(z), rt, NOMINAL_DIAMETER.H19);
|
||||
for (const z of col.p4) ring('P4', c.k, sc, base + mm(z), rt, NOMINAL_DIAMETER.H19);
|
||||
const hookP6 = mm(Math.round(hookLength('tie90', NOMINAL_DIAMETER.H16))); // 135 mm
|
||||
for (const z of col.p6Levels) {
|
||||
for (const deg of [0, 46.96, 90, 133.04]) {
|
||||
const a = (deg * Math.PI) / 180;
|
||||
addBar('P6', c.k, [sc - rt * Math.cos(a), base + mm(z), -rt * Math.sin(a)], [sc + rt * Math.cos(a), base + mm(z), rt * Math.sin(a)], NOMINAL_DIAMETER.H16, COLOR.tie);
|
||||
const xA = sc - rt * Math.cos(a);
|
||||
const zA = -rt * Math.sin(a);
|
||||
const xB = sc + rt * Math.cos(a);
|
||||
const zB = rt * Math.sin(a);
|
||||
const yBar = base + mm(z);
|
||||
// Main crosstie across the diameter
|
||||
addBar('P6', c.k, [xA, yBar, zA], [xB, yBar, zB], NOMINAL_DIAMETER.H16, COLOR.tie);
|
||||
// 90° hooks at both ends turning downward (135 mm, wrapping the tie)
|
||||
addBar('P6', c.k, [xA, yBar, zA], [xA, yBar - hookP6, zA], NOMINAL_DIAMETER.H16, COLOR.tie);
|
||||
addBar('P6', c.k, [xB, yBar, zB], [xB, yBar - hookP6, zB], NOMINAL_DIAMETER.H16, COLOR.tie);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,37 +246,122 @@ export function buildRebar3D(m: PierModel): RebarScene {
|
||||
const nA = -Wf / 2 + 0.1;
|
||||
const nB = Wf / 2 - 0.1;
|
||||
const bottom = f.bottom;
|
||||
const along = (name: string, n: number, y: number, dMm: number, color: number) =>
|
||||
addBar(name, 0, [f.s + sA, y, n], [f.s + sB, y, n], dMm, color);
|
||||
const acrossN = (name: string, s: number, y: number, dMm: number, color: number) =>
|
||||
addBar(name, 0, [f.s + s, y, nA], [f.s + s, y, nB], dMm, color);
|
||||
const off = legOffsets();
|
||||
// One name, several cylinders: each segment of the path is one bar piece.
|
||||
const path = (name: string, pts: [number, number, number][], dMm: number) => {
|
||||
for (let k = 0; k + 1 < pts.length; k++) addBar(name, 0, pts[k], pts[k + 1], dMm, COLOR.footing);
|
||||
};
|
||||
// B1–B4: along s, at W position n. legTo (absolute EL, m) is where both ends turn up or down (§5.1); undefined = straight.
|
||||
const along = (name: string, n: number, y: number, legTo: number | undefined, dMm: number) => {
|
||||
const at = (t: number, h: number): [number, number, number] => [f.s + t, h, n];
|
||||
path(name, legTo === undefined ? [at(sA, y), at(sB, y)] : [at(sA, legTo), at(sA, y), at(sB, y), at(sB, legTo)], dMm);
|
||||
};
|
||||
// B5–B8: across, at L position s. Same rule, with the ends on the W faces (§6.2).
|
||||
const across = (name: string, s: number, y: number, legTo: number | undefined, dMm: number) => {
|
||||
const at = (t: number, h: number): [number, number, number] => [f.s + s, h, t];
|
||||
path(name, legTo === undefined ? [at(nA, y), at(nB, y)] : [at(nA, legTo), at(nA, y), at(nB, y), at(nB, legTo)], dMm);
|
||||
};
|
||||
for (let j = 0; j <= gW.n; j++) {
|
||||
const n = posW(j);
|
||||
if (j % 2 === 1) {
|
||||
along('B1', n, bottom + mm(z.B1), NOMINAL_DIAMETER.S25, COLOR.footing);
|
||||
along('B3', n, bottom + mm(z.B3), NOMINAL_DIAMETER.S19, COLOR.footing);
|
||||
// B1 ⊓ down, B2 ⊔ up to the B1 height, B3 ⊔ up. B1·B3 sit beside the B2 leg (+25.4 / +22.25, §5.3).
|
||||
along('B1', n + mm(off.B1), bottom + mm(z.B1), bottom + mm(z.B1) - mm(legLength('S25')), NOMINAL_DIAMETER.S25);
|
||||
along('B2', n, bottom + mm(z.B24), bottom + mm(z.B1), NOMINAL_DIAMETER.S25);
|
||||
along('B3', n + mm(off.B3), bottom + mm(z.B3), bottom + mm(z.B3) + mm(legLength('S19')), NOMINAL_DIAMETER.S19);
|
||||
} else {
|
||||
along('B4', n, bottom + mm(z.B24), NOMINAL_DIAMETER.S25, COLOR.footing);
|
||||
along('B4', n, bottom + mm(z.B24), undefined, NOMINAL_DIAMETER.S25);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i <= gL.n; i++) {
|
||||
const s = posL(i);
|
||||
if (i % 2 === 1) {
|
||||
acrossN('B5', s, bottom + mm(z.B5), NOMINAL_DIAMETER.S29, COLOR.footing);
|
||||
acrossN('B6', s, bottom + mm(z.B68), NOMINAL_DIAMETER.S29, COLOR.footing);
|
||||
acrossN('B7', s, bottom + mm(z.B7), NOMINAL_DIAMETER.S19, COLOR.footing);
|
||||
// B5 ⊓ down, B6 ⊔ up to the B5 height, B7 ⊔ up. B5·B7 sit beside the B6 leg (+28.6 / +23.85, §6.3).
|
||||
across('B5', s + mm(off.B5), bottom + mm(z.B5), bottom + mm(z.B5) - mm(legLength('S29')), NOMINAL_DIAMETER.S29);
|
||||
across('B6', s, bottom + mm(z.B68), bottom + mm(z.B5), NOMINAL_DIAMETER.S29);
|
||||
across('B7', s + mm(off.B7), bottom + mm(z.B7), bottom + mm(z.B7) + mm(legLength('S19')), NOMINAL_DIAMETER.S19);
|
||||
} else {
|
||||
acrossN('B8', s, bottom + mm(z.B68), NOMINAL_DIAMETER.S29, COLOR.footing);
|
||||
across('B8', s, bottom + mm(z.B68), undefined, NOMINAL_DIAMETER.S29);
|
||||
}
|
||||
}
|
||||
// B9 (확대기초철근 (1).md §9, rule applied): vertical H16 bars on the grid, outside the column zones, with 135° hooks.
|
||||
// Each hook tail (6·d) turns toward the footing centre along the pier axis (Q-B19).
|
||||
const dB9 = NOMINAL_DIAMETER.H16;
|
||||
const tail9 = (6 * dB9) / 1000;
|
||||
const colX = m.columns.filter((c) => Math.abs(c.s - f.s) <= Lf / 2).map((c) => (c.s - f.s) * 1000);
|
||||
const yB9Bot = bottom + mm(z.B24);
|
||||
const yB9Top = bottom + mm(z.B5);
|
||||
for (const b of b9Bars(Lf * 1000, Wf * 1000, colX).bars) {
|
||||
const x = mm(b.x);
|
||||
const n = mm(b.n);
|
||||
const tailDir = x >= 0 ? -1 : 1;
|
||||
addBar('B9', 0, [f.s + x, yB9Bot, n], [f.s + x, yB9Top, n], dB9, COLOR.footing);
|
||||
addBar('B9', 0, [f.s + x, yB9Top, n], [f.s + x + tailDir * tail9, yB9Top, n], dB9, COLOR.footing);
|
||||
addBar('B9', 0, [f.s + x, yB9Bot, n], [f.s + x + tailDir * tail9, yB9Bot, n], dB9, COLOR.footing);
|
||||
}
|
||||
|
||||
// B10-1 / B10-2 (§7) at each B10 level, B11 / B12 (§8) between them. Ends turn 90° inward (B10) or down (B11, B12).
|
||||
const polyline = (name: string, pts: [number, number, number][], dMm: number) => {
|
||||
for (let k = 0; k + 1 < pts.length; k++) addBar(name, 0, pts[k], pts[k + 1], dMm, COLOR.footing);
|
||||
};
|
||||
const hookB10 = mm(hookLength('main90', NOMINAL_DIAMETER.S19)); // 296
|
||||
const hookAsm = mm(Math.round(hookLength('main90', NOMINAL_DIAMETER.S16))); // 246
|
||||
const d1 = sideDepth(NOMINAL_DIAMETER.S29, NOMINAL_DIAMETER.S19); // B10-1 depth (mm), on the W faces
|
||||
const d2 = sideDepth(NOMINAL_DIAMETER.S25, NOMINAL_DIAMETER.S19); // B10-2 depth (mm), on the L faces
|
||||
const sEdge = Lf / 2 - mm(d2);
|
||||
const nEdge = Wf / 2 - mm(d1);
|
||||
const dB10 = mm(NOMINAL_DIAMETER.S19);
|
||||
for (let j = 0; j < b10Levels(Hf); j++) {
|
||||
const zj = bottom + mm(FOOTING_DEFAULTS.cBottom + j * FOOTING_DEFAULTS.sV);
|
||||
for (const sg of [-1, 1]) {
|
||||
// B10-2: across W at the L faces; its ends turn inward along s.
|
||||
const sp = f.s + sg * sEdge;
|
||||
polyline('B10-2', [[sp - sg * hookB10, zj, -nEdge], [sp, zj, -nEdge], [sp, zj, nEdge], [sp - sg * hookB10, zj, nEdge]], NOMINAL_DIAMETER.S19);
|
||||
// B10-1: along s at the W faces, 19.1 above B10-2; its ends turn inward along n.
|
||||
const np = sg * nEdge;
|
||||
const zb = zj + dB10;
|
||||
polyline('B10-1', [[f.s - sEdge, zb, np - sg * hookB10], [f.s - sEdge, zb, np], [f.s + sEdge, zb, np], [f.s + sEdge, zb, np - sg * hookB10]], NOMINAL_DIAMETER.S19);
|
||||
}
|
||||
}
|
||||
// B11 (across W, spread along L) and B12 (along L, spread across W) at the assembly levels, 4s apart, 2s stagger per level.
|
||||
const xsL = gridPositions(Lf * 1000);
|
||||
const ysW = gridPositions(Wf * 1000);
|
||||
const dAsm = assemblyEndOffset();
|
||||
const nAsm = Wf / 2 - mm(d1 + dAsm);
|
||||
const sAsm = Lf / 2 - mm(d2 + dAsm);
|
||||
assemblyJs(Hf).forEach((jA, k) => {
|
||||
const zA = bottom + mm(FOOTING_DEFAULTS.cBottom + jA * FOOTING_DEFAULTS.sV);
|
||||
const zB = zA + dB10;
|
||||
const i0 = k % 2 === 0 ? 0 : 2;
|
||||
for (let iL = i0; iL < xsL.length; iL += 4) {
|
||||
const x = f.s + mm(xsL[iL]);
|
||||
polyline('B11', [[x, zA - hookAsm, -nAsm], [x, zA, -nAsm], [x, zA, nAsm], [x, zA - hookAsm, nAsm]], NOMINAL_DIAMETER.S16);
|
||||
}
|
||||
for (let iW = i0; iW < ysW.length; iW += 4) {
|
||||
const n = mm(ysW[iW]);
|
||||
polyline('B12', [[f.s - sAsm, zB - hookAsm, n], [f.s - sAsm, zB, n], [f.s + sAsm, zB, n], [f.s + sAsm, zB - hookAsm, n]], NOMINAL_DIAMETER.S16);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Bearing blocks: S2 (upper, along s) and S1 (lower, along n), 8 bars each across the 1200 block.
|
||||
// Positions from barsAcross (162.5 from the block edge, @125), bars a − 2·c_s long, legs 700 down at both ends (§3–5).
|
||||
const across = barsAcross();
|
||||
const half = (BLOCK_REBAR.dim - 2 * BLOCK_REBAR.cover) / 2000;
|
||||
const legM = BLOCK_REBAR.legLength / 1000;
|
||||
const offsets = Array.from({ length: across.count }, (_, i) => (across.firstEnd + i * across.spacing) / 1000 - BLOCK_REBAR.dim / 2000);
|
||||
const dBar = NOMINAL_DIAMETER.H19;
|
||||
for (const b of m.blocks) {
|
||||
for (let j = 0; j < 8; j++) {
|
||||
const off = (j - 3.5) * 0.125;
|
||||
addBar('S2', b.k, [b.s - 0.5, b.top - 0.05, b.n + off], [b.s + 0.5, b.top - 0.05, b.n + off], NOMINAL_DIAMETER.H19, COLOR.block);
|
||||
addBar('S1', b.k, [b.s + off, b.top - 0.069, b.n - 0.5], [b.s + off, b.top - 0.069, b.n + 0.5], NOMINAL_DIAMETER.H19, COLOR.block);
|
||||
const z2 = b.top - BLOCK_REBAR.depthS2 / 1000;
|
||||
const z1 = b.top - BLOCK_REBAR.depthS1 / 1000;
|
||||
for (const off of offsets) {
|
||||
const n2 = b.n + off;
|
||||
addBar('S2', b.k, [b.s - half, z2, n2], [b.s + half, z2, n2], dBar, COLOR.block);
|
||||
addBar('S2', b.k, [b.s - half, z2 - legM, n2], [b.s - half, z2, n2], dBar, COLOR.block);
|
||||
addBar('S2', b.k, [b.s + half, z2, n2], [b.s + half, z2 - legM, n2], dBar, COLOR.block);
|
||||
const s1 = b.s + off;
|
||||
addBar('S1', b.k, [s1, z1, b.n - half], [s1, z1, b.n + half], dBar, COLOR.block);
|
||||
addBar('S1', b.k, [s1, z1 - legM, b.n - half], [s1, z1, b.n - half], dBar, COLOR.block);
|
||||
addBar('S1', b.k, [s1, z1, b.n + half], [s1, z1 - legM, b.n + half], dBar, COLOR.block);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user