;
}
function VaultDiagram({ span, rise, cpeProfile }: VaultProps) {
const vw = 400, vh = 300;
const s = Math.min((vw - 80) / span, (vh - 80) / rise);
const ox = vw / 2, oy = vh - 40;
const spanS = span * s, riseS = rise * s;
const archPoints: string[] = [];
const segments = 32;
for (let i = 0; i <= segments; i++) {
const t = i / segments;
const x = ox - spanS / 2 + t * spanS;
const y = oy - riseS * Math.sin(t * Math.PI);
archPoints.push(`${x},${y}`);
}
const zones = [
{ idx: 0, label: '1', key: 'zone1' },
{ idx: 5, label: '2', key: 'zone2' },
{ idx: 11, label: '3', key: 'zone3' },
{ idx: 16, label: '4', key: 'zone4' },
{ idx: 21, label: '5', key: 'zone5' },
{ idx: 27, label: '6', key: 'zone6' },
];
return (
);
}
interface DomeProps {
diameter: number;
rise: number;
wallHeight: number;
cpi: number;
cpeBarlavento: number;
cpeTopo: number;
cpeLateral: number;
}
function DomeDiagram({ diameter, rise, wallHeight, cpeBarlavento, cpeTopo }: DomeProps) {
const vw = 400, vh = 300;
const s = Math.min((vw - 80) / diameter, (vh - 80) / (wallHeight + rise));
const cx = vw / 2, cy = vh - 40;
const r = (diameter / 2) * s;
const wh = wallHeight * s;
const rh = rise * s;
return (
);
}
interface SignProps {
length: number;
height: number;
groundClearance: number;
alpha: number;
cf: number;
forceKN: number;
applicationPoint: number;
}
function SignDiagram({ length, height, groundClearance, cf, forceKN }: SignProps) {
const vw = 400, vh = 300;
const s = Math.min((vw - 100) / length, (vh - 80) / (height + groundClearance));
const cx = vw / 2, ground = vh - 40;
const gc = groundClearance * s;
const h = height * s;
const w = length * s;
const plateY = ground - gc - h;
return (
);
}
interface BarProps {
barType: 'flat' | 'circular';
section?: string;
diameter?: number;
width?: number;
length: number;
alpha: number;
fxKN: number;
fyKN: number;
cx: number;
}
function BarDiagram({ barType, length, alpha, fxKN, fyKN, cx: cxVal }: BarProps) {
const vw = 400, vh = 300;
const cx = vw / 2, cy = vh / 2;
const barLen = Math.min(length * 8, vw - 100);
const forceMag = Math.sqrt(fxKN * fxKN + fyKN * fyKN);
const forceAngle = Math.atan2(fyKN, fxKN);
void barType;
return (
);
}
interface BridgeProps {
lp: number;
width: number;
deckHeight: number;
heg: number;
cx: number;
cz: number;
fxPerLength: number;
fzPerLength: number;
}
function BridgeDiagram({ lp, width, deckHeight, heg, cx: cxVal, fxPerLength, fzPerLength }: BridgeProps) {
const vw = 400, vh = 300;
const s = Math.min((vw - 80) / lp, (vh - 80) / (deckHeight + heg));
const ox = vw / 2, ground = vh - 40;
const lpS = lp * s;
const dh = deckHeight * s;
const deckT = Math.max(heg, 0.8) * s;
return (
);
}
interface TowerProps {
section: 'square' | 'triangular';
baseWidth: number;
height: number;
panels: number;
phi: number;
alphaWind: number;
forceKN: number;
}
function TowerDiagram({ baseWidth, height, panels, phi, forceKN }: TowerProps) {
const vw = 400, vh = 300;
const s = Math.min((vw - 80) / baseWidth, (vh - 80) / height);
const cx = vw / 2, ground = vh - 40;
const bw = baseWidth * s;
const h = height * s;
const lines: React.ReactElement[] = [];
for (let p = 0; p < panels; p++) {
const y0 = ground - (p / panels) * h;
const y1 = ground - ((p + 1) / panels) * h;
const shrink = p / panels;
const nextShrink = (p + 1) / panels;
const w0 = bw * (1 - shrink * 0.6);
const w1 = bw * (1 - nextShrink * 0.6);
// Montantes
lines.push();
lines.push();
// Diagonais
lines.push();
lines.push();
// Travessa
lines.push();
}
return (
);
}
interface IsolatedRoofProps {
type: 'shed' | 'gable';
theta: number;
height: number;
depth: number;
cpeWindward: number;
cpeLeeward: number;
cpeTop: number;
forceKN: number;
}
function IsolatedRoofDiagram({ type, theta, height, depth, cpeWindward, cpeLeeward, cpeTop, forceKN }: IsolatedRoofProps) {
const vw = 400, vh = 300;
const s = Math.min((vw - 100) / depth, (vh - 80) / (height + depth * Math.tan((theta * Math.PI) / 180)));
const cx = vw / 2, ground = vh - 40;
const h = height * s;
const d = depth * s;
const rise = d * Math.tan((theta * Math.PI) / 180);
return (
);
}
interface DynamicsProps {
height: number;
freq: number;
windSpeed: number;
scruton: number;
sectionShape: string;
sectionSize: number;
showVortexStreet: boolean;
showModeShape: boolean;
}
function DynamicsDiagram({ height, freq, scruton, sectionShape, sectionSize, showVortexStreet, showModeShape }: DynamicsProps) {
const vw = 400, vh = 300;
const s = Math.min((vw - 100) / sectionSize, (vh - 80) / height);
const cx = vw / 2, ground = vh - 40;
const h = height * s;
const w = sectionSize * s;
void sectionShape;
return (
);
}
export type FallbackDiagramProps =
| { type: 'warehouse'; props: WarehouseProps }
| { type: 'cylinder'; props: CylinderProps }
| { type: 'vault'; props: VaultProps }
| { type: 'dome'; props: DomeProps }
| { type: 'sign'; props: SignProps }
| { type: 'bar'; props: BarProps }
| { type: 'bridge'; props: BridgeProps }
| { type: 'tower'; props: TowerProps }
| { type: 'isolatedRoof'; props: IsolatedRoofProps }
| { type: 'dynamics'; props: DynamicsProps };
export default function FallbackDiagram(input: FallbackDiagramProps) {
return (
{input.type === 'warehouse' && }
{input.type === 'cylinder' && }
{input.type === 'vault' && }
{input.type === 'dome' && }
{input.type === 'sign' && }
{input.type === 'bar' && }
{input.type === 'bridge' && }
{input.type === 'tower' && }
{input.type === 'isolatedRoof' && }
{input.type === 'dynamics' && }
);
}