import React, { useState } from 'react'; import { useCalculatorStore } from '../../../store/calculatorStore'; import { calculateWindPressure } from '../../../utils/windLogic'; import { LoadCaseADiagram, LoadCaseBDiagram, LoadCaseCDiagram, SolidSignDimensionsDiagram } from '../diagrams/OtherStructuresDiagrams'; export const OtherStructuresSheet: React.FC = () => { const { wind } = useCalculatorStore(); // Kd Overrides const [kdOverrides, setKdOverrides] = useState({ A: 0.85, B: 0.85, C: 0.90, D: 0.85 }); // Section A: Solid Freestanding Walls & Solid Signs const [solidSign, setSolidSign] = useState({ h: 80.0, s: 20.0, B: 50.0, Lr: 0.0, openPct: 0.0, userInputAs: 10.0 }); const Kd_A = kdOverrides.A; // Section B: Open Signs & Open Frames const [openSign, setOpenSign] = useState({ z: 15.0, width: 0.0, diameter: 2.0, openPct: 35.0, userInputAf: 10.0 }); const Kd_B = kdOverrides.B; // Section C: Chimneys, Tanks const [chimney, setChimney] = useState({ z: 15.0, type: 'Square' as 'Square' | 'Hexagonal' | 'Round', h: 15.0, D: 1.0, surface: 'N/A', userInputAf: 10.0 }); const Kd_C = kdOverrides.C; // Section D: Trussed Towers const [tower, setTower] = useState({ z: 15.0, epsilon: 0.27, crossSection: 'Square' as 'Square' | 'Triangular', memberShape: 'Flat' as 'Flat' | 'Round', userInputAf: 10.0 }); const Kd_D = kdOverrides.D; // --- Calculations --- // A. Solid Signs const ratio_s_h = solidSign.s / solidSign.h; const ratio_B_s = solidSign.B / solidSign.s; const ratio_Lr_s = solidSign.Lr / solidSign.s; // Qh calc for height (h) const qh_A = calculateWindPressure({ speed: wind.speed, exposure: wind.exposure, height: solidSign.h, kzt: wind.topography.factor, kd: 1.0, ke: wind.groundElevationFactor, g: -1 }) * Kd_A; // Cf logic placeholder (ASCE 7 Figure 29.3-1) const Cf_AB = 1.80; const F_AB = qh_A * wind.gust.factor * Cf_AB * solidSign.userInputAs; // Case C logic placeholder const Cf_C_0s = 2.43; const Cf_C_s2s = 1.60; const Cf_C_2s3s = 1.15; // B. Open Signs const qz_B = calculateWindPressure({ speed: wind.speed, exposure: wind.exposure, height: openSign.z, kzt: wind.topography.factor, kd: 1.0, ke: wind.groundElevationFactor, g: -1 }) * Kd_B; const Cf_B = 1.6; // Placeholder for epsilon based const F_B = qz_B * wind.gust.factor * Cf_B * openSign.userInputAf; // C. Chimneys const qz_C = calculateWindPressure({ speed: wind.speed, exposure: wind.exposure, height: chimney.z, kzt: wind.topography.factor, kd: 1.0, ke: wind.groundElevationFactor, g: -1 }) * Kd_C; const Cf_C_Diag = 1.28; // Square diag const Cf_C_Norm = 1.67; // Square normal const F_C_Diag = qz_C * wind.gust.factor * Cf_C_Diag * chimney.userInputAf; const F_C_Norm = qz_C * wind.gust.factor * Cf_C_Norm * chimney.userInputAf; // D. Towers const qz_D = calculateWindPressure({ speed: wind.speed, exposure: wind.exposure, height: tower.z, kzt: wind.topography.factor, kd: 1.0, ke: wind.groundElevationFactor, g: -1 }) * Kd_D; const Cf_D_Diag = 3.24; const Cf_D_Norm = 2.70; const F_D_Diag = qz_D * wind.gust.factor * Cf_D_Diag * tower.userInputAf; const F_D_Norm = qz_D * wind.gust.factor * Cf_D_Norm * tower.userInputAf; return (

Wind Loads - Other Structures: ASCE 7-22

Ultimate Wind Pressures
Wind Factor = 1.00
Gust Effect Factor (G) = {wind.gust.factor}
Kzt = {wind.topography.factor}
Ultimate Wind Speed = {wind.speed} mph
Exposure = {wind.exposure}
{/* Kd Override Table */}
Kd override values
for jurisdictions that
modify Kd
A. Solid Signs
setKdOverrides({ ...kdOverrides, A: parseFloat(e.target.value) })} style={{ width: '50px', background: '#d1fae5' }} />
B. Open Signs, etc
setKdOverrides({ ...kdOverrides, B: parseFloat(e.target.value) })} style={{ width: '50px', background: '#d1fae5' }} />
C. Chimneys, etc
setKdOverrides({ ...kdOverrides, C: parseFloat(e.target.value) })} style={{ width: '50px', background: '#d1fae5' }} />
D. Trussed towers
setKdOverrides({ ...kdOverrides, D: parseFloat(e.target.value) })} style={{ width: '50px', background: '#d1fae5' }} />
{/* A. Solid Freestanding Walls */}

A. Solid Freestanding Walls & Solid Signs (& open signs with less than 30% open)

Dist to sign top (h) = setSolidSign({ ...solidSign, h: parseFloat(e.target.value) })} style={{ width: '60px' }} /> ft
Height (s) = setSolidSign({ ...solidSign, s: parseFloat(e.target.value) })} style={{ width: '60px' }} /> ft
Width (B) = setSolidSign({ ...solidSign, B: parseFloat(e.target.value) })} style={{ width: '60px' }} /> ft
Wall Return (Lr) = setSolidSign({ ...solidSign, Lr: parseFloat(e.target.value) })} style={{ width: '60px' }} /> ft
Directionality (Kd) = {Kd_A} (Override A)
% open area = setSolidSign({ ...solidSign, openPct: parseFloat(e.target.value) })} style={{ width: '60px' }} />%
s/h = {ratio_s_h.toFixed(2)}
B/s = {ratio_B_s.toFixed(2)}
Lr/s = {ratio_Lr_s.toFixed(2)}
Kd qh = {qh_A.toFixed(1)} psf
Case A & B
Cf = {Cf_AB.toFixed(2)}
F = Kd qh G Cf As = {(qh_A * wind.gust.factor * Cf_AB).toFixed(1)} As
As = setSolidSign({ ...solidSign, userInputAs: parseFloat(e.target.value) })} style={{ width: '50px', background: '#ffcccb' }} /> sf
F = {F_AB.toFixed(0)} lbs
Case C
{/* Simplified Case C Table */}
Horiz DistCfF (psf)
0 to s{Cf_C_0s}{(qh_A * wind.gust.factor * Cf_C_0s).toFixed(1)} As
s to 2s{Cf_C_s2s}{(qh_A * wind.gust.factor * Cf_C_s2s).toFixed(1)} As
2s to 3s{Cf_C_2s3s}{(qh_A * wind.gust.factor * Cf_C_2s3s).toFixed(1)} As
{/* B. Open Signs */}

B. Open Signs & Single-Plane Open Frames (openings 30% or more)

Height to centroid (z) = setOpenSign({ ...openSign, z: parseFloat(e.target.value) })} style={{ width: '60px' }} /> ft
% of open area = setOpenSign({ ...openSign, openPct: parseFloat(e.target.value) })} style={{ width: '60px' }} />%
Directionality (Kd) = {Kd_B} (Override B)
Base pressure (Kd qz) = {qz_B.toFixed(1)} psf
Cf = {Cf_B}
F = Kdqz G Cf Af = {(qz_B * wind.gust.factor * Cf_B).toFixed(1)} Af
Solid Area Af = setOpenSign({ ...openSign, userInputAf: parseFloat(e.target.value) })} style={{ width: '50px', background: '#ffcccb' }} /> sf
F = {F_B.toFixed(0)} lbs
{/* C. Chimneys */}

C. Walls of Chimneys, Tanks, & Similar Structures

Height to centroid (z) = setChimney({ ...chimney, z: parseFloat(e.target.value) })} style={{ width: '60px' }} /> ft
Cross-Section:
Height (h) = {chimney.h} ft
Width (D) = {chimney.D} ft
Base pressure (Kd qz) = {qz_C.toFixed(1)} psf
h/D = {(chimney.h / chimney.D).toFixed(2)}
Square (wind along diagonal)
Cf = {Cf_C_Diag}
F = {(qz_C * wind.gust.factor * Cf_C_Diag).toFixed(1)} Af
Af = setChimney({ ...chimney, userInputAf: parseFloat(e.target.value) })} style={{ width: '50px', background: '#ffcccb' }} /> sf
F = {F_C_Diag.toFixed(0)} lbs
Square (wind normal to face)
Cf = {Cf_C_Norm}
F = {(qz_C * wind.gust.factor * Cf_C_Norm).toFixed(1)} Af
Af = setChimney({ ...chimney, userInputAf: parseFloat(e.target.value) })} style={{ width: '50px', background: '#ffcccb' }} /> sf
F = {F_C_Norm.toFixed(0)} lbs
{/* D. Trussed Towers */}

D. Trussed Towers

Height to centroid (z) = setTower({ ...tower, z: parseFloat(e.target.value) })} style={{ width: '60px' }} /> ft
ε = {tower.epsilon}
Cross Section: Square
Base pressure (Kd qz) = {qz_D.toFixed(1)} psf
Square (wind along tower diagonal)
Cf = {Cf_D_Diag}
F = {(qz_D * wind.gust.factor * Cf_D_Diag).toFixed(1)} Af
Af = setTower({ ...tower, userInputAf: parseFloat(e.target.value) })} style={{ width: '50px', background: '#ffcccb' }} /> sf
F = {F_D_Diag.toFixed(0)} lbs
Square (wind normal to face)
Cf = {Cf_D_Norm}
F = {(qz_D * wind.gust.factor * Cf_D_Norm).toFixed(1)} Af
Af = setTower({ ...tower, userInputAf: parseFloat(e.target.value) })} style={{ width: '50px', background: '#ffcccb' }} /> sf
F = {F_D_Norm.toFixed(0)} lbs
); };