完善AMESim组件界面与仿真求解稳定性

This commit is contained in:
ljz committed 2026-08-02 00:57:48 +08:00
1 parent e7177ab03e
commit 410ef535e8
34 files changed
+3340 -251

No files matched your search

+233
View File
@@ -0,0 +1,233 @@
import {
SYMBOL_ACCENT,
SYMBOL_FILL,
SYMBOL_MUTED,
SYMBOL_STROKE,
SymbolSvg,
} from "./primitives";
const PNEUMATIC_STROKE_WIDTH = 1.7;
function OrificeBody({
centerY = 25,
leftPortY = centerY,
}: {
centerY?: number;
leftPortY?: number;
}) {
const top = centerY - 10;
const bottom = centerY + 10;
const leftConnector =
leftPortY === centerY
? `M2 ${centerY}h18`
: `M2 ${leftPortY}h14L20 ${centerY}`;
return (
<>
<path
d={`${leftConnector}M44 ${centerY}h18M20 ${centerY}h24`}
stroke={SYMBOL_STROKE}
strokeLinecap="round"
strokeWidth={PNEUMATIC_STROKE_WIDTH}
/>
<path
d={`M20 ${top}c5 6 9 7 12 7s7-1 12-7M20 ${bottom}c5-6 9-7 12-7s7 1 12 7`}
stroke={SYMBOL_STROKE}
strokeLinecap="round"
strokeWidth={PNEUMATIC_STROKE_WIDTH}
/>
</>
);
}
/** Constant-coefficient pneumatic orifice (AMESim PNOR001). */
export function AmesimPnor001Symbol() {
return (
<SymbolSvg className="component-symbol-amesim-pnor001-svg" domain="pneumatic">
<OrificeBody centerY={24} />
</SymbolSvg>
);
}
/** PNVO001 convenience variant whose opening is fixed by a parameter. */
export function AmesimPnvo001FixedSymbol() {
return (
<SymbolSvg
className="component-symbol-amesim-pnvo001-fixed-svg"
domain="pneumatic"
>
<OrificeBody centerY={28} />
<path
d="M43 4 34 20m9-16-2 7-5-3"
stroke={SYMBOL_ACCENT}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="1.7"
/>
</SymbolSvg>
);
}
/** Signal-modulated pneumatic orifice (AMESim PNVO001 / pn_morifice). */
export function AmesimPnvo001SignalSymbol() {
return (
<SymbolSvg
className="component-symbol-amesim-pnvo001-signal-svg"
domain="pneumatic"
>
<OrificeBody centerY={25} leftPortY={32} />
<path
d="M2 16h11l21 5m0 0-7-1m7 1-5 5"
stroke={SYMBOL_ACCENT}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="1.7"
/>
</SymbolSvg>
);
}
type PipeSection = "C" | "R";
function PipeNetworkBody({ sections }: { sections: readonly PipeSection[] }) {
const left = 9;
const right = 55;
const top = 13;
const bottom = 35;
const sectionWidth = (right - left) / sections.length;
return (
<>
<path
d="M2 24h7M55 24h7"
stroke={SYMBOL_STROKE}
strokeLinecap="round"
strokeWidth={PNEUMATIC_STROKE_WIDTH}
/>
<rect
fill={SYMBOL_FILL}
height={bottom - top}
rx="2"
stroke={SYMBOL_STROKE}
strokeWidth={PNEUMATIC_STROKE_WIDTH}
width={right - left}
x={left}
y={top}
/>
{sections.slice(1).map((_, index) => {
const x = left + sectionWidth * (index + 1);
return (
<path
d={`M${x} ${top + 2}v${bottom - top - 4}`}
key={x}
stroke={SYMBOL_MUTED}
strokeWidth="1.1"
/>
);
})}
{sections.map((section, index) => (
<text
dominantBaseline="central"
fill={section === "R" ? SYMBOL_ACCENT : SYMBOL_MUTED}
fontFamily="Arial, sans-serif"
fontSize="9"
fontWeight="700"
key={`${section}-${index}`}
textAnchor="middle"
x={left + sectionWidth * (index + 0.5)}
y="24"
>
{section}
</text>
))}
</>
);
}
/** Pure pneumatic resistance line (AMESim PNL00R). */
export function AmesimPnl00rSymbol() {
return (
<SymbolSvg className="component-symbol-amesim-pnl00r-svg" domain="pneumatic">
<PipeNetworkBody sections={["R"]} />
</SymbolSvg>
);
}
/** C-R dynamic pneumatic line (AMESim PNL0001). */
export function AmesimPnl0001Symbol() {
return (
<SymbolSvg className="component-symbol-amesim-pnl0001-svg" domain="pneumatic">
<PipeNetworkBody sections={["C", "R"]} />
</SymbolSvg>
);
}
/** R-C-R dynamic pneumatic line (AMESim PNL0002). */
export function AmesimPnl0002Symbol() {
return (
<SymbolSvg className="component-symbol-amesim-pnl0002-svg" domain="pneumatic">
<PipeNetworkBody sections={["R", "C", "R"]} />
</SymbolSvg>
);
}
/** C-R-C dynamic pneumatic line (AMESim PNL0003). */
export function AmesimPnl0003Symbol() {
return (
<SymbolSvg className="component-symbol-amesim-pnl0003-svg" domain="pneumatic">
<PipeNetworkBody sections={["C", "R", "C"]} />
</SymbolSvg>
);
}
function JunctionTerminal({ x, y }: { x: number; y: number }) {
return (
<circle
cx={x}
cy={y}
fill={SYMBOL_FILL}
r="2"
stroke={SYMBOL_STROKE}
strokeWidth="1.3"
/>
);
}
/** Three-port pneumatic junction with one inlet-side and two outlet-side ports. */
export function AmesimPn3Node2Symbol() {
return (
<SymbolSvg className="component-symbol-amesim-pn3node2-svg" domain="pneumatic">
<path
d="M4 24h25M29 24C41 24 42 12 60 12M29 24c12 0 13 12 31 12"
stroke={SYMBOL_STROKE}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={PNEUMATIC_STROKE_WIDTH}
/>
<circle cx="29" cy="24" fill={SYMBOL_ACCENT} r="3" />
<JunctionTerminal x={3} y={24} />
<JunctionTerminal x={61} y={12} />
<JunctionTerminal x={61} y={36} />
</SymbolSvg>
);
}
/** Four-port pneumatic junction with one inlet-side and three outlet-side ports. */
export function AmesimP4Node2Symbol() {
return (
<SymbolSvg className="component-symbol-amesim-p4node2-svg" domain="pneumatic">
<path
d="M4 24h24M28 24C40 24 42 8 60 8M28 24h32M28 24c12 0 14 16 32 16"
stroke={SYMBOL_STROKE}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={PNEUMATIC_STROKE_WIDTH}
/>
<circle cx="28" cy="24" fill={SYMBOL_ACCENT} r="3" />
<JunctionTerminal x={3} y={24} />
<JunctionTerminal x={61} y={8} />
<JunctionTerminal x={61} y={24} />
<JunctionTerminal x={61} y={40} />
</SymbolSvg>
);
}