🚀 Auto-deploy: BrainWind atualizado em 13/07/2026 19:32:43

This commit is contained in:
2026-07-13 19:32:43 +00:00
parent db9db5ff57
commit c446542a26
+10 -61
View File
@@ -81,16 +81,6 @@ const PiperackModule: React.FC = () => {
{ label: 'Força Global Total', value: `${result.globalForce.toFixed(2)} kN` },
{ label: 'Momento Total de Tombamento', value: `${(result.linearLoadFront * width * elevation + (numFrames > 1 ? (numFrames - 1) * result.linearLoadBack * width * elevation : 0)).toFixed(2)} kN·m` },
],
},
{
title: 'Reações Globais Simplificadas (Ação de Conjunto)',
type: 'grid',
gridItems: numFrames > 1 ? [
{ label: 'Braço de Alavanca Total (L)', value: `${((numFrames - 1) * spacing).toFixed(2)} m` },
{ label: `Reação nas Extremidades (C1 / C${numFrames})`, value: `±${((result.linearLoadFront * width * elevation + (numFrames - 1) * result.linearLoadBack * width * elevation) / ((numFrames - 1) * spacing)).toFixed(2)} kN` },
] : [
{ label: 'Momento Fletor na Base (Pórtico Único)', value: `${(result.linearLoadFront * width * elevation).toFixed(2)} kN·m` }
],
}
];
@@ -259,16 +249,8 @@ const PiperackModule: React.FC = () => {
<span className="font-mono font-bold text-primary">{result.linearLoadBack.toFixed(2)} kN/m</span>
</div>
{(() => {
const mFrontal = result.linearLoadFront * width * elevation;
const mTraseiro = numFrames > 1 ? result.linearLoadBack * width * elevation : 0;
const mTotal = mFrontal + (numFrames - 1) * mTraseiro;
const braco = (numFrames - 1) * spacing;
const reacaoGlobal = braco > 0 ? mTotal / braco : 0;
return (
<div className="pt-2">
<h4 className="font-semibold text-sm mb-3">Reações Simplificadas (Vista Lateral)</h4>
<h4 className="font-semibold text-sm mb-3">Distribuição do Vento (Vista Lateral)</h4>
<div className="bg-muted/30 p-3 rounded-md border text-xs space-y-4">
<svg width="100%" height="150" viewBox="0 0 300 150" className="bg-white rounded border">
@@ -294,8 +276,6 @@ const PiperackModule: React.FC = () => {
{/* Colunas */}
{Array.from({ length: numFrames }).map((_, i) => {
const colX = numFrames === 1 ? 150 : startX + i * step;
const isFirst = i === 0;
const isLast = i === numFrames - 1;
return (
<g key={`col-${i}`}>
@@ -303,24 +283,6 @@ const PiperackModule: React.FC = () => {
<text x={colX + 4} y="125" textAnchor="middle" fontSize={numFrames > 3 ? "8" : "10"} fill="#475569">
{`C${i + 1}`}
</text>
{/* Tração na primeira */}
{isFirst && (
<>
<line x1={colX - 10} y1="110" x2={colX - 10} y2="80" stroke="#ef4444" strokeWidth="2" markerEnd="url(#arrowUp)" />
<text x={colX - 15} y="95" textAnchor="end" fill="#ef4444" fontSize="10">Tração</text>
<text x={colX + 4} y="135" textAnchor="middle" fontSize="8" fill="#475569">Barlavento</text>
</>
)}
{/* Compressão na última */}
{isLast && numFrames > 1 && (
<>
<line x1={colX + 13} y1="80" x2={colX + 13} y2="110" stroke="#3b82f6" strokeWidth="2" markerEnd="url(#arrowDown)" />
<text x={colX + 18} y="95" textAnchor="start" fill="#3b82f6" fontSize="10">Comp.</text>
<text x={colX + 4} y="135" textAnchor="middle" fontSize="8" fill="#475569">Sotavento</text>
</>
)}
</g>
);
})}
@@ -349,43 +311,30 @@ const PiperackModule: React.FC = () => {
<circle cx="200" cy="30" r="12" fill="#3b82f6" fillOpacity="0.8" />
<defs>
<marker id="arrowUp" markerWidth="6" markerHeight="6" refX="3" refY="0" orient="auto">
<path d="M0,6 L3,0 L6,6" fill="none" stroke="#ef4444" strokeWidth="1.5" />
</marker>
<marker id="arrowDown" markerWidth="6" markerHeight="6" refX="3" refY="6" orient="auto">
<path d="M0,0 L3,6 L6,0" fill="none" stroke="#3b82f6" strokeWidth="1.5" />
</marker>
<marker id="arrowRight" markerWidth="6" markerHeight="6" refX="6" refY="3" orient="auto">
<path d="M0,0 L6,3 L0,6" fill="none" stroke="#10b981" strokeWidth="1.5" />
</marker>
</defs>
</svg>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 pt-2">
<div className="pt-2 space-y-2">
<div className="font-bold text-primary">Forças e Momentos Aerodinâmicos</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 bg-background p-3 rounded border">
<div className="space-y-1">
<div className="font-bold text-primary">Forças e Momentos</div>
<div className="flex justify-between text-muted-foreground"><span>F. Frontal:</span> <span className="font-mono">{(result.linearLoadFront * width).toFixed(2)} kN</span></div>
{numFrames > 1 && <div className="flex justify-between text-muted-foreground"><span>F. Traseiros (Total):</span> <span className="font-mono">{((numFrames - 1) * result.linearLoadBack * width).toFixed(2)} kN</span></div>}
<div className="flex justify-between text-muted-foreground font-semibold mt-1"><span>Momento Global:</span> <span className="font-mono">{mTotal.toFixed(2)} kN·m</span></div>
</div>
<div className="space-y-1">
<div className="font-bold text-primary">Reações Globais (Conjunto)</div>
{numFrames > 1 ? (
<>
<div className="flex justify-between text-muted-foreground"><span>Alavanca Total (L):</span> <span className="font-mono">{braco.toFixed(2)} m</span></div>
<div className="flex justify-between text-muted-foreground font-semibold mt-1"><span>Reação (C1/C{numFrames}):</span> <span className="font-mono text-primary">±{reacaoGlobal.toFixed(2)} kN</span></div>
</>
) : (
<div className="text-muted-foreground text-[10px] leading-tight mt-1">
Pórtico único. O momento de {mTotal.toFixed(2)} kN·m é absorvido como momento fletor engastado nas bases das colunas.
<div className="flex justify-between text-primary font-medium"><span>Momento Global de Tombamento:</span></div>
<div className="flex justify-end font-mono font-bold text-base">{(result.linearLoadFront * width * elevation + (numFrames > 1 ? (numFrames - 1) * result.linearLoadBack * width * elevation : 0)).toFixed(2)} kN·m</div>
</div>
)}
</div>
<p className="text-[10px] text-muted-foreground leading-tight text-center">
* O Momento Global representa a ação aerodinâmica pura. As reações reais (esforços axiais e fletores) devem ser obtidas no modelo estrutural.
</p>
</div>
</div>
</div>
</div>
);
})()}
</CardContent>
</Card>