Voltmeter
This commit is contained in:
parent
e71791d0b2
commit
02a24b43e7
@ -6,6 +6,10 @@ import static java.lang.Math.round;
|
|||||||
|
|
||||||
public class CONFIG {
|
public class CONFIG {
|
||||||
|
|
||||||
|
public static final double NO_RESISTANCE = 1e-12;
|
||||||
|
|
||||||
|
public static final double MAX_RESISTANCE = 1 / NO_RESISTANCE;
|
||||||
|
|
||||||
public static boolean SHOW_WIRE_DETAILS = true;
|
public static boolean SHOW_WIRE_DETAILS = true;
|
||||||
|
|
||||||
public static boolean SHOW_JUNCTION_VOLTAGES = false;
|
public static boolean SHOW_JUNCTION_VOLTAGES = false;
|
||||||
|
|||||||
@ -5,6 +5,9 @@ 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.junction.Junction;
|
import de.ph87.electro.circuit.part.junction.Junction;
|
||||||
|
import de.ph87.electro.circuit.part.parts.Battery;
|
||||||
|
import de.ph87.electro.circuit.part.parts.Poti;
|
||||||
|
import de.ph87.electro.circuit.part.parts.Voltmeter;
|
||||||
import de.ph87.electro.circuit.wire.Wire;
|
import de.ph87.electro.circuit.wire.Wire;
|
||||||
import de.ph87.electro.circuit.wire.WireDto;
|
import de.ph87.electro.circuit.wire.WireDto;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -19,6 +22,8 @@ import java.util.List;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static de.ph87.electro.circuit.part.Position.RST;
|
||||||
|
|
||||||
public class Circuit {
|
public class Circuit {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@ -40,7 +45,7 @@ public class Circuit {
|
|||||||
public Circuit(final File file, final CircuitDto dto) {
|
public Circuit(final File file, final CircuitDto dto) {
|
||||||
created = dto.getCreated();
|
created = dto.getCreated();
|
||||||
for (PartDto partDto : dto.getParts()) {
|
for (PartDto partDto : dto.getParts()) {
|
||||||
final Part part = Part.of(this, partDto);
|
final Part part = Part.fromDto(this, partDto);
|
||||||
verifyFree(part.getPosition());
|
verifyFree(part.getPosition());
|
||||||
parts.add(part);
|
parts.add(part);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,6 +37,8 @@ public class CircuitPanelDropTarget extends AbstractDropTarget {
|
|||||||
circuitPanel.getCircuit().addPart(new SwitchCross(circuitPanel.getCircuit(), position));
|
circuitPanel.getCircuit().addPart(new SwitchCross(circuitPanel.getCircuit(), position));
|
||||||
} else if (data.equals(Poti.class.getSimpleName())) {
|
} else if (data.equals(Poti.class.getSimpleName())) {
|
||||||
circuitPanel.getCircuit().addPart(new Poti(circuitPanel.getCircuit(), position));
|
circuitPanel.getCircuit().addPart(new Poti(circuitPanel.getCircuit(), position));
|
||||||
|
} else if (data.equals(Voltmeter.class.getSimpleName())) {
|
||||||
|
circuitPanel.getCircuit().addPart(new Voltmeter(circuitPanel.getCircuit(), position));
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package de.ph87.electro.circuit.calculation;
|
package de.ph87.electro.circuit.calculation;
|
||||||
|
|
||||||
|
import de.ph87.electro.CONFIG;
|
||||||
import de.ph87.electro.circuit.Circuit;
|
import de.ph87.electro.circuit.Circuit;
|
||||||
import de.ph87.electro.circuit.part.InnerConnection;
|
import de.ph87.electro.circuit.part.InnerConnection;
|
||||||
import de.ph87.electro.circuit.part.Part;
|
import de.ph87.electro.circuit.part.Part;
|
||||||
@ -22,10 +23,6 @@ import static java.lang.Math.max;
|
|||||||
@Getter
|
@Getter
|
||||||
public class Calculation {
|
public class Calculation {
|
||||||
|
|
||||||
public static final double NO_RESISTANCE = 1e-12;
|
|
||||||
|
|
||||||
private static final double FULL_ADMITTANCE = 1 / NO_RESISTANCE;
|
|
||||||
|
|
||||||
private final List<Junction> junctions = new ArrayList<>();
|
private final List<Junction> junctions = new ArrayList<>();
|
||||||
|
|
||||||
private final Set<Part> parts = new HashSet<>();
|
private final Set<Part> parts = new HashSet<>();
|
||||||
@ -76,7 +73,7 @@ public class Calculation {
|
|||||||
|
|
||||||
private void fromSchematic() {
|
private void fromSchematic() {
|
||||||
wires.forEach(
|
wires.forEach(
|
||||||
wire -> addResistor(wire.getA(), wire.getB(), NO_RESISTANCE)
|
wire -> addResistor(wire.getA(), wire.getB(), CONFIG.NO_RESISTANCE)
|
||||||
);
|
);
|
||||||
parts.forEach(part -> {
|
parts.forEach(part -> {
|
||||||
for (final InnerConnection innerConnection : part.getInnerConnections()) {
|
for (final InnerConnection innerConnection : part.getInnerConnections()) {
|
||||||
@ -113,7 +110,7 @@ public class Calculation {
|
|||||||
private double getCurrent(final Wire wire) {
|
private double getCurrent(final Wire wire) {
|
||||||
final int indexA = getJunctionIndex(wire.getA());
|
final int indexA = getJunctionIndex(wire.getA());
|
||||||
final int indexB = getJunctionIndex(wire.getB());
|
final int indexB = getJunctionIndex(wire.getB());
|
||||||
final double conductance = indexA >= 0 && indexB >= 0 ? matrix.getEntry(indexA, indexB) : FULL_ADMITTANCE;
|
final double conductance = indexA >= 0 && indexB >= 0 ? matrix.getEntry(indexA, indexB) : 1 / CONFIG.NO_RESISTANCE;
|
||||||
final double potentialDifference = getPotential(wire.getB()) - getPotential(wire.getA());
|
final double potentialDifference = getPotential(wire.getB()) - getPotential(wire.getA());
|
||||||
return conductance * potentialDifference;
|
return conductance * potentialDifference;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -80,7 +80,7 @@ public abstract class Part {
|
|||||||
evaluate();
|
evaluate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render() {
|
public final void render() {
|
||||||
render.rect(ZERO, RASTER, RASTER, null, null, PART_BACKGROUND);
|
render.rect(ZERO, RASTER, RASTER, null, null, PART_BACKGROUND);
|
||||||
|
|
||||||
_labels();
|
_labels();
|
||||||
@ -136,7 +136,7 @@ public abstract class Part {
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Part of(final Circuit circuit, final PartDto abstractDto) {
|
public static Part fromDto(final Circuit circuit, final PartDto abstractDto) {
|
||||||
return switch (abstractDto) {
|
return switch (abstractDto) {
|
||||||
case final BatteryDto dto -> new Battery(circuit, dto);
|
case final BatteryDto dto -> new Battery(circuit, dto);
|
||||||
case final ConnectorCornerDto dto -> new ConnectorCorner(circuit, dto);
|
case final ConnectorCornerDto dto -> new ConnectorCorner(circuit, dto);
|
||||||
@ -146,6 +146,8 @@ public abstract class Part {
|
|||||||
case final Switch1x1Dto dto -> new Switch1x1(circuit, dto);
|
case final Switch1x1Dto dto -> new Switch1x1(circuit, dto);
|
||||||
case final Switch1x2Dto dto -> new Switch1x2(circuit, dto);
|
case final Switch1x2Dto dto -> new Switch1x2(circuit, dto);
|
||||||
case final SwitchCrossDto dto -> new SwitchCross(circuit, dto);
|
case final SwitchCrossDto dto -> new SwitchCross(circuit, dto);
|
||||||
|
case final PotiDto dto -> new Poti(circuit, dto);
|
||||||
|
case final VoltmeterDto dto -> new Voltmeter(circuit, dto);
|
||||||
case null, default -> throw new RuntimeException();
|
case null, default -> throw new RuntimeException();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,6 +40,7 @@ public abstract class PartDto {
|
|||||||
case final Switch1x2 part -> new Switch1x2Dto(part);
|
case final Switch1x2 part -> new Switch1x2Dto(part);
|
||||||
case final SwitchCross part -> new SwitchCrossDto(part);
|
case final SwitchCross part -> new SwitchCrossDto(part);
|
||||||
case final Poti part -> new PotiDto(part);
|
case final Poti part -> new PotiDto(part);
|
||||||
|
case final Voltmeter part -> new VoltmeterDto(part);
|
||||||
case null, default -> throw new RuntimeException();
|
case null, default -> throw new RuntimeException();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package de.ph87.electro.circuit.part;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
import org.apache.commons.math3.linear.RealVector;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
@ -22,6 +23,10 @@ public final class Position {
|
|||||||
|
|
||||||
public final Point raster;
|
public final Point raster;
|
||||||
|
|
||||||
|
public static Position ABS(final RealVector vector) {
|
||||||
|
return ABS(vector.getEntry(0), vector.getEntry(1));
|
||||||
|
}
|
||||||
|
|
||||||
public static Position ABS(final double absoluteX, final double absoluteY) {
|
public static Position ABS(final double absoluteX, final double absoluteY) {
|
||||||
return new Position((int) round(absoluteX), (int) round(absoluteY));
|
return new Position((int) round(absoluteX), (int) round(absoluteY));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,11 +19,11 @@ public class Render {
|
|||||||
|
|
||||||
private final Graphics2D g = image.createGraphics();
|
private final Graphics2D g = image.createGraphics();
|
||||||
|
|
||||||
public void line(final Junction junction0, final Junction junction1, final Color color, final BasicStroke stroke) {
|
public void line(final Junction junction0, final Junction junction1, final Color color, final Stroke stroke) {
|
||||||
line(junction0.getPosition(), junction1.getPosition(), color, stroke);
|
line(junction0.getPosition(), junction1.getPosition(), color, stroke);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void line(final Position p0, final Position p1, final Color color, final BasicStroke stroke) {
|
public void line(final Position p0, final Position p1, final Color color, final Stroke stroke) {
|
||||||
if (color != null) {
|
if (color != null) {
|
||||||
g.setColor(color);
|
g.setColor(color);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,6 @@ import java.awt.*;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static de.ph87.electro.CONFIG.*;
|
import static de.ph87.electro.CONFIG.*;
|
||||||
import static de.ph87.electro.circuit.calculation.Calculation.NO_RESISTANCE;
|
|
||||||
import static java.lang.Math.max;
|
import static java.lang.Math.max;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@ -38,7 +37,7 @@ public class Poti extends Part {
|
|||||||
end = addJunction("E", P90, P50);
|
end = addJunction("E", P90, P50);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Poti(final Circuit circuit, final PotiDto dto) {
|
public Poti(final Circuit circuit, final PotiDto dto) {
|
||||||
super(circuit, dto);
|
super(circuit, dto);
|
||||||
common = addJunction(dto.getCommon().getName(), P10, P50);
|
common = addJunction(dto.getCommon().getName(), P10, P50);
|
||||||
middle = addJunction(dto.getMiddle().getName(), P50, P10);
|
middle = addJunction(dto.getMiddle().getName(), P50, P10);
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
package de.ph87.electro.circuit.part.parts;
|
||||||
|
|
||||||
|
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
|
||||||
|
import org.apache.commons.math3.linear.RealMatrix;
|
||||||
|
|
||||||
|
import static java.lang.Math.cos;
|
||||||
|
import static java.lang.Math.sin;
|
||||||
|
|
||||||
|
public class RotationMatrix extends Array2DRowRealMatrix {
|
||||||
|
|
||||||
|
public static RealMatrix ofDegrees(final double degrees) {
|
||||||
|
final double radians = degrees * Math.PI / 180.0;
|
||||||
|
return new RotationMatrix(radians);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RotationMatrix(final double radians) {
|
||||||
|
super(new double[][]{
|
||||||
|
{cos(radians), -sin(radians)},
|
||||||
|
{sin(radians), cos(radians)},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -12,7 +12,7 @@ import java.awt.*;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static de.ph87.electro.CONFIG.*;
|
import static de.ph87.electro.CONFIG.*;
|
||||||
import static de.ph87.electro.circuit.calculation.Calculation.NO_RESISTANCE;
|
import static de.ph87.electro.CONFIG.NO_RESISTANCE;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import lombok.ToString;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static de.ph87.electro.CONFIG.*;
|
import static de.ph87.electro.CONFIG.*;
|
||||||
import static de.ph87.electro.circuit.calculation.Calculation.NO_RESISTANCE;
|
import static de.ph87.electro.CONFIG.NO_RESISTANCE;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import lombok.ToString;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static de.ph87.electro.CONFIG.*;
|
import static de.ph87.electro.CONFIG.*;
|
||||||
import static de.ph87.electro.circuit.calculation.Calculation.NO_RESISTANCE;
|
import static de.ph87.electro.CONFIG.NO_RESISTANCE;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
|
|||||||
@ -0,0 +1,95 @@
|
|||||||
|
package de.ph87.electro.circuit.part.parts;
|
||||||
|
|
||||||
|
import de.ph87.electro.circuit.Circuit;
|
||||||
|
import de.ph87.electro.circuit.part.InnerConnection;
|
||||||
|
import de.ph87.electro.circuit.part.Part;
|
||||||
|
import de.ph87.electro.circuit.part.PartDto;
|
||||||
|
import de.ph87.electro.circuit.part.Position;
|
||||||
|
import de.ph87.electro.circuit.part.junction.Junction;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.apache.commons.math3.linear.ArrayRealVector;
|
||||||
|
import org.apache.commons.math3.linear.RealMatrix;
|
||||||
|
import org.apache.commons.math3.linear.RealVector;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static de.ph87.electro.CONFIG.*;
|
||||||
|
import static de.ph87.electro.circuit.part.Position.ABS;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class Voltmeter extends Part {
|
||||||
|
|
||||||
|
private static final RealVector ANCHOR = new ArrayRealVector(new double[]{P50, P50});
|
||||||
|
|
||||||
|
private static final RealVector FINGER = new ArrayRealVector(new double[]{P90, P50}).subtract(ANCHOR);
|
||||||
|
|
||||||
|
private static final Stroke SCALE_STROKE = new BasicStroke(1);
|
||||||
|
|
||||||
|
private static final double DEGREES_TOTAL = 90.0;
|
||||||
|
|
||||||
|
private static final double DEGREES_ROTATE = -135.0;
|
||||||
|
|
||||||
|
private final Junction a;
|
||||||
|
|
||||||
|
private final Junction b;
|
||||||
|
|
||||||
|
private double min = -3;
|
||||||
|
|
||||||
|
private double max = +3;
|
||||||
|
|
||||||
|
private double voltage;
|
||||||
|
|
||||||
|
private RealVector tip;
|
||||||
|
|
||||||
|
public Voltmeter(final Circuit circuit, final Position position) {
|
||||||
|
super(circuit, "Voltmeter", position);
|
||||||
|
a = addJunction("A", P10, P50);
|
||||||
|
b = addJunction("B", P90, P50);
|
||||||
|
postCalculate(); // TODO remove
|
||||||
|
}
|
||||||
|
|
||||||
|
public Voltmeter(final Circuit circuit, final PartDto dto) {
|
||||||
|
super(circuit, dto);
|
||||||
|
a = addJunction("A", P10, P50);
|
||||||
|
b = addJunction("B", P90, P50);
|
||||||
|
postCalculate(); // TODO remove
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMin(final double min) {
|
||||||
|
this.min = min;
|
||||||
|
evaluate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMax(final double max) {
|
||||||
|
this.max = max;
|
||||||
|
evaluate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postCalculate() {
|
||||||
|
voltage = !Double.isNaN(b.getVoltage()) && !Double.isNaN(a.getVoltage()) ? b.getVoltage() - a.getVoltage() : 0.0;
|
||||||
|
final double ratio = (voltage - min) / (max - min);
|
||||||
|
final double degrees = DEGREES_TOTAL * ratio + DEGREES_ROTATE;
|
||||||
|
final RealMatrix rotate = RotationMatrix.ofDegrees(degrees);
|
||||||
|
final RealVector rotatedFinger = rotate.operate(FINGER);
|
||||||
|
tip = ANCHOR.add(rotatedFinger);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void _render() {
|
||||||
|
render.clockwise(getOrientation());
|
||||||
|
render.line(ABS(ANCHOR), ABS(tip), Color.BLACK, SCALE_STROKE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _labels() {
|
||||||
|
render.textCenter(LABEL_FONT, "%.2f V".formatted(voltage), P50, P75, Color.BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<InnerConnection> getInnerConnections() {
|
||||||
|
return List.of(new InnerConnection(a, b, MAX_RESISTANCE));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package de.ph87.electro.circuit.part.parts;
|
||||||
|
|
||||||
|
import de.ph87.electro.circuit.part.PartDto;
|
||||||
|
import de.ph87.electro.circuit.part.junction.JunctionDto;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class VoltmeterDto extends PartDto {
|
||||||
|
|
||||||
|
private JunctionDto a;
|
||||||
|
|
||||||
|
private JunctionDto b;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private double min;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private double max;
|
||||||
|
|
||||||
|
public VoltmeterDto(final Voltmeter voltmeter) {
|
||||||
|
a = new JunctionDto(voltmeter.getA());
|
||||||
|
b = new JunctionDto(voltmeter.getB());
|
||||||
|
min = voltmeter.getMin();
|
||||||
|
max = voltmeter.getMax();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -44,6 +44,7 @@ public class Sidebar extends JPanel {
|
|||||||
addPart(new Switch1x2(null, Position.ZERO));
|
addPart(new Switch1x2(null, Position.ZERO));
|
||||||
addPart(new SwitchCross(null, Position.ZERO));
|
addPart(new SwitchCross(null, Position.ZERO));
|
||||||
addPart(new Poti(null, Position.ZERO));
|
addPart(new Poti(null, Position.ZERO));
|
||||||
|
addPart(new Voltmeter(null, Position.ZERO));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("UnusedReturnValue")
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user