Admittance matrix (Knotenpotentialverfahren)

This commit is contained in:
Patrick Haßel 2024-05-22 11:46:52 +02:00
parent e91d1eadde
commit dfea68adaf
29 changed files with 575 additions and 326 deletions

View File

@ -35,6 +35,11 @@
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>2.17.0</version> <version>2.17.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -6,9 +6,7 @@ import static java.lang.Math.round;
public class CONFIG { public class CONFIG {
public static final double BULB_VOLTAGE_MIN = 0.5; public static final double VOLTAGE_HIGH_MIN = 0.1;
public static final double VOLTAGE = 3.0;
public static final int RASTER = 200; public static final int RASTER = 200;

View File

@ -0,0 +1,216 @@
package de.ph87.electro.circuit;
import de.ph87.electro.circuit.part.InnerConnection;
import de.ph87.electro.circuit.part.Junction;
import de.ph87.electro.circuit.part.Part;
import de.ph87.electro.circuit.part.parts.PartBattery;
import de.ph87.electro.circuit.part.parts.PartLight;
import lombok.Getter;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.math3.linear.*;
import java.util.Collections;
import java.util.List;
import static java.lang.Math.max;
@Slf4j
@Getter
public class Calculation {
private static final double NO_RESISTANCE = 1e-12;
private static final double FULL_ADMITTANCE = 1 / NO_RESISTANCE;
private final List<Junction> junctions;
private final RealMatrix matrix;
private final RealVector currents;
private RealVector potentials = null;
public Calculation(final int numNodes) {
junctions = Collections.emptyList();
matrix = new Array2DRowRealMatrix(numNodes, numNodes);
currents = new ArrayRealVector(numNodes);
}
public Calculation(final Circuit circuit) {
final PartBattery pivot = circuit.streamParts().flatMap(PartBattery::filterCast).findFirst().orElseThrow(RuntimeException::new);
junctions = circuit.streamJunctions().filter(junction -> junction != pivot.getMinus()).toList(); // pivot.minus is GND and cannot be part of the matrix (linear dependency)
matrix = new Array2DRowRealMatrix(junctions.size(), junctions.size());
currents = new ArrayRealVector(junctions.size());
fromSchematic(circuit);
solve();
toSchematic(circuit);
}
private void fromSchematic(final Circuit circuit) {
circuit.streamWires().forEach(
wire -> addResistor(wire.getA(), wire.getB(), NO_RESISTANCE)
);
circuit.streamParts().forEach(part -> {
for (final InnerConnection innerConnection : part.getInnerConnections()) {
addResistor(innerConnection.a, innerConnection.b, NO_RESISTANCE);
}
if (part instanceof final PartBattery battery) {
addBattery(battery);
} else if (part instanceof final PartLight light) {
addResistor(light.getA(), light.getB(), light.getResistance());
}
});
}
private void toSchematic(final Circuit circuit) {
circuit.streamJunctions().forEach(junction -> junction.setVoltage(getPotential(junction)));
circuit.streamWires().forEach(wire -> wire.setCurrent(getCurrent(wire)));
circuit.streamParts().forEach(Part::postCalculate);
}
private double getPotential(final @NonNull Junction junction) {
final int index = getJunctionIndex(junction);
if (index < 0) {
return 0; // per definition
}
if (potentials == null) {
return Double.NaN;
}
return potentials.getEntry(index);
}
private double getCurrent(final Wire wire) {
final int indexA = getJunctionIndex(wire.getA());
final int indexB = getJunctionIndex(wire.getB());
final double conductance = indexA >= 0 && indexB >= 0 ? matrix.getEntry(indexA, indexB) : FULL_ADMITTANCE;
final double potentialDifference = getPotential(wire.getB()) - getPotential(wire.getA());
return conductance * potentialDifference;
}
private int getJunctionIndex(@NonNull final Junction junction) {
for (int i = 0; i < junctions.size(); i++) {
if (junctions.get(i) == junction) {
return i;
}
}
return -1;
}
public void addResistor(final Junction a, final Junction b, final double resistance) {
final int indexA = getJunctionIndex(a);
final int indexB = getJunctionIndex(b);
addResistor(indexA, indexB, resistance);
}
public void addResistor(final int index0, final int index1, double resistance) {
double conductance = 1.0 / resistance;
if (index0 >= 0) {
matrix.setEntry(index0, index0, matrix.getEntry(index0, index0) + conductance);
}
if (index1 >= 0) {
matrix.setEntry(index1, index1, matrix.getEntry(index1, index1) + conductance);
}
if (index0 >= 0 && index1 >= 0) {
matrix.setEntry(index0, index1, matrix.getEntry(index0, index1) - conductance);
matrix.setEntry(index1, index0, matrix.getEntry(index1, index0) - conductance);
}
potentials = null;
}
public void addBattery(final PartBattery battery) {
final double current = battery.getVoltage() / battery.getResistance();
final int indexMinus = getJunctionIndex(battery.getMinus());
final int indexPlus = getJunctionIndex(battery.getPlus());
addCurrentSource(indexMinus, indexPlus, current, battery.getResistance());
}
public void addCurrentSource(final int index0, final int index1, final double current, final double resistance) {
if (index0 >= 0) {
currents.setEntry(index0, currents.getEntry(index0) - current);
}
if (index1 >= 0) {
currents.setEntry(index1, currents.getEntry(index1) + current);
}
addResistor(index0, index1, resistance);
potentials = null;
}
public void solve() {
final DecompositionSolver solver = new LUDecomposition(matrix).getSolver();
try {
potentials = solver.solve(currents);
} catch (SingularMatrixException e) {
potentials = null;
log.error("Schaltung fehlerhaft: {}", e.getMessage());
}
}
@Override
public String toString() {
final Format matrixFormat = new Format(matrix);
final Format currentsFormat = new Format(currents);
final Format potentialsFormat = new Format(potentials);
final StringBuilder builder = new StringBuilder();
for (int row = 0; row < matrix.getRowDimension(); row++) {
builder.append("[");
String prefix = "";
for (int c = 0; c < matrix.getColumnDimension(); c++) {
builder.append(prefix);
builder.append(matrixFormat.format(matrix.getEntry(row, c)));
prefix = ", ";
}
final String potentialString = potentialsFormat.format(potentials.getEntry(row));
final String currentString = currentsFormat.format(currents.getEntry(row));
builder.append("] x [%s V] = [%s A]\n".formatted(potentialString, currentString));
}
return builder.toString();
}
@Getter
private static final class Format {
private int integer;
private int decimal;
private final String format;
public Format(final RealMatrix matrix) {
for (int r = 0; r < matrix.getRowDimension(); r++) {
for (int c = 0; c < matrix.getColumnDimension(); c++) {
append(matrix.getEntry(r, c));
}
}
format = calculateFormat();
}
public Format(final RealVector vector) {
for (int r = 0; r < vector.getDimension(); r++) {
append(vector.getEntry(r));
}
format = calculateFormat();
}
private void append(final double value) {
final String string = "%+f".formatted(value);
final String[] parts = string.split("[.,]");
integer = max(integer, parts[0].length());
if (parts.length > 1) {
decimal = max(decimal, parts[1].length());
}
}
private String calculateFormat() {
return "%%+%d.%df".formatted(integer + decimal + (decimal > 0 ? 1 : 0), decimal);
}
public String format(final double value) {
return format.formatted(value);
}
}
}

View File

@ -4,7 +4,6 @@ import de.ph87.electro.circuit.part.Junction;
import de.ph87.electro.circuit.part.Part; import de.ph87.electro.circuit.part.Part;
import de.ph87.electro.circuit.part.PartDto; import de.ph87.electro.circuit.part.PartDto;
import de.ph87.electro.circuit.part.Position; import de.ph87.electro.circuit.part.Position;
import de.ph87.electro.circuit.part.parts.PartBattery;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.NonNull; import lombok.NonNull;
@ -18,6 +17,8 @@ public class Circuit {
private final List<Part> parts = new ArrayList<>(); private final List<Part> parts = new ArrayList<>();
private final List<Junction> junctions = new ArrayList<>();
private final List<Wire> wires = new ArrayList<>(); private final List<Wire> wires = new ArrayList<>();
public Circuit(final CircuitDto dto) { public Circuit(final CircuitDto dto) {
@ -41,25 +42,17 @@ public class Circuit {
} }
public void evaluateAndRender() { public void evaluateAndRender() {
parts.forEach(Part::reset); new Calculation(this);
streamBatteries().forEach(PartBattery::startPropagation);
parts.forEach(Part::render); parts.forEach(Part::render);
} }
private Stream<PartBattery> streamBatteries() {
return parts.stream().filter(part -> part instanceof PartBattery).map(part -> (PartBattery) part);
}
public Stream<Wire> streamWires() {
return wires.stream();
}
public <T extends Part> T addPart(final T part) { public <T extends Part> T addPart(final T part) {
if (parts.contains(part)) { if (parts.contains(part)) {
throw new RuntimeException(); throw new RuntimeException();
} }
if (isFree(part.getPosition())) { if (isFree(part.getPosition())) {
parts.add(part); parts.add(part);
junctions.addAll(part.getJunctions());
part.render(); part.render();
} }
return part; return part;
@ -82,6 +75,14 @@ public class Circuit {
return parts.stream(); return parts.stream();
} }
public Stream<Junction> streamJunctions() {
return junctions.stream();
}
public Stream<Wire> streamWires() {
return wires.stream();
}
public int getPartCount() { public int getPartCount() {
return parts.size(); return parts.size();
} }

View File

@ -1,6 +1,8 @@
package de.ph87.electro.circuit; package de.ph87.electro.circuit;
import de.ph87.electro.circuit.part.Position; import de.ph87.electro.circuit.part.Position;
import de.ph87.electro.circuit.part.parts.PartBattery;
import de.ph87.electro.circuit.part.parts.PartLight;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
@ -15,6 +17,19 @@ public class CircuitPanel extends JPanel {
public CircuitPanel() { public CircuitPanel() {
new CircuitPanelDropTarget(this, circuit); new CircuitPanelDropTarget(this, circuit);
final PartBattery battery = circuit.addPart(new PartBattery(Position.ofRaster(1, 0)));
final PartLight light0 = circuit.addPart(new PartLight(Position.ofRaster(0, 2)));
light0.clockwise();
final PartLight light1 = circuit.addPart(new PartLight(Position.ofRaster(1, 2)));
light1.clockwise();
light1.clockwise();
light1.clockwise();
circuit.connect(battery.getMinus(), light0.getA());
circuit.connect(light0.getB(), light1.getA());
circuit.connect(light1.getB(), battery.getPlus());
} }
@Override @Override
@ -51,13 +66,7 @@ public class CircuitPanel extends JPanel {
} }
private void drawWires(final Graphics2D g) { private void drawWires(final Graphics2D g) {
circuit.streamWires().forEach(wire -> { circuit.streamWires().forEach(wire -> wire.draw(g));
final Position a = wire.getA().getPosition();
final Position b = wire.getB().getPosition();
g.setColor(wire.getA().getColor());
g.setStroke(WIRE_STROKE);
g.drawLine(a.absolute.x, a.absolute.y, b.absolute.x, b.absolute.y);
});
} }
} }

View File

@ -2,18 +2,33 @@ package de.ph87.electro.circuit;
import de.ph87.electro.circuit.part.Junction; import de.ph87.electro.circuit.part.Junction;
import de.ph87.electro.circuit.part.Position; import de.ph87.electro.circuit.part.Position;
import lombok.Data; import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import lombok.Setter;
import lombok.ToString;
@Data import java.awt.*;
import java.awt.geom.Rectangle2D;
import static de.ph87.electro.CONFIG.LABEL_FONT;
import static de.ph87.electro.CONFIG.WIRE_STROKE;
import static java.lang.Math.abs;
import static java.lang.Math.round;
@ToString
public class Wire { public class Wire {
@Getter
@NonNull @NonNull
private final Junction a; private final Junction a;
@Getter
@NonNull @NonNull
private final Junction b; private final Junction b;
@Setter
private double current = Double.NaN;
public Wire(@NonNull final Junction a, @NonNull final Junction b) { public Wire(@NonNull final Junction a, @NonNull final Junction b) {
this.a = a; this.a = a;
this.b = b; this.b = b;
@ -34,4 +49,34 @@ public class Wire {
throw new RuntimeException(); throw new RuntimeException();
} }
public double getCurrent(final Junction junction) {
return junction == a ? current : -current;
}
public void draw(final Graphics2D g) {
g.setColor(a.getColor());
g.setStroke(WIRE_STROKE);
g.drawLine(a.getPosition().absolute.x, a.getPosition().absolute.y, b.getPosition().absolute.x, b.getPosition().absolute.y);
drawValues(g, "%.2f A".formatted(abs(current)), -0.5);
drawValues(g, "%.2f V".formatted(a.getVoltage()), +0.5);
}
private void drawValues(final Graphics2D g, final String string, final double offset) {
g.setFont(LABEL_FONT);
final Rectangle2D bounds = g.getFontMetrics().getStringBounds(string, g);
final int mx = (a.getPosition().absolute.x + b.getPosition().absolute.x) / 2;
final int my = (a.getPosition().absolute.y + b.getPosition().absolute.y) / 2;
final int bx = (int) round((mx - bounds.getWidth() / 2)) - 2;
final int by = (int) round((my - bounds.getHeight() / 2) + offset * bounds.getHeight()) - 2;
g.setColor(new Color(255, 255, 255, 200));
g.fillRect(bx, by, (int) round(bounds.getWidth()) + 4, (int) round(bounds.getHeight()) + 4);
final int sx = (int) round((mx - bounds.getWidth() / 2));
final int sy = (int) round(my + bounds.getHeight() / 3 + offset * bounds.getHeight());
g.setColor(a.getColor());
g.drawString(string, sx, sy);
}
} }

View File

@ -0,0 +1,14 @@
package de.ph87.electro.circuit.part;
public class InnerConnection {
public final Junction a;
public final Junction b;
public InnerConnection(final Junction a, final Junction b) {
this.a = a;
this.b = b;
}
}

View File

@ -1,9 +1,7 @@
package de.ph87.electro.circuit.part; package de.ph87.electro.circuit.part;
import de.ph87.electro.circuit.ShortCircuit;
import de.ph87.electro.circuit.Wire; import de.ph87.electro.circuit.Wire;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import java.awt.*; import java.awt.*;
@ -32,7 +30,6 @@ public class Junction {
private final Set<Wire> wires = new HashSet<>(); private final Set<Wire> wires = new HashSet<>();
@Setter
@ToString.Include @ToString.Include
private double voltage = Double.NaN; private double voltage = Double.NaN;
@ -60,31 +57,9 @@ public class Junction {
updatePosition(); updatePosition();
} }
public void reset() { public void setVoltage(final double voltage) {
voltage = Double.NaN; this.voltage = voltage;
color = VOLTAGE_UNKNOWN_COLOR; this.color = Double.isNaN(voltage) ? VOLTAGE_UNKNOWN_COLOR : ((voltage >= VOLTAGE_HIGH_MIN) ? VOLTAGE_HIGH_COLOR : VOLTAGE_LOW_COLOR);
}
public void propagate(final double newVoltage) throws ShortCircuit {
if (voltage == newVoltage) {
return;
}
if (Double.isNaN(voltage)) {
voltage = newVoltage;
if (Double.isNaN(voltage)) {
color = Color.GRAY;
} else if (voltage > 0) {
color = VOLTAGE_HIGH_COLOR;
} else {
color = VOLTAGE_LOW_COLOR;
}
owner.propagate(this);
for (Wire wire : wires) {
wire.getOpposite(this).propagate(newVoltage);
}
return;
}
throw new ShortCircuit();
} }
public void render(final Render g) { public void render(final Render g) {

View File

@ -1,16 +1,13 @@
package de.ph87.electro.circuit.part; package de.ph87.electro.circuit.part;
import de.ph87.electro.circuit.ShortCircuit;
import de.ph87.electro.circuit.part.parts.*; import de.ph87.electro.circuit.part.parts.*;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import java.awt.*; import java.awt.*;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.*;
import java.util.UUID;
import static de.ph87.electro.CONFIG.PART_BACKGROUND; import static de.ph87.electro.CONFIG.PART_BACKGROUND;
import static de.ph87.electro.CONFIG.RASTER; import static de.ph87.electro.CONFIG.RASTER;
@ -29,17 +26,16 @@ public abstract class Part {
private Position position; private Position position;
private Orientation orientation; private Orientation orientation = Orientation.R0;
private final List<Junction> junctions = new ArrayList<>(); private final List<Junction> junctions = new ArrayList<>();
protected final Render render = new Render(); protected final Render render = new Render();
protected Part(final String name, final Position position, final Orientation orientation) { protected Part(final String name, final Position position) {
this.uuid = UUID.randomUUID().toString(); this.uuid = UUID.randomUUID().toString();
this.name = name; this.name = name;
setPosition(position); setPosition(position);
this.orientation = orientation;
} }
protected Part(final PartDto dto) { protected Part(final PartDto dto) {
@ -73,10 +69,6 @@ public abstract class Part {
render(); render();
} }
public void reset() {
junctions.forEach(Junction::reset);
}
public void render() { public void render() {
render.rect(ZERO, RASTER, RASTER, null, null, PART_BACKGROUND); render.rect(ZERO, RASTER, RASTER, null, null, PART_BACKGROUND);
@ -106,7 +98,7 @@ public abstract class Part {
// may be overwritten // may be overwritten
} }
public void propagate(final Junction source) throws ShortCircuit { public void postCalculate() {
// may be overwritten // may be overwritten
} }
@ -132,4 +124,8 @@ public abstract class Part {
}; };
} }
public List<InnerConnection> getInnerConnections() {
return Collections.emptyList();
}
} }

View File

@ -2,8 +2,8 @@ package de.ph87.electro.circuit.part;
public abstract class PartOther extends Part { public abstract class PartOther extends Part {
protected PartOther(final String name, final Position position, final Orientation orientation) { protected PartOther(final String name, final Position position) {
super(name, position, orientation); super(name, position);
} }
protected PartOther(final PartDto dto) { protected PartOther(final PartDto dto) {

View File

@ -28,6 +28,10 @@ public final class Position {
this.inside = new Point(x % RASTER, y % RASTER); this.inside = new Point(x % RASTER, y % RASTER);
} }
public static Position ofRaster(final int x, final int y) {
return new Position(x * RASTER, y * RASTER);
}
@Override @Override
public int hashCode() { public int hashCode() {
return absolute.hashCode(); return absolute.hashCode();

View File

@ -61,11 +61,13 @@ public class Render {
} }
} }
public void textCenter(final Font font, final String string, final int y, final Color color) { public void textCenter(final Font font, final String string, final int innerX, final int innerY, final Color color) {
g.setFont(font); g.setFont(font);
g.setColor(color); g.setColor(color);
final Rectangle2D bounds = g.getFontMetrics().getStringBounds(string, g); final Rectangle2D bounds = g.getFontMetrics().getStringBounds(string, g);
g.drawString(string, (int) round(RASTER - bounds.getWidth()) / 2, y + g.getFont().getSize()); final int x = innerX - (int) round(bounds.getWidth()) / 2;
final int y = innerY + (int) round(bounds.getHeight()) / 2;
g.drawString(string, x, y);
} }
public void clockwise(final Orientation orientation) { public void clockwise(final Orientation orientation) {

View File

@ -1,6 +1,5 @@
package de.ph87.electro.circuit.part.parts; package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.ShortCircuit;
import de.ph87.electro.circuit.part.Junction; import de.ph87.electro.circuit.part.Junction;
import de.ph87.electro.circuit.part.Orientation; import de.ph87.electro.circuit.part.Orientation;
import de.ph87.electro.circuit.part.Part; import de.ph87.electro.circuit.part.Part;
@ -10,11 +9,12 @@ import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import java.awt.*; import java.awt.*;
import java.util.stream.Stream;
import static de.ph87.electro.CONFIG.*; import static de.ph87.electro.CONFIG.*;
@Getter @Getter
@ToString(callSuper = true) @ToString(callSuper = true, onlyExplicitlyIncluded = true)
public class PartBattery extends Part { public class PartBattery extends Part {
private static final double MINUS_W = 0.1 * RASTER; private static final double MINUS_W = 0.1 * RASTER;
@ -32,24 +32,21 @@ public class PartBattery extends Part {
private final Junction plus; private final Junction plus;
@Setter @Setter
private double voltage; @ToString.Include
private double voltage = 3;
private ShortCircuit shortCircuit = null; @Setter
@ToString.Include
private double resistance = 0.05;
public PartBattery() { public PartBattery() {
this(Position.ZERO); this(Position.ZERO);
} }
public PartBattery(final Position position) { public PartBattery(final Position position) {
this("Batterie", position, Orientation.R0, VOLTAGE); super("Batterie", position);
} minus = newJunction(this, "PLUS", P10, P50);
plus = newJunction(this, "MINUS", P90, P50);
public PartBattery(final String name, final Position position, final Orientation orientation, final double initialVoltage) {
super(name, position, orientation);
minus = newJunction(this, "-", P10, P50);
plus = newJunction(this, "+", P90, P50);
voltage = initialVoltage;
startPropagation();
} }
public PartBattery(final PartBatteryDto dto) { public PartBattery(final PartBatteryDto dto) {
@ -57,17 +54,6 @@ public class PartBattery extends Part {
minus = newJunction(this, dto.getMinus(), P10, P50); minus = newJunction(this, dto.getMinus(), P10, P50);
plus = newJunction(this, dto.getPlus(), P90, P50); plus = newJunction(this, dto.getPlus(), P90, P50);
voltage = dto.getVoltage(); voltage = dto.getVoltage();
startPropagation();
}
public void startPropagation() {
try {
shortCircuit = null;
minus.propagate(0);
plus.propagate(voltage);
} catch (ShortCircuit e) {
shortCircuit = e;
}
} }
@Override @Override
@ -81,20 +67,22 @@ public class PartBattery extends Part {
@Override @Override
protected void _labels() { protected void _labels() {
final int x = RASTER / 2;
final int y0; final int y0;
final int y1;
if (getOrientation() == Orientation.R180) { if (getOrientation() == Orientation.R180) {
y0 = P95 - LABEL_FONT.getSize(); y0 = P95 - LABEL_FONT.getSize();
y1 = P05;
} else { } else {
render.clockwise(getOrientation()); render.clockwise(getOrientation());
y0 = P05; y0 = P05;
y1 = P95 - LABEL_FONT.getSize();
} }
render.textCenter(LABEL_FONT, "%.1fV".formatted(voltage), y0, Color.BLACK); render.textCenter(LABEL_FONT, "%.1fV".formatted(voltage), x, y0, Color.BLACK);
if (shortCircuit != null) { }
render.textCenter(LABEL_FONT, "KURZSCHLUSS", y1, Color.RED);
public static Stream<PartBattery> filterCast(final Part part) {
if (part instanceof final PartBattery battery) {
return Stream.of(battery);
} }
return Stream.empty();
} }
} }

View File

@ -1,13 +1,13 @@
package de.ph87.electro.circuit.part.parts; package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.part.Junction; import de.ph87.electro.circuit.part.Junction;
import de.ph87.electro.circuit.part.Orientation;
import de.ph87.electro.circuit.part.PartOther; import de.ph87.electro.circuit.part.PartOther;
import de.ph87.electro.circuit.part.Position; import de.ph87.electro.circuit.part.Position;
import lombok.Getter; import lombok.Getter;
import lombok.ToString; import lombok.ToString;
import static de.ph87.electro.CONFIG.*; import static de.ph87.electro.CONFIG.P10;
import static de.ph87.electro.CONFIG.P90;
@Getter @Getter
@ToString(callSuper = true) @ToString(callSuper = true)
@ -22,13 +22,9 @@ public class PartJunctionCorner extends PartOther {
} }
public PartJunctionCorner(final Position position) { public PartJunctionCorner(final Position position) {
this("", position, Orientation.R0); super("", position);
} j0 = newJunction(this, "J0", P10, P10);
j1 = newJunction(this, "J1", P90, P90);
public PartJunctionCorner(final String name, final Position position, final Orientation orientation) {
super(name, position, orientation);
j0 = newJunction(this, "", P10, P10);
j1 = newJunction(this, "", P90, P90);
} }
public PartJunctionCorner(final PartJunctionCornerDto dto) { public PartJunctionCorner(final PartJunctionCornerDto dto) {

View File

@ -1,14 +1,13 @@
package de.ph87.electro.circuit.part.parts; package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.part.Junction; import de.ph87.electro.circuit.part.Junction;
import de.ph87.electro.circuit.part.Orientation;
import de.ph87.electro.circuit.part.PartOther; import de.ph87.electro.circuit.part.PartOther;
import de.ph87.electro.circuit.part.Position; import de.ph87.electro.circuit.part.Position;
import lombok.Getter; import lombok.Getter;
import lombok.ToString; import lombok.ToString;
import static de.ph87.electro.CONFIG.P50;
import static de.ph87.electro.CONFIG.P10; import static de.ph87.electro.CONFIG.P10;
import static de.ph87.electro.CONFIG.P50;
@Getter @Getter
@ToString(callSuper = true) @ToString(callSuper = true)
@ -23,13 +22,9 @@ public class PartJunctionEdge extends PartOther {
} }
public PartJunctionEdge(final Position position) { public PartJunctionEdge(final Position position) {
this("", position, Orientation.R0); super("", position);
} j0 = newJunction(this, "J0", P10, P50);
j1 = newJunction(this, "J1", P50, P10);
public PartJunctionEdge(final String name, final Position position, final Orientation orientation) {
super(name, position, orientation);
j0 = newJunction(this, "", P10, P50);
j1 = newJunction(this, "", P50, P10);
} }
public PartJunctionEdge(final PartJunctionEdgeDto dto) { public PartJunctionEdge(final PartJunctionEdgeDto dto) {

View File

@ -1,7 +1,6 @@
package de.ph87.electro.circuit.part.parts; package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.part.Junction; import de.ph87.electro.circuit.part.Junction;
import de.ph87.electro.circuit.part.Orientation;
import de.ph87.electro.circuit.part.PartOther; import de.ph87.electro.circuit.part.PartOther;
import de.ph87.electro.circuit.part.Position; import de.ph87.electro.circuit.part.Position;
import lombok.Getter; import lombok.Getter;
@ -20,12 +19,8 @@ public class PartJunctionMiddle extends PartOther {
} }
public PartJunctionMiddle(final Position position) { public PartJunctionMiddle(final Position position) {
this("", position, Orientation.R0); super("", position);
} junction = newJunction(this, "J", P50, P50);
public PartJunctionMiddle(final String name, final Position position, final Orientation orientation) {
super(name, position, orientation);
junction = newJunction(this, "", P50, P50);
} }
public PartJunctionMiddle(final PartJunctionMiddleDto dto) { public PartJunctionMiddle(final PartJunctionMiddleDto dto) {

View File

@ -33,17 +33,19 @@ public class PartLight extends PartOther {
private static final Color BULB_OFF_COLOR = Color.DARK_GRAY; private static final Color BULB_OFF_COLOR = Color.DARK_GRAY;
private final Junction pin0; private final Junction a;
private final Junction pin1; private final Junction b;
private final double minVoltage; private double resistance = 15;
private final double maxVoltage; private double minVoltage = 1;
private double maxVoltage = 3;
private boolean defect = false; private boolean defect = false;
private double voltage = 0; private double potentialDifference = Double.NaN;
private Color color = BULB_OFF_COLOR; private Color color = BULB_OFF_COLOR;
@ -52,21 +54,16 @@ public class PartLight extends PartOther {
} }
public PartLight(final Position position) { public PartLight(final Position position) {
this("Licht", position, Orientation.R0, BULB_VOLTAGE_MIN, VOLTAGE); super("Licht", position);
} a = newJunction(this, "A", P10, P50);
b = newJunction(this, "B", P90, P50);
public PartLight(final String name, final Position position, final Orientation orientation, final double minVoltage, final double maxVoltage) {
super(name, position, orientation);
this.minVoltage = minVoltage;
this.maxVoltage = maxVoltage;
pin0 = newJunction(this, "", P10, P50);
pin1 = newJunction(this, "", P90, P50);
} }
public PartLight(final PartLightDto dto) { public PartLight(final PartLightDto dto) {
super(dto); super(dto);
pin0 = newJunction(this, dto.getMinus(), P10, P50); a = newJunction(this, dto.getB(), P10, P50);
pin1 = newJunction(this, dto.getPlus(), P90, P50); b = newJunction(this, dto.getA(), P90, P50);
resistance = dto.getResistance();
minVoltage = dto.getMinVoltage(); minVoltage = dto.getMinVoltage();
maxVoltage = dto.getMaxVoltage(); maxVoltage = dto.getMaxVoltage();
defect = dto.isDefect(); defect = dto.isDefect();
@ -78,26 +75,20 @@ public class PartLight extends PartOther {
} }
@Override @Override
public void propagate(final Junction source) { public void postCalculate() {
voltage = abs(pin1.getVoltage() - pin0.getVoltage()); potentialDifference = abs(b.getVoltage() - a.getVoltage());
if (voltage > maxVoltage) { defect |= potentialDifference > maxVoltage;
defect = true; if (defect || potentialDifference < minVoltage) {
} color = BULB_OFF_COLOR;
if (defect) {
color = COLOR_DEFECT;
} else { } else {
final int v = (int) round(voltage / maxVoltage * 255); final int c = (int) round(255 * potentialDifference / maxVoltage);
if (v < 10) { color = new Color(c, c, 0);
color = BULB_OFF_COLOR;
} else {
color = new Color(v, v, 0);
}
} }
} }
@Override @Override
protected void _render() { protected void _render() {
render.line(pin0, pin1, Color.BLACK, SYMBOL_STROKE); render.line(a, b, Color.BLACK, SYMBOL_STROKE);
render.circle(new Position(P50, P50), BULB_RADIUS, Color.BLACK, SYMBOL_STROKE, color); render.circle(new Position(P50, P50), BULB_RADIUS, Color.BLACK, SYMBOL_STROKE, color);
final double diag = 0.33 * RASTER; final double diag = 0.33 * RASTER;
@ -107,6 +98,7 @@ public class PartLight extends PartOther {
@Override @Override
protected void _labels() { protected void _labels() {
final int x = RASTER / 2;
final int y0; final int y0;
final int y1; final int y1;
if (getOrientation() == Orientation.R180) { if (getOrientation() == Orientation.R180) {
@ -117,9 +109,9 @@ public class PartLight extends PartOther {
y0 = P05; y0 = P05;
y1 = P95 - LABEL_FONT.getSize(); y1 = P95 - LABEL_FONT.getSize();
} }
render.textCenter(LABEL_FONT, "%.1fV (max)".formatted(maxVoltage), y0, Color.BLACK); render.textCenter(LABEL_FONT, "%.1fV (max)".formatted(maxVoltage), x, y0, Color.BLACK);
if (defect) { if (defect) {
render.textCenter(LABEL_FONT, "DEFEKT", y1, Color.RED); render.textCenter(LABEL_FONT, "DEFEKT", x, y1, Color.RED);
} }
} }

View File

@ -11,9 +11,11 @@ import lombok.ToString;
@NoArgsConstructor @NoArgsConstructor
public class PartLightDto extends PartDto { public class PartLightDto extends PartDto {
private JunctionDto plus; private JunctionDto a;
private JunctionDto minus; private JunctionDto b;
private double resistance;
private double minVoltage; private double minVoltage;
@ -23,9 +25,10 @@ public class PartLightDto extends PartDto {
public PartLightDto(final PartLight partLight) { public PartLightDto(final PartLight partLight) {
super(partLight); super(partLight);
this.plus = new JunctionDto(partLight.getPin1()); this.a = new JunctionDto(partLight.getB());
this.minus = new JunctionDto(partLight.getPin0()); this.b = new JunctionDto(partLight.getA());
this.defect = partLight.isDefect(); this.defect = partLight.isDefect();
this.resistance = partLight.getResistance();
this.minVoltage = partLight.getMinVoltage(); this.minVoltage = partLight.getMinVoltage();
this.maxVoltage = partLight.getMaxVoltage(); this.maxVoltage = partLight.getMaxVoltage();
} }

View File

@ -1,8 +1,7 @@
package de.ph87.electro.circuit.part.parts; package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.ShortCircuit; import de.ph87.electro.circuit.part.InnerConnection;
import de.ph87.electro.circuit.part.Junction; import de.ph87.electro.circuit.part.Junction;
import de.ph87.electro.circuit.part.Orientation;
import de.ph87.electro.circuit.part.PartOther; import de.ph87.electro.circuit.part.PartOther;
import de.ph87.electro.circuit.part.Position; import de.ph87.electro.circuit.part.Position;
import lombok.Getter; import lombok.Getter;
@ -10,6 +9,7 @@ import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import java.awt.*; import java.awt.*;
import java.util.List;
import static de.ph87.electro.CONFIG.*; import static de.ph87.electro.CONFIG.*;
@ -22,21 +22,16 @@ public class PartSwitch1x1 extends PartOther {
private final Junction output; private final Junction output;
@Setter @Setter
private boolean state; private boolean state = false;
public PartSwitch1x1() { public PartSwitch1x1() {
this(Position.ZERO); this(Position.ZERO);
} }
public PartSwitch1x1(final Position position) { public PartSwitch1x1(final Position position) {
this("Ausschalter", position, Orientation.R0, false); super("Ausschalter", position);
} common = newJunction(this, "C", P10, P50);
output = newJunction(this, "O", P90, P50);
public PartSwitch1x1(final String name, final Position position, final Orientation orientation, final boolean state) {
super(name, position, orientation);
common = newJunction(this, "", P10, P50);
output = newJunction(this, "", P90, P50);
this.state = state;
} }
public PartSwitch1x1(final PartSwitch1x1Dto dto) { public PartSwitch1x1(final PartSwitch1x1Dto dto) {
@ -51,19 +46,6 @@ public class PartSwitch1x1 extends PartOther {
state = !state; state = !state;
} }
@Override
public void propagate(final Junction source) throws ShortCircuit {
if (source == common) {
if (state) {
output.propagate(source.getVoltage());
}
} else if (source == output) {
if (state) {
common.propagate(source.getVoltage());
}
}
}
@Override @Override
protected void _render() { protected void _render() {
if (!state) { if (!state) {
@ -74,4 +56,12 @@ public class PartSwitch1x1 extends PartOther {
} }
} }
@Override
public List<InnerConnection> getInnerConnections() {
if (state) {
return List.of(new InnerConnection(common, output));
}
return super.getInnerConnections();
}
} }

View File

@ -1,14 +1,15 @@
package de.ph87.electro.circuit.part.parts; package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.ShortCircuit; import de.ph87.electro.circuit.part.InnerConnection;
import de.ph87.electro.circuit.part.Junction; import de.ph87.electro.circuit.part.Junction;
import de.ph87.electro.circuit.part.Orientation;
import de.ph87.electro.circuit.part.PartOther; import de.ph87.electro.circuit.part.PartOther;
import de.ph87.electro.circuit.part.Position; import de.ph87.electro.circuit.part.Position;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import java.util.List;
import static de.ph87.electro.CONFIG.*; import static de.ph87.electro.CONFIG.*;
@Getter @Getter
@ -22,22 +23,17 @@ public class PartSwitch1x2 extends PartOther {
private final Junction output1; private final Junction output1;
@Setter @Setter
private boolean state; private boolean state = false;
public PartSwitch1x2() { public PartSwitch1x2() {
this(Position.ZERO); this(Position.ZERO);
} }
public PartSwitch1x2(final Position position) { public PartSwitch1x2(final Position position) {
this("Wechselschalter", position, Orientation.R0, false); super("Wechselschalter", position);
} common = newJunction(this, "C", P10, P50);
output0 = newJunction(this, "O0", P90, P25);
public PartSwitch1x2(final String name, final Position position, final Orientation orientation, final boolean state) { output1 = newJunction(this, "O1", P90, P75);
super(name, position, orientation);
common = newJunction(this, "", P10, P50);
output0 = newJunction(this, "", P90, P25);
output1 = newJunction(this, "", P90, P75);
this.state = state;
} }
public PartSwitch1x2(final PartSwitch1x2Dto dto) { public PartSwitch1x2(final PartSwitch1x2Dto dto) {
@ -53,25 +49,6 @@ public class PartSwitch1x2 extends PartOther {
state = !state; state = !state;
} }
@Override
public void propagate(final Junction source) throws ShortCircuit {
if (source == common) {
if (state) {
output1.propagate(source.getVoltage());
} else {
output0.propagate(source.getVoltage());
}
} else if (source == output0) {
if (!state) {
common.propagate(source.getVoltage());
}
} else if (source == output1) {
if (state) {
common.propagate(source.getVoltage());
}
}
}
@Override @Override
protected void _render() { protected void _render() {
if (!state) { if (!state) {
@ -81,4 +58,12 @@ public class PartSwitch1x2 extends PartOther {
} }
} }
@Override
public List<InnerConnection> getInnerConnections() {
if (state) {
return List.of(new InnerConnection(common, output1));
}
return List.of(new InnerConnection(common, output0));
}
} }

View File

@ -1,14 +1,15 @@
package de.ph87.electro.circuit.part.parts; package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.ShortCircuit; import de.ph87.electro.circuit.part.InnerConnection;
import de.ph87.electro.circuit.part.Junction; import de.ph87.electro.circuit.part.Junction;
import de.ph87.electro.circuit.part.Orientation;
import de.ph87.electro.circuit.part.PartOther; import de.ph87.electro.circuit.part.PartOther;
import de.ph87.electro.circuit.part.Position; import de.ph87.electro.circuit.part.Position;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import java.util.List;
import static de.ph87.electro.CONFIG.*; import static de.ph87.electro.CONFIG.*;
@Getter @Getter
@ -24,23 +25,18 @@ public class PartSwitchCross extends PartOther {
private final Junction output1; private final Junction output1;
@Setter @Setter
private boolean state; private boolean state = false;
public PartSwitchCross() { public PartSwitchCross() {
this(Position.ZERO); this(Position.ZERO);
} }
public PartSwitchCross(final Position position) { public PartSwitchCross(final Position position) {
this("Kreuzschalter", position, Orientation.R0, false); super("Kreuzschalter", position);
} common0 = newJunction(this, "C0", P10, P25);
common1 = newJunction(this, "C1", P10, P75);
public PartSwitchCross(final String name, final Position position, final Orientation orientation, final boolean state) { output0 = newJunction(this, "O0", P90, P25);
super(name, position, orientation); output1 = newJunction(this, "O1", P90, P75);
common0 = newJunction(this, "", P10, P25);
common1 = newJunction(this, "", P10, P75);
output0 = newJunction(this, "", P90, P25);
output1 = newJunction(this, "", P90, P75);
this.state = state;
} }
public PartSwitchCross(final PartSwitchCrossDto dto) { public PartSwitchCross(final PartSwitchCrossDto dto) {
@ -57,35 +53,6 @@ public class PartSwitchCross extends PartOther {
state = !state; state = !state;
} }
@Override
public void propagate(final Junction source) throws ShortCircuit {
if (source == common0) {
if (state) {
output1.propagate(source.getVoltage());
} else {
output0.propagate(source.getVoltage());
}
} else if (source == common1) {
if (state) {
output0.propagate(source.getVoltage());
} else {
output1.propagate(source.getVoltage());
}
} else if (source == output0) {
if (state) {
common1.propagate(source.getVoltage());
} else {
common0.propagate(source.getVoltage());
}
} else if (source == output1) {
if (state) {
common0.propagate(source.getVoltage());
} else {
common1.propagate(source.getVoltage());
}
}
}
@Override @Override
protected void _render() { protected void _render() {
if (!state) { if (!state) {
@ -97,4 +64,18 @@ public class PartSwitchCross extends PartOther {
} }
} }
@Override
public List<InnerConnection> getInnerConnections() {
if (state) {
return List.of(
new InnerConnection(common0, output1),
new InnerConnection(common1, output0)
);
}
return List.of(
new InnerConnection(common0, output0),
new InnerConnection(common1, output1)
);
}
} }

View File

@ -12,27 +12,27 @@ public class BatteryLightTest {
private static final double VOLTAGE = 3; private static final double VOLTAGE = 3;
private static final Circuit circuit = new Circuit(); private static final Circuit CIRCUIT = new Circuit();
private static final PartBattery battery = circuit.addPart(new PartBattery()); private static final PartBattery battery = CIRCUIT.addPart(new PartBattery());
private static final PartLight light = circuit.addPart(new PartLight()); private static final PartLight light = CIRCUIT.addPart(new PartLight());
@BeforeAll @BeforeAll
public static void setUp() { public static void setUp() {
circuit.connect(battery.getPlus(), light.getPin1()); CIRCUIT.connect(battery.getPlus(), light.getB());
circuit.connect(light.getPin0(), battery.getMinus()); CIRCUIT.connect(light.getA(), battery.getMinus());
} }
@Test @Test
void test() { void test() {
circuit.evaluateAndRender(); CIRCUIT.evaluateAndRender();
assertEquals(VOLTAGE, battery.getPlus().getVoltage()); assertEquals(VOLTAGE, battery.getPlus().getVoltage());
assertEquals(VOLTAGE, light.getPin1().getVoltage()); assertEquals(VOLTAGE, light.getB().getVoltage());
assertEquals(VOLTAGE, light.getVoltage()); assertEquals(VOLTAGE, light.getPotentialDifference());
assertEquals(0, light.getPin0().getVoltage()); assertEquals(0, light.getA().getVoltage());
assertEquals(0, battery.getMinus().getVoltage()); assertEquals(0, battery.getMinus().getVoltage());
assertFalse(light.isDefect()); assertFalse(light.isDefect());

View File

@ -13,19 +13,19 @@ public class BatterySwitcher1x1Test {
private static final double VOLTAGE = 3; private static final double VOLTAGE = 3;
private static final Circuit circuit = new Circuit(); private static final Circuit CIRCUIT = new Circuit();
private static final PartBattery battery = circuit.addPart(new PartBattery()); private static final PartBattery battery = CIRCUIT.addPart(new PartBattery());
private static final PartSwitch1x1 switcher = circuit.addPart(new PartSwitch1x1()); private static final PartSwitch1x1 switcher = CIRCUIT.addPart(new PartSwitch1x1());
private static final PartLight light = circuit.addPart(new PartLight()); private static final PartLight light = CIRCUIT.addPart(new PartLight());
@BeforeAll @BeforeAll
public static void setUp() { public static void setUp() {
circuit.connect(battery.getPlus(), switcher.getCommon()); CIRCUIT.connect(battery.getPlus(), switcher.getCommon());
circuit.connect(switcher.getOutput(), light.getPin1()); CIRCUIT.connect(switcher.getOutput(), light.getB());
circuit.connect(light.getPin0(), battery.getMinus()); CIRCUIT.connect(light.getA(), battery.getMinus());
} }
@Test @Test
@ -43,7 +43,7 @@ public class BatterySwitcher1x1Test {
switcher.setState(state); switcher.setState(state);
circuit.evaluateAndRender(); CIRCUIT.evaluateAndRender();
assertEquals(state, switcher.isState()); assertEquals(state, switcher.isState());
@ -51,10 +51,10 @@ public class BatterySwitcher1x1Test {
assertEquals(VOLTAGE, switcher.getCommon().getVoltage()); assertEquals(VOLTAGE, switcher.getCommon().getVoltage());
assertEquals(voltage, switcher.getOutput().getVoltage()); assertEquals(voltage, switcher.getOutput().getVoltage());
assertEquals(voltage, light.getPin1().getVoltage()); assertEquals(voltage, light.getB().getVoltage());
assertEquals(voltage, light.getVoltage()); assertEquals(voltage, light.getPotentialDifference());
assertEquals(0, light.getPin0().getVoltage()); assertEquals(0, light.getA().getVoltage());
assertEquals(0, battery.getMinus().getVoltage()); assertEquals(0, battery.getMinus().getVoltage());
assertFalse(light.isDefect()); assertFalse(light.isDefect());

View File

@ -13,23 +13,23 @@ public class BatterySwitcher1x2Test {
private static final double VOLTAGE = 3; private static final double VOLTAGE = 3;
private static final Circuit circuit = new Circuit(); private static final Circuit CIRCUIT = new Circuit();
private static final PartBattery battery = circuit.addPart(new PartBattery()); private static final PartBattery battery = CIRCUIT.addPart(new PartBattery());
private static final PartSwitch1x2 switcher = circuit.addPart(new PartSwitch1x2()); private static final PartSwitch1x2 switcher = CIRCUIT.addPart(new PartSwitch1x2());
private static final PartLight light0 = circuit.addPart(new PartLight()); private static final PartLight light0 = CIRCUIT.addPart(new PartLight());
private static final PartLight light1 = circuit.addPart(new PartLight()); private static final PartLight light1 = CIRCUIT.addPart(new PartLight());
@BeforeAll @BeforeAll
public static void setUp() { public static void setUp() {
circuit.connect(battery.getPlus(), switcher.getCommon()); CIRCUIT.connect(battery.getPlus(), switcher.getCommon());
circuit.connect(switcher.getOutput0(), light0.getPin1()); CIRCUIT.connect(switcher.getOutput0(), light0.getB());
circuit.connect(light0.getPin0(), battery.getMinus()); CIRCUIT.connect(light0.getA(), battery.getMinus());
circuit.connect(switcher.getOutput1(), light1.getPin1()); CIRCUIT.connect(switcher.getOutput1(), light1.getB());
circuit.connect(light1.getPin0(), battery.getMinus()); CIRCUIT.connect(light1.getA(), battery.getMinus());
} }
@Test @Test
@ -48,7 +48,7 @@ public class BatterySwitcher1x2Test {
switcher.setState(state); switcher.setState(state);
circuit.evaluateAndRender(); CIRCUIT.evaluateAndRender();
assertEquals(state, switcher.isState()); assertEquals(state, switcher.isState());
@ -56,15 +56,15 @@ public class BatterySwitcher1x2Test {
assertEquals(VOLTAGE, switcher.getCommon().getVoltage()); assertEquals(VOLTAGE, switcher.getCommon().getVoltage());
assertEquals(voltage0, switcher.getOutput0().getVoltage()); assertEquals(voltage0, switcher.getOutput0().getVoltage());
assertEquals(voltage0, light0.getPin1().getVoltage()); assertEquals(voltage0, light0.getB().getVoltage());
assertEquals(voltage0, light0.getVoltage()); assertEquals(voltage0, light0.getPotentialDifference());
assertEquals(voltage1, switcher.getOutput1().getVoltage()); assertEquals(voltage1, switcher.getOutput1().getVoltage());
assertEquals(voltage1, light1.getPin1().getVoltage()); assertEquals(voltage1, light1.getB().getVoltage());
assertEquals(voltage1, light1.getVoltage()); assertEquals(voltage1, light1.getPotentialDifference());
assertEquals(0, light0.getPin0().getVoltage()); assertEquals(0, light0.getA().getVoltage());
assertEquals(0, light1.getPin0().getVoltage()); assertEquals(0, light1.getA().getVoltage());
assertEquals(0, battery.getMinus().getVoltage()); assertEquals(0, battery.getMinus().getVoltage());
assertFalse(light0.isDefect()); assertFalse(light0.isDefect());

View File

@ -13,23 +13,23 @@ public class BatterySwitcher2x2Test {
private static final double VOLTAGE = 3; private static final double VOLTAGE = 3;
private static final Circuit circuit = new Circuit(); private static final Circuit CIRCUIT = new Circuit();
private static final PartBattery battery = circuit.addPart(new PartBattery()); private static final PartBattery battery = CIRCUIT.addPart(new PartBattery());
private static final PartSwitch1x2 switcher0 = circuit.addPart(new PartSwitch1x2()); private static final PartSwitch1x2 switcher0 = CIRCUIT.addPart(new PartSwitch1x2());
private static final PartSwitch1x2 switcher1 = circuit.addPart(new PartSwitch1x2()); private static final PartSwitch1x2 switcher1 = CIRCUIT.addPart(new PartSwitch1x2());
private static final PartLight light = circuit.addPart(new PartLight()); private static final PartLight light = CIRCUIT.addPart(new PartLight());
@BeforeAll @BeforeAll
public static void setUp() { public static void setUp() {
circuit.connect(battery.getPlus(), switcher0.getCommon()); CIRCUIT.connect(battery.getPlus(), switcher0.getCommon());
circuit.connect(switcher0.getOutput0(), switcher1.getOutput0()); CIRCUIT.connect(switcher0.getOutput0(), switcher1.getOutput0());
circuit.connect(switcher0.getOutput1(), switcher1.getOutput1()); CIRCUIT.connect(switcher0.getOutput1(), switcher1.getOutput1());
circuit.connect(switcher1.getCommon(), light.getPin1()); CIRCUIT.connect(switcher1.getCommon(), light.getB());
circuit.connect(light.getPin0(), battery.getMinus()); CIRCUIT.connect(light.getA(), battery.getMinus());
} }
@Test @Test
@ -60,7 +60,7 @@ public class BatterySwitcher2x2Test {
switcher0.setState(state0); switcher0.setState(state0);
switcher1.setState(state1); switcher1.setState(state1);
circuit.evaluateAndRender(); CIRCUIT.evaluateAndRender();
assertEquals(state0, switcher0.isState()); assertEquals(state0, switcher0.isState());
assertEquals(state1, switcher1.isState()); assertEquals(state1, switcher1.isState());
@ -75,10 +75,10 @@ public class BatterySwitcher2x2Test {
assertEquals(voltage1, switcher1.getOutput1().getVoltage()); assertEquals(voltage1, switcher1.getOutput1().getVoltage());
assertEquals(voltage, switcher1.getCommon().getVoltage()); assertEquals(voltage, switcher1.getCommon().getVoltage());
assertEquals(voltage, light.getPin1().getVoltage()); assertEquals(voltage, light.getB().getVoltage());
assertEquals(voltage, light.getVoltage()); assertEquals(voltage, light.getPotentialDifference());
assertEquals(0, light.getPin0().getVoltage()); assertEquals(0, light.getA().getVoltage());
assertEquals(0, battery.getMinus().getVoltage()); assertEquals(0, battery.getMinus().getVoltage());
assertFalse(light.isDefect()); assertFalse(light.isDefect());

View File

@ -14,27 +14,27 @@ public class BatterySwitcherCrossTest {
private static final double VOLTAGE = 3; private static final double VOLTAGE = 3;
private static final Circuit circuit = new Circuit(); private static final Circuit CIRCUIT = new Circuit();
private static final PartBattery battery = circuit.addPart(new PartBattery()); private static final PartBattery battery = CIRCUIT.addPart(new PartBattery());
private static final PartSwitch1x2 switcher0 = circuit.addPart(new PartSwitch1x2()); private static final PartSwitch1x2 switcher0 = CIRCUIT.addPart(new PartSwitch1x2());
private static final PartSwitchCross switcherX = circuit.addPart(new PartSwitchCross()); private static final PartSwitchCross switcherX = CIRCUIT.addPart(new PartSwitchCross());
private static final PartSwitch1x2 switcher1 = circuit.addPart(new PartSwitch1x2()); private static final PartSwitch1x2 switcher1 = CIRCUIT.addPart(new PartSwitch1x2());
private static final PartLight light = circuit.addPart(new PartLight()); private static final PartLight light = CIRCUIT.addPart(new PartLight());
@BeforeAll @BeforeAll
public static void setUp() { public static void setUp() {
circuit.connect(battery.getPlus(), switcher0.getCommon()); CIRCUIT.connect(battery.getPlus(), switcher0.getCommon());
circuit.connect(switcher0.getOutput0(), switcherX.getCommon0()); CIRCUIT.connect(switcher0.getOutput0(), switcherX.getCommon0());
circuit.connect(switcher0.getOutput1(), switcherX.getCommon1()); CIRCUIT.connect(switcher0.getOutput1(), switcherX.getCommon1());
circuit.connect(switcherX.getOutput0(), switcher1.getOutput0()); CIRCUIT.connect(switcherX.getOutput0(), switcher1.getOutput0());
circuit.connect(switcherX.getOutput1(), switcher1.getOutput1()); CIRCUIT.connect(switcherX.getOutput1(), switcher1.getOutput1());
circuit.connect(switcher1.getCommon(), light.getPin1()); CIRCUIT.connect(switcher1.getCommon(), light.getB());
circuit.connect(light.getPin0(), battery.getMinus()); CIRCUIT.connect(light.getA(), battery.getMinus());
} }
@Test @Test
@ -88,7 +88,7 @@ public class BatterySwitcherCrossTest {
switcherX.setState(stateX); switcherX.setState(stateX);
switcher1.setState(state1); switcher1.setState(state1);
circuit.evaluateAndRender(); CIRCUIT.evaluateAndRender();
assertEquals(state0, switcher0.isState()); assertEquals(state0, switcher0.isState());
assertEquals(stateX, switcherX.isState()); assertEquals(stateX, switcherX.isState());
@ -110,10 +110,10 @@ public class BatterySwitcherCrossTest {
assertEquals(voltageX1, switcher1.getOutput1().getVoltage()); assertEquals(voltageX1, switcher1.getOutput1().getVoltage());
assertEquals(voltage, switcher1.getCommon().getVoltage()); assertEquals(voltage, switcher1.getCommon().getVoltage());
assertEquals(voltage, light.getPin1().getVoltage()); assertEquals(voltage, light.getB().getVoltage());
assertEquals(voltage, light.getVoltage()); assertEquals(voltage, light.getPotentialDifference());
assertEquals(0, light.getPin0().getVoltage()); assertEquals(0, light.getA().getVoltage());
assertEquals(0, battery.getMinus().getVoltage()); assertEquals(0, battery.getMinus().getVoltage());
assertFalse(light.isDefect()); assertFalse(light.isDefect());

View File

@ -13,15 +13,15 @@ import java.nio.charset.StandardCharsets;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
class CircuitServiceTest { class CircuitCalculationServiceTest {
@Test @Test
void serialization() throws IOException { void serialization() throws IOException {
final Circuit circuit = new Circuit(); final Circuit circuit = new Circuit();
final PartBattery battery = circuit.addPart(new PartBattery()); final PartBattery battery = circuit.addPart(new PartBattery());
final PartLight light = circuit.addPart(new PartLight()); final PartLight light = circuit.addPart(new PartLight());
circuit.connect(battery.getPlus(), light.getPin1()); circuit.connect(battery.getPlus(), light.getB());
circuit.connect(light.getPin0(), battery.getMinus()); circuit.connect(light.getA(), battery.getMinus());
check(circuit); check(circuit);
} }

View File

@ -0,0 +1,40 @@
package de.ph87.electro.circuit.net;
import de.ph87.electro.circuit.Calculation;
import de.ph87.electro.circuit.Circuit;
import de.ph87.electro.circuit.Wire;
import de.ph87.electro.circuit.part.Junction;
import de.ph87.electro.circuit.part.parts.PartBattery;
import de.ph87.electro.circuit.part.parts.PartLight;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
@Slf4j
class CalculationServiceTest {
@Test
void test() {
final Circuit circuit = new Circuit();
final PartBattery battery = circuit.addPart(new PartBattery());
final PartLight light = circuit.addPart(new PartLight());
circuit.connect(battery.getMinus(), light.getA());
circuit.connect(battery.getPlus(), light.getB());
final Calculation calculation = new Calculation(circuit);
calculation.toString().lines().forEach(log::info);
circuit.streamParts().forEach(part -> {
log.info("");
log.info(part.toString());
for (final Junction junction : part.getJunctions()) {
log.info(" \"%s\" = %.2f V".formatted(junction.getName(), junction.getVoltage()));
for (final Wire wire : junction.getWires()) {
final Junction opposite = wire.getOpposite(junction);
log.info(" -> %s.%s = %.2f A".formatted(opposite.getOwner().getName(), opposite.getName(), wire.getCurrent(junction)));
}
}
});
log.info("");
}
}

View File

@ -0,0 +1,19 @@
package de.ph87.electro.circuit.net;
import de.ph87.electro.circuit.Calculation;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
@Slf4j
class CalculationTest {
@Test
void test() {
final Calculation calculation = new Calculation(1);
calculation.addResistor(-1, 0, 15);
calculation.addCurrentSource(-1, 0, 4, 5);
calculation.solve();
calculation.toString().lines().forEach(log::info);
}
}