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
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)
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 Dist | Cf | F (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)
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
);
};