FIX: Battery.current didn't respect sign of wire current

This commit is contained in:
Patrick Haßel 2025-02-04 10:59:32 +01:00
parent 54b4d4d3e6
commit ab084d867a
7 changed files with 26 additions and 26 deletions

View File

@ -22,9 +22,12 @@ export class Calculation {
readonly junctionsWithoutPivot: Junction[], readonly junctionsWithoutPivot: Junction[],
readonly wires: Wire[]) { readonly wires: Wire[]) {
this.matrixInit(junctionsWithoutPivot.length); this.matrixInit(junctionsWithoutPivot.length);
this.wires.forEach(wire => this.addResistor(wire)); this.wires.forEach(wire => this.addResistor(wire));
this.parts.filter(p => p instanceof Battery).forEach(battery => this.addCurrentSource(battery)); this.parts.filter(p => p instanceof Battery).forEach(battery => this.addCurrentSource(battery));
this.solve(); this.solve();
this.wires.forEach(wire => this.useCurrent(wire)); this.wires.forEach(wire => this.useCurrent(wire));
const minCircuitVoltage = this.potentials.reduce((a, b) => a < b ? a : b, 0); const minCircuitVoltage = this.potentials.reduce((a, b) => a < b ? a : b, 0);
const maxCircuitVoltage = this.potentials.reduce((a, b) => a > b ? a : b, 0); const maxCircuitVoltage = this.potentials.reduce((a, b) => a > b ? a : b, 0);
@ -34,9 +37,11 @@ export class Calculation {
junction.voltage = this.getPotential(junctionsWithoutPivot.indexOf(junction)); junction.voltage = this.getPotential(junctionsWithoutPivot.indexOf(junction));
console.debug(" junction", junction.fullName, junction.voltage, 'V'); console.debug(" junction", junction.fullName, junction.voltage, 'V');
}); });
pivot.minCircuitVoltage = minCircuitVoltage; pivot.minCircuitVoltage = minCircuitVoltage;
pivot.maxCircuitVoltage = maxCircuitVoltage; pivot.maxCircuitVoltage = maxCircuitVoltage;
pivot.voltage = 0; pivot.voltage = 0;
const junctionCountIncludingPivot = junctionsWithoutPivot.length + 1; const junctionCountIncludingPivot = junctionsWithoutPivot.length + 1;
console.debug(` => Circuit #${number} (${parts.length} parts, ${junctionCountIncludingPivot} junctions, ${wires.length} wires)`); console.debug(` => Circuit #${number} (${parts.length} parts, ${junctionCountIncludingPivot} junctions, ${wires.length} wires)`);
} }
@ -91,7 +96,7 @@ export class Calculation {
private addCurrentSource(battery: Battery) { private addCurrentSource(battery: Battery) {
const indexMinus = this.junctionsWithoutPivot.indexOf(battery.minus); const indexMinus = this.junctionsWithoutPivot.indexOf(battery.minus);
const indexPlus = this.junctionsWithoutPivot.indexOf(battery.plus); const indexPlus = this.junctionsWithoutPivot.indexOf(battery.plus);
const current = battery.voltage / battery.resistance; const current = battery.voltage / battery.resistance.resistance;
if (indexMinus >= 0) { if (indexMinus >= 0) {
this.currents[indexMinus] += current; this.currents[indexMinus] += current;
} }

View File

@ -27,7 +27,7 @@ export class Circuit {
Calculation.calculate(this); Calculation.calculate(this);
const changedParts = []; const changedParts = [];
for (const part of this.parts) { for (const part of this.parts) {
if (part.loop()) { if (part.postCalculate()) {
changedParts.push(part); changedParts.push(part);
} }
} }

View File

@ -68,13 +68,6 @@ export class Junction {
this._rect = this.findRect(); this._rect = this.findRect();
} }
sumAllBut(plus: Junction) {
return this.wires
.filter(wire => wire.traverse(this) !== plus)
.map(wire => wire.current)
.reduce((a, b) => a + b, 0);
}
private findRect(): Rect { private findRect(): Rect {
const child = document.getElementById(this.uuid); const child = document.getElementById(this.uuid);
if (!child) { if (!child) {

View File

@ -39,7 +39,7 @@ export abstract class Part {
this.junctions.forEach(junction => junction.updatePosition()); this.junctions.forEach(junction => junction.updatePosition());
} }
loop(): boolean { postCalculate(): boolean {
return false; return false;
}; };

View File

@ -11,28 +11,33 @@ export class Battery extends Part {
readonly plus: Junction = new Junction(this, 85, 50, "+"); readonly plus: Junction = new Junction(this, 85, 50, "+");
readonly resistance: Wire;
current: number = 0;
constructor( constructor(
circuit: Circuit, circuit: Circuit,
rasterX: number, rasterX: number,
rasterY: number, rasterY: number,
name: string, name: string,
public voltage: number, public voltage: number,
public resistance: number, resistance: number,
) { ) {
super(circuit, PartType.Battery, name, rasterX, rasterY); super(circuit, PartType.Battery, name, rasterX, rasterY);
new Wire(this.minus, this.plus, resistance, "Innenwiderstand"); this.resistance = new Wire(this.minus, this.plus, resistance, "Innenwiderstand");
} }
override get junctions(): Junction[] { override get junctions(): Junction[] {
return [this.minus, this.plus]; return [this.minus, this.plus];
} }
get voltageStr(): string { override postCalculate(): boolean {
return siPrefix(Math.abs(this.voltage), 'V', 2); this.current = this.minus.wires.map(wire => wire.currentFrom(this.minus)).reduce((a, b) => a + b, -this.resistance.current)
return false;
} }
get current(): number { get voltageStr(): string {
return this.minus.sumAllBut(this.plus); return siPrefix(Math.abs(this.voltage), 'V', 2);
} }
get currentStr(): string { get currentStr(): string {

View File

@ -69,7 +69,7 @@ export class Relay extends Part {
return siPrefix(Math.abs(this.current) || 0, 'A', 2); return siPrefix(Math.abs(this.current) || 0, 'A', 2);
} }
override loop(): boolean { override postCalculate(): boolean {
const shouldBeActive = this.isCoilActive; const shouldBeActive = this.isCoilActive;
const isActive = this.contact.end === this.active; const isActive = this.contact.end === this.active;
if (isActive != shouldBeActive) { if (isActive != shouldBeActive) {

View File

@ -1,6 +1,5 @@
import {Junction} from "../junction/Junction"; import {Junction} from "../junction/Junction";
import {RESISTANCE_MIN} from '../circuit/Calculation'; import {RESISTANCE_MIN} from '../circuit/Calculation';
import {fadeColor} from '../colorHelpers';
export const ANIMATION_ELECTRON_STEPS = 20; export const ANIMATION_ELECTRON_STEPS = 20;
@ -51,15 +50,13 @@ export class Wire {
this.current = 0; this.current = 0;
} }
voltageColor(): string { currentFrom(junction: Junction) {
if (this.start.voltage === null || this.end.voltage === null || this.start.minCircuitVoltage === null || this.start.maxCircuitVoltage === null) { if (this.start === junction) {
return 'lightgray'; return this.current;
} else if (this.end === junction) {
return -this.current;
} }
const ratio = ((this.end.voltage + this.start.voltage) / 2 - this.start.minCircuitVoltage) / (this.start.maxCircuitVoltage - this.start.minCircuitVoltage); throw new Error(`Wire is not connected to given Junction: wire=${this}, junction=${junction}`);
if (ratio < 0.5) {
return fadeColor(ratio * 2, '#008cff', 'magenta');
}
return fadeColor((ratio - 0.5) * 2, 'magenta', 'red');
} }
} }