Added Opamp Table and Sine Kreis to Schaltungstheorie
All checks were successful
Build Typst PDFs (Docker) / build-typst (push) Successful in 27s
All checks were successful
Build Typst PDFs (Docker) / build-typst (push) Successful in 27s
This commit is contained in:
@@ -1,14 +1,18 @@
|
||||
#import "@preview/mannot:0.3.1"
|
||||
#import "@preview/zap:0.5.0"
|
||||
#import "@preview/cetz:0.4.2" :*
|
||||
#import "@preview/cetz:0.4.2" : *
|
||||
#import "@preview/cetz-plot:0.1.3"
|
||||
#import "../lib/circuit.typ" : *
|
||||
#import "@preview/unify:0.7.1": num,qty,unit
|
||||
#import "@preview/cetz-plot:0.1.3"
|
||||
|
||||
#import "../lib/schaltungstheorie/opampTable.typ" : *
|
||||
#import "../lib/schaltungstheorie/tumCustomSymbols.typ" as tumSymbols
|
||||
|
||||
#import "../lib/circuit.typ" : *
|
||||
#import "../lib/common_rewrite.typ" : *
|
||||
#import "../lib/circuit.typ" : *
|
||||
|
||||
|
||||
#set math.mat(delim: "[")
|
||||
#show math.equation.where(block: true): it => math.inline(it)
|
||||
#set math.mat(delim: "[")
|
||||
@@ -260,7 +264,7 @@
|
||||
wire("I0.in", "R1.in")
|
||||
wire("R1.in", (rel: (0.5, 0)), i: (content: $i$, invert: true))
|
||||
|
||||
cetz.draw.content((0.62, -0.75), [$R$])
|
||||
cetz.draw.content((0.62, -0.75), [$G_i$])
|
||||
cetz.draw.set-style(mark: (end: ">", fill: black, scale: 0.6))
|
||||
cetz.draw.content((1.7, -0.75), [$u$])
|
||||
cetz.draw.line((1.5, -0.1), (1.5, -1.4), stroke: 0.5pt)
|
||||
@@ -278,7 +282,7 @@
|
||||
)
|
||||
wire((0, -1.5), (1.75, -1.5))
|
||||
|
||||
cetz.draw.content((0.62, -0.75), [$R$])
|
||||
cetz.draw.content((0.62, -0.75), [$R_i$])
|
||||
cetz.draw.set-style(mark: (end: ">", fill: black, scale: 0.6))
|
||||
cetz.draw.content((1.95, -0.75), [$u$])
|
||||
cetz.draw.line((1.75, -0.1), (1.75, -1.4), stroke: 0.5pt)
|
||||
@@ -286,23 +290,22 @@
|
||||
),
|
||||
|
||||
[
|
||||
$u = R_i i + u_0$ \
|
||||
$u = R_i i + U_0$ \
|
||||
|
||||
],
|
||||
[
|
||||
$i = 1/R_i u - I_0$
|
||||
$i = G_i u - I_0$
|
||||
],
|
||||
|
||||
table.cell(colspan: 2)[
|
||||
#align($-->$)
|
||||
],
|
||||
table.cell(colspan: 2)[
|
||||
$<--$
|
||||
],
|
||||
align(center, text(size: 7mm, $-->$)),
|
||||
[$G_i = 1/R_i \ I_0 = U_0 G_i$],
|
||||
|
||||
[$R_i = 1/G_i \ U_0 = I_0 R_i$],
|
||||
align(center, text(size: 7mm, $<--$)),
|
||||
)
|
||||
]
|
||||
|
||||
// Quell Wandlung
|
||||
/*// Quell Wandlung
|
||||
#bgBlock(fill: colorEineTore)[
|
||||
#subHeading(fill: colorEineTore)[Quelle Wandlung]
|
||||
|
||||
@@ -369,6 +372,8 @@
|
||||
]
|
||||
);
|
||||
]
|
||||
*/
|
||||
|
||||
// Bauelemente
|
||||
#bgBlock(fill: colorEineTore)[
|
||||
#subHeading(fill: colorEineTore)[Bauelemente]
|
||||
@@ -1293,6 +1298,7 @@
|
||||
#subHeading(fill: colorComplexAC)[Komplexe Komponent]
|
||||
#table(
|
||||
columns: (1fr, 2fr, 2fr, 2fr),
|
||||
inset: (bottom: 2mm, top: 2mm),
|
||||
fill: (x, y) => if calc.rem(y, 2) == 1 { tableFillLow } else { tableFillHigh },
|
||||
[], [*$Y = U/I$*], [*$Z = I/U$*], [*$phi$*],
|
||||
[], [*$Omega$*], [*$S$*], [*rad*],
|
||||
@@ -1347,11 +1353,20 @@
|
||||
#bgBlock(fill: colorAllgemein, [
|
||||
#subHeading(fill: colorAllgemein, [Sin-Table])
|
||||
#sinTable
|
||||
|
||||
#SineCircle()
|
||||
])
|
||||
]
|
||||
|
||||
#pagebreak()
|
||||
|
||||
#bgBlock(fill: colorZweiTore, width: 100%)[
|
||||
#subHeading(fill: colorZweiTore)[OpAmp Schaltungen]
|
||||
|
||||
#scale(opampTable, 100%)
|
||||
]
|
||||
|
||||
|
||||
#bgBlock(fill: colorZweiTore, width: 100%)[
|
||||
#subHeading(fill: colorZweiTore)[Zwei-Tor-Übersichts]
|
||||
|
||||
@@ -1579,12 +1594,12 @@
|
||||
content((0.75, 0.75), "In")
|
||||
})
|
||||
]),
|
||||
$bold(R)$,
|
||||
$bold(G)$,
|
||||
$bold(H)$,
|
||||
$bold(H')$,
|
||||
$bold(A)$,
|
||||
$bold(A')$,
|
||||
$bold(R) quad mat(Omega, Omega; Omega, Omega)$,
|
||||
$bold(G) quad mat(S, S; S, S)$,
|
||||
$bold(H) quad mat(Omega, 1; 1, S)$,
|
||||
$bold(H') quad mat(S, 1; 1, Omega)$,
|
||||
$bold(A) quad mat(S, 1; 1, Omega)$,
|
||||
$bold(A') quad mat(S, 1; 1, Omega)$,
|
||||
|
||||
$bold(R)$,
|
||||
$mat(r_11, r_12; r_21, r_22)$,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#import "@preview/cetz:0.4.2"
|
||||
|
||||
#let bgBlock(body, fill: color, width: 100%) = block(body, fill:fill.lighten(80%), width: width, inset: (bottom: 2mm, left: 2mm, right: 2mm,))
|
||||
|
||||
#let SeperatorLine = line(length: 100%, stroke: (paint: black, thickness: 0.3mm))
|
||||
@@ -66,8 +68,51 @@
|
||||
|
||||
$z^* = a - #i b = r e^(-#i phi)$
|
||||
|
||||
Konjungiert Erweitern:\
|
||||
$(a + b #i)/(c + d #i) = ((a + b #i)(c - d #i))/(c^2 + d² )$
|
||||
|
||||
$r = abs(z) quad phi = cases(
|
||||
+ arccos(a/r) space : space a >= 0,
|
||||
- arccos(a/r) space : space a < 0,
|
||||
)$
|
||||
]
|
||||
]
|
||||
|
||||
#let SineCircle() = {
|
||||
align(center+horizon,
|
||||
cetz.canvas({
|
||||
import cetz.draw : *
|
||||
line((-33mm, 0), (33mm, 0), stroke: (paint: rgb("#8e8e8e7f")))
|
||||
line((0, -33mm), (0, 33mm), stroke: (paint: rgb("#8e8e8e7f")))
|
||||
let labels = (
|
||||
(0deg, $0°$, $0$),
|
||||
(30deg, $30°$, $pi/6$),
|
||||
(45deg, $45°$, $pi/4$),
|
||||
(60deg, $60°$, $pi/3$),
|
||||
(90deg, $90°$, $pi/2$),
|
||||
(120deg, $120°$, $2pi/3$),
|
||||
(135deg, $135°$, $3pi/4$),
|
||||
(150deg, $150°$, $5pi/6$),
|
||||
(180deg, $180°$, $pi$),
|
||||
(210deg, $210°$, $7pi/6$),
|
||||
(225deg, $2250°$, $5pi/4$),
|
||||
(240deg, $240°$, $4pi/3$),
|
||||
(270deg, $270°$, $3pi/2$),
|
||||
(300deg, $300°$, $5pi/3$),
|
||||
(315deg, $3150°$, $7pi/4$),
|
||||
(330deg, $330°$, $11pi/6$),
|
||||
)
|
||||
|
||||
|
||||
circle((0, 0), radius: 25mm)
|
||||
|
||||
|
||||
|
||||
for (pos, label1, label2) in labels {
|
||||
line((radius: 24mm, angle: pos), (radius: 26mm, angle: pos))
|
||||
content((radius: 20.0mm, angle: pos), label1, anchor: "mid", angle: if(pos > 90deg and pos < 270deg) {pos + 180deg} else {pos})
|
||||
content((radius: 29.5mm, angle: pos), label2, anchor: "mid")
|
||||
}
|
||||
|
||||
})
|
||||
)
|
||||
}
|
||||
271
src/lib/schaltungstheorie/opampTable.typ
Normal file
271
src/lib/schaltungstheorie/opampTable.typ
Normal file
@@ -0,0 +1,271 @@
|
||||
#import "@preview/zap:0.5.0"
|
||||
#import "@preview/cetz:0.4.2"
|
||||
|
||||
#import "tumCustomSymbols.typ" as joham
|
||||
#import "../common_rewrite.typ" : *
|
||||
|
||||
|
||||
#let opampTable = table(
|
||||
columns: (auto, auto, auto, auto, auto, auto),
|
||||
align: center + horizon,
|
||||
inset: (x, y) => if(y > 0) {3mm} else {2mm},
|
||||
fill: (x, y) => if calc.rem(x, 2) == 1 { tableFillHigh } else { tableFillLow },
|
||||
|
||||
table.header(
|
||||
[*Spannungsfolger*],
|
||||
[*Invertierender Verstärker*],
|
||||
[*Nicht invertierender Verstärker*],
|
||||
[*Ideale Diode*],
|
||||
[*NIK*],
|
||||
[*Gyrator*]),
|
||||
zap.circuit({
|
||||
import zap: *
|
||||
|
||||
set-style(vsource: (radius: 0.3))
|
||||
|
||||
joham.ideal-opamp("O", (2, 0), scale: 0.4, invert: true)
|
||||
|
||||
node("MU", (rel: (0.2, 0), to: "O.out"))
|
||||
cetz.draw.anchor("MM", (rel: (0, -0.65), to: "MU"))
|
||||
node("MB", (2, -1))
|
||||
|
||||
|
||||
node("A", (rel: (-0.7, 0), to: "O.plus"), fill: false)
|
||||
node("C", (rel: (0.7, 0), to: "O.out"), fill: false)
|
||||
node("D", (rel: (0.7, -1), to: "O.out"), fill: false)
|
||||
node("B", ("A", "|-", "MB"), fill: false)
|
||||
|
||||
|
||||
wire("O.ground", "MB")
|
||||
wire("B", "MB")
|
||||
wire("MB", "D")
|
||||
|
||||
wire("A", "O.plus")
|
||||
wire("O.out", "C")
|
||||
|
||||
zwire("O.minus", "MM", ratio: -30%)
|
||||
wire("MM", "MU")
|
||||
|
||||
joham.ground("G1", "MB", scale: 0.7)
|
||||
|
||||
joham.voltage("A", "B", $u_"in"$)
|
||||
joham.voltage("C", "D", anchor: "west", $u_"out"$)
|
||||
}),
|
||||
zap.circuit({
|
||||
import zap: *
|
||||
|
||||
set-style(vsource: (radius: 0.3))
|
||||
|
||||
let height = 2 / 3;
|
||||
|
||||
node("A", (0, height), fill: false)
|
||||
node("B", (0, -height), fill: false)
|
||||
node("C", (3, height), fill: false)
|
||||
node("D", (3, -height), fill: false)
|
||||
|
||||
node("MU", (1.25, height))
|
||||
node("MB", (1.25, -height))
|
||||
|
||||
node("OU", (2.5, height))
|
||||
node("OB", (2, -height))
|
||||
|
||||
joham.ideal-opamp("O", (2, 0), scale: 0.4)
|
||||
|
||||
resistor("R1", "A", "MU", scale: 0.4, label: (content: $R_1$, distance: 3pt), fill: none)
|
||||
wire("B", "MB")
|
||||
|
||||
zwire("MU", "O.minus", ratio: 0%)
|
||||
zwire("MB", "O.plus", ratio: 0%)
|
||||
|
||||
resistor("R0", "MU", "OU", scale: 0.4, label: (content: $R_0$, distance: 3pt))
|
||||
wire("OU", "C")
|
||||
|
||||
wire("O.ground", "OB")
|
||||
wire("MB", "OB")
|
||||
wire("OB", "D")
|
||||
|
||||
zwire("O.out", "OU", ratio: 100%)
|
||||
|
||||
joham.ground("G1", "MB", scale: 0.7)
|
||||
|
||||
joham.voltage("A", "B", $u_"in"$)
|
||||
joham.voltage("C", "D", anchor: "west", $u_"out"$)
|
||||
}),
|
||||
zap.circuit({
|
||||
import zap: *
|
||||
|
||||
set-style(vsource: (radius: 0.3))
|
||||
|
||||
joham.ideal-opamp("O", (2, 0), scale: 0.4, invert: true)
|
||||
|
||||
node("MU", (rel: (0.2, 0), to: "O.out"))
|
||||
node("MM", (rel: (0, -1), to: "MU"))
|
||||
node("MB", (rel: (0, -1), to: "MM"))
|
||||
|
||||
node("A", (rel: (-0.7, 0), to: "O.plus"), fill: false)
|
||||
node("C", (rel: (1, 0), to: "O.out"), fill: false)
|
||||
node("D", (rel: (1, -2), to: "O.out"), fill: false)
|
||||
node("B", ("A", "|-", "MB"), fill: false)
|
||||
|
||||
node("G", (2, -2))
|
||||
|
||||
wire("O.ground", "G")
|
||||
|
||||
resistor("R0", "MU", "MM", scale: 0.4, label: (content: $R_0$, distance: 3pt), fill: none)
|
||||
resistor("R1", "MM", "MB", scale: 0.4, label: (content: $R_1$, distance: 3pt), fill: none)
|
||||
|
||||
wire("MB", "D")
|
||||
|
||||
wire("A", "O.plus")
|
||||
wire("O.out", "C")
|
||||
wire("B", "MB")
|
||||
|
||||
zwire("O.minus", "MM", ratio: -30%)
|
||||
|
||||
joham.ground("G1", "G", scale: 0.7)
|
||||
|
||||
joham.voltage("A", "B", $u_"in"$)
|
||||
joham.voltage("C", "D", anchor: "west", $u_"out"$)
|
||||
}),
|
||||
zap.circuit({
|
||||
import zap: *
|
||||
|
||||
set-style(vsource: (radius: 0.3))
|
||||
|
||||
joham.ideal-opamp("O", (2, 0), scale: 0.4)
|
||||
|
||||
node("G", (2, -0.75))
|
||||
node("MU", (rel: (-0.4, 0), to: "O.minus"))
|
||||
node("MB", ("MU", "|-", "G"))
|
||||
|
||||
node("A", (rel: (-1.2, 0), to: "O.minus"), fill: false)
|
||||
node("B", ("A", "|-", "G"), fill: false)
|
||||
|
||||
joham.diode("D1", (rel: (0, 0.5), to: "MU"), (rel: (1.4, 0)), scale: 0.6, type: "real")
|
||||
|
||||
wire("O.ground", "G")
|
||||
wire("B", "G")
|
||||
|
||||
wire("A", "O.minus")
|
||||
|
||||
zwire("MB", "O.plus", ratio: 0%)
|
||||
|
||||
wire("D1.in", "MU")
|
||||
zwire("D1.out", "O.out", ratio: 0%)
|
||||
|
||||
joham.ground("G1", "G", scale: 0.7)
|
||||
|
||||
joham.voltage("A", "B", $u$)
|
||||
}),
|
||||
zap.circuit({
|
||||
import zap: *
|
||||
|
||||
node("A", (-1.4, 0), fill: false)
|
||||
node("C", (1.4, 0), fill: false)
|
||||
node("B", (-1.4, -1.4), fill: false)
|
||||
node("D", (1.4, -1.4), fill: false)
|
||||
|
||||
node("E", (0.7, -1.4))
|
||||
node("F", (0, 0))
|
||||
|
||||
joham.ideal-opamp("O", (0, -0.6), scale: 0.4, angle: 90deg)
|
||||
|
||||
wire("B", "E")
|
||||
wire("D", "E")
|
||||
|
||||
node("G", (to: "A", rel: (0.4, 0)))
|
||||
node("H", (to: "C", rel: (-0.4, 0)))
|
||||
|
||||
wire("A", "G", i: (content: $i_"in"$, distance: 3pt, scale: 0.7))
|
||||
wire("C", "H")
|
||||
|
||||
resistor("R1", "G", "F", scale: 0.4, label: (content: $R$, anchor: "south", distance: 3pt), fill: none)
|
||||
resistor("R2", "H", "F", scale: 0.4, label: (content: $R$, anchor: "north", distance: 3pt), fill: none)
|
||||
|
||||
zwire("G", "O.minus", ratio: 115%, axis: "y")
|
||||
zwire("H", "O.plus", ratio: 115%, axis: "y")
|
||||
|
||||
wire("O.out", "F")
|
||||
|
||||
zwire("E", "O.ground", ratio: 0%)
|
||||
|
||||
joham.ground("G1", "E", scale: 0.7)
|
||||
|
||||
resistor("R3", (rel: (0.2, 0), to: "C"), (rel: (0.2, 0), to: "D"), scale: 0.4, label: (content: $R_L$, distance: 3pt), fill: none)
|
||||
|
||||
wire("R3.in", "C")
|
||||
wire("R3.out", "D")
|
||||
|
||||
joham.voltage("A", "B", $u_"in"$)
|
||||
}),
|
||||
scale(80%, zap.circuit({
|
||||
import zap: *
|
||||
|
||||
set-style(vsource: (radius: 0.3))
|
||||
|
||||
joham.ideal-opamp("O1", (-1, 0), scale: 0.4, angle: 90deg, invert: true)
|
||||
joham.ideal-opamp("O2", (1, 0), scale: 0.4, angle: 90deg)
|
||||
|
||||
node("MM", (0, -0.6))
|
||||
node("MB", (0, -0.9))
|
||||
node("MBL", (rel: (-0.3, 0), to: "MB"))
|
||||
node("MBR", (rel: (0.3, 0), to: "MB"))
|
||||
node("MU", (0, 1))
|
||||
|
||||
node("RU", (1, 1))
|
||||
node("LU", (-1, 1))
|
||||
|
||||
node("LLU", (rel: (-1, 0), to: "LU"))
|
||||
node("RRU", (rel: (1.3, 0), to: "RU"))
|
||||
|
||||
node("A", (rel: (-0.5, 0), to: "LLU"), fill: false)
|
||||
node("B", ("A", "|-", "MB"), fill: false)
|
||||
|
||||
node("D", (rel: (0.2, 0.4), to: "RU"), fill: false)
|
||||
node("C", (rel: (-0.2, 0.4), to: "RRU"), fill: false)
|
||||
|
||||
resistor("R1", "MU", "LU", scale: 0.4, label: (content: $R$, distance: 3pt, anchor: "south"))
|
||||
resistor("R2", "RU", "MU", scale: 0.4, label: (content: $R$, distance: 3pt, anchor: "south"))
|
||||
|
||||
resistor("R3", "LU", "LLU", scale: 0.4, label: (content: $R$, distance: 3pt, anchor: "south"))
|
||||
|
||||
resistor("R4", (rel: (0.3, 0), to: "RRU"), ((rel: (0.3, 0), to: "RRU"), "|-", "MB"), scale: 0.4, label: (content: $R$, distance: 3pt))
|
||||
|
||||
joham.ground("G", "MB", scale: 0.7)
|
||||
|
||||
wire("O1.out", (rel: (0, 0.2)), (rel: (0, -0.2), to: "RU"), "RU")
|
||||
wire("O2.out", (rel: (0, 0.2)), (rel: (0, -0.2), to: "LU"), "LU")
|
||||
|
||||
wire("MM", "MU")
|
||||
|
||||
zwire("O1.minus", "MM", ratio: 0%)
|
||||
zwire("O2.minus", "MM", ratio: 0%)
|
||||
|
||||
wire("O1.plus", ("O1.plus", "|-", "MM"), ("MM", "-|", "LLU"), "LLU")
|
||||
|
||||
wire("LLU", "A")
|
||||
wire("MBL", "B")
|
||||
|
||||
wire("MBL", "MB")
|
||||
wire("MBR", "MB")
|
||||
|
||||
zwire("O1.ground", "MBL", ratio: 100%)
|
||||
zwire("O2.vcc", "MBR", ratio: 100%)
|
||||
|
||||
wire("O2.plus", ("O2.plus", "|-", "MM"), ("MM", "-|", "RRU"), "RRU")
|
||||
|
||||
wire("R4.in", "RRU")
|
||||
wire("R4.out", "MBR")
|
||||
|
||||
zwire("D", "RU", ratio: 0%)
|
||||
zwire("C", "RRU", ratio: 0%)
|
||||
|
||||
joham.voltage("A", "B", $u_"in"$)
|
||||
joham.voltage("D", "C", anchor: "south", $u_"out"$)
|
||||
})),
|
||||
$u_"out" = u_"in"$,
|
||||
$u_"out" = - R_0/R_1 u_"in"$,
|
||||
$u_"out" = (1 + R_0 / R_1) u_"in"$,
|
||||
$$,
|
||||
$u_"in" = -R_L i_"in"$
|
||||
)
|
||||
430
src/lib/schaltungstheorie/tumCustomSymbols.typ
Normal file
430
src/lib/schaltungstheorie/tumCustomSymbols.typ
Normal file
@@ -0,0 +1,430 @@
|
||||
#import "@preview/zap:0.4.0": * // TODO: Using wrong version, because 5.0.0 breaks custom stuff
|
||||
#import "@preview/cetz:0.4.2": draw
|
||||
#import cetz.draw: *
|
||||
|
||||
#let norator(name, node, scale: 1.0, ..params) = {
|
||||
let custom-style = (
|
||||
width: 1.41 * scale,
|
||||
height: 1.41 * scale
|
||||
)
|
||||
|
||||
let draw(ctx, position, style) = {
|
||||
interface((-custom-style.width / 2, -custom-style.height / 2), (custom-style.width / 2, custom-style.height / 2), io: position.len() < 2)
|
||||
|
||||
merge-path(close: true, {
|
||||
arc((-custom-style.width / 2, 0), radius: custom-style.height / 5, start: 45deg, stop: 315deg, anchor: "arc-center", name: "right-arc")
|
||||
arc((custom-style.width / 2, 0), radius: custom-style.height / 5, start: 135deg, stop: -135deg, anchor: "arc-center", name: "left-arc")
|
||||
})
|
||||
}
|
||||
|
||||
component("norator", name, node, draw: draw, ..params)
|
||||
}
|
||||
|
||||
#let nullator(name, node, scale: 1.0, ..params) = {
|
||||
let custom-style = (
|
||||
width: 1.41 * scale,
|
||||
height: 1.41 * scale
|
||||
)
|
||||
|
||||
let draw(ctx, position, style) = {
|
||||
interface((-custom-style.width / 2, -custom-style.height / 2), (custom-style.width / 2, custom-style.height / 2), io: position.len() < 2)
|
||||
|
||||
circle((0, 0), radius: (custom-style.width / 2, custom-style.height / 6))
|
||||
}
|
||||
|
||||
component("nullator", name, node, draw: draw, ..params)
|
||||
}
|
||||
|
||||
#let diode(name, node, type: none, ..params) = {
|
||||
assert((type in ("ideal", "convex", "concave", "zener", "real") or type == none), message: "type must be ideal, convex, concave, zener, ...")
|
||||
if type == none {
|
||||
type = "ideal"
|
||||
}
|
||||
|
||||
|
||||
let custom-style = (
|
||||
radius: 0.3,
|
||||
width: 0.28,
|
||||
)
|
||||
|
||||
let draw(ctx, position, style) = {
|
||||
translate((-custom-style.radius / 4, 0))
|
||||
interface((-custom-style.radius / 2, -custom-style.radius), (custom-style.radius, custom-style.radius), io: position.len() < 2)
|
||||
|
||||
polygon((0, 0), 3, radius: custom-style.radius, fill: if type in ("real", "zener") { black } else { auto })
|
||||
|
||||
if type == "zener" {
|
||||
merge-path({
|
||||
line((custom-style.radius, custom-style.width), (custom-style.radius, -custom-style.width))
|
||||
line((custom-style.radius, custom-style.width), (custom-style.radius + custom-style.width / 3, custom-style.width))
|
||||
})
|
||||
} else { // ideal, convex, concave
|
||||
line((custom-style.radius, custom-style.width), (custom-style.radius, -custom-style.width))
|
||||
}
|
||||
|
||||
if type == "concave" {
|
||||
arc((-custom-style.radius/10,0), radius: (custom-style.radius / 4, custom-style.radius / 3), start: 90deg, stop: -90deg, anchor: "chord-center")
|
||||
} else if type == "convex" {
|
||||
circle((0, 0), radius: custom-style.radius / 3.5)
|
||||
}
|
||||
}
|
||||
|
||||
component("custom-diode", name, node, draw: draw, ..params)
|
||||
}
|
||||
|
||||
#let inductor(name, node, ..params) = {
|
||||
let custom-style = (
|
||||
width: 1,
|
||||
height: 0.4
|
||||
)
|
||||
|
||||
let draw(ctx, position, style) = {
|
||||
interface((-custom-style.width / 2, -custom-style.height / 2), (custom-style.width / 2, custom-style.height / 2), io: position.len() < 2)
|
||||
|
||||
cetz.decorations.coil(line((-custom-style.width / 2, 0), (custom-style.width / 2, 0)), amplitude: custom-style.width / 3, segments: 5)
|
||||
}
|
||||
|
||||
component("indcutor", name, node, draw: draw, ..params)
|
||||
}
|
||||
|
||||
#let eintor(name, node, ..params) = {
|
||||
let custom-style = (
|
||||
width: 1,
|
||||
height: 0.4
|
||||
)
|
||||
|
||||
let draw(ctx, position, style) = {
|
||||
interface((-custom-style.width / 2, -custom-style.height / 2), (custom-style.width / 2, custom-style.height / 2), io: position.len() < 2)
|
||||
|
||||
rect((-custom-style.width / 2, -custom-style.height / 2), (custom-style.width / 2, custom-style.height / 2), ..style)
|
||||
rect((custom-style.width / 2, -custom-style.height / 2), (custom-style.width / 4, custom-style.height / 2), fill: black, ..style)
|
||||
}
|
||||
|
||||
component("eintor", name, node, draw: draw, ..params)
|
||||
}
|
||||
|
||||
#let controlled-source(name, node, scale: 1.0, type: none, ..params) = {
|
||||
assert((type in ("voltage", "current")), message: "type must be voltage or current, ...")
|
||||
|
||||
let custom-style = (
|
||||
radius: 0.3 * scale,
|
||||
width: 0.28 * scale,
|
||||
)
|
||||
|
||||
let draw(ctx, position, style) = {
|
||||
interface((-custom-style.radius, -custom-style.radius), (custom-style.radius, custom-style.radius), io: position.len() < 2)
|
||||
|
||||
polygon((0, 0), 4, radius: custom-style.radius)
|
||||
|
||||
if type == "voltage" {
|
||||
line((-custom-style.radius, 0), (custom-style.radius, 0))
|
||||
} else {
|
||||
line((0, -custom-style.radius), (0, custom-style.radius))
|
||||
}
|
||||
|
||||
anchor("north", (0, custom-style.radius))
|
||||
anchor("south", (0, -custom-style.radius))
|
||||
}
|
||||
|
||||
component("custom-diode", name, node, draw: draw, ..params)
|
||||
}
|
||||
|
||||
#let empty(name, node, ..params) = {
|
||||
let draw(ctx, position, style) = {
|
||||
interface((-0.5, -0.2), (0.5, 0.2), io: true)
|
||||
}
|
||||
|
||||
component("empty", name, node, draw: draw, ..params)
|
||||
}
|
||||
|
||||
#let blackbox(name, node, mirror: false, label: "", ..params) = {
|
||||
assert(params.pos().len() == 0, message: "blackbox only supports one node")
|
||||
|
||||
let custom-style = (
|
||||
width: 1,
|
||||
height: 1,
|
||||
length: 0.2,
|
||||
)
|
||||
|
||||
let factor = if mirror { -1 } else { 1 }
|
||||
|
||||
let draw(ctx, position, style) = {
|
||||
interface((-custom-style.width / 2, -custom-style.height / 2), (custom-style.width / 2, custom-style.height / 2), io: false)
|
||||
|
||||
rect((-custom-style.width / 2, -custom-style.height / 2), (custom-style.width / 2, custom-style.height / 2), ..style)
|
||||
content((0, 0), label)
|
||||
|
||||
anchor("in", (factor * (custom-style.width / 2 + custom-style.length), custom-style.height / 3))
|
||||
anchor("out", (factor * (custom-style.width / 2 + custom-style.length), -custom-style.height / 3))
|
||||
|
||||
wire("in", (rel: (-factor * custom-style.length, 0)))
|
||||
wire("out", (rel: (-factor * custom-style.length, 0)))
|
||||
}
|
||||
|
||||
component("blackbox", name, node, draw: draw, ..params)
|
||||
}
|
||||
|
||||
#let zweitor(name, node, label: "", ..params) = {
|
||||
assert(params.pos().len() == 0, message: "zweitor only supports one node")
|
||||
// assert(type(label) == content, message: "label has to be content")
|
||||
|
||||
let custom-style = (
|
||||
width: 1,
|
||||
height: 1,
|
||||
length: 0.2,
|
||||
)
|
||||
|
||||
let draw(ctx, position, style) = {
|
||||
interface((-custom-style.width / 2, -custom-style.height / 2), (custom-style.width / 2, custom-style.height / 2), io: false)
|
||||
|
||||
rect((-custom-style.width / 2, -custom-style.height / 2), (custom-style.width / 2, custom-style.height / 2), ..style)
|
||||
content((0, 0), label)
|
||||
|
||||
anchor("11", (-custom-style.width / 2 - custom-style.length, custom-style.height / 3))
|
||||
anchor("12", (-custom-style.width / 2 - custom-style.length, -custom-style.height / 3))
|
||||
anchor("21", (custom-style.width / 2 + custom-style.length, custom-style.height / 3))
|
||||
anchor("22", (custom-style.width / 2 + custom-style.length, -custom-style.height / 3))
|
||||
|
||||
wire("11", (rel: (custom-style.length, 0)))
|
||||
wire("12", (rel: (custom-style.length, 0)))
|
||||
wire("21", (rel: (-custom-style.length, 0)))
|
||||
wire("22", (rel: (-custom-style.length, 0)))
|
||||
}
|
||||
|
||||
component("zweitor", name, node, draw: draw, ..params)
|
||||
}
|
||||
|
||||
#let gyrator(name, node, scale: 1.0, constant: $R_d$, invert: false, ..params) = {
|
||||
assert(params.pos().len() == 0, message: "gyrator only supports one node")
|
||||
|
||||
let custom-style = (
|
||||
width: 5 * scale,
|
||||
height: 5 * scale,
|
||||
length: 0.5 * scale,
|
||||
)
|
||||
|
||||
let draw(ctx, position, style) = {
|
||||
interface((-custom-style.width / 2, -custom-style.height / 2), (custom-style.width / 2, custom-style.height / 2), io: true)
|
||||
|
||||
anchor("11", (-custom-style.width / 2 - custom-style.length, custom-style.height / 3))
|
||||
anchor("12", (-custom-style.width / 2 - custom-style.length, -custom-style.height / 3))
|
||||
anchor("21", (custom-style.width / 2 + custom-style.length, custom-style.height / 3))
|
||||
anchor("22", (custom-style.width / 2 + custom-style.length, -custom-style.height / 3))
|
||||
|
||||
wire("11", (rel: (custom-style.length + custom-style.width / 3, 0)), (to: "12", rel: (custom-style.length + custom-style.width / 3, 0)), "12")
|
||||
wire("21", (rel: (-custom-style.length - custom-style.width / 3, 0)), (to: "22", rel: (-custom-style.length - custom-style.width / 3, 0)), "22")
|
||||
|
||||
arc((-custom-style.width / 6, 0), radius: custom-style.width / 9, start: 90deg, stop: -90deg, anchor: "chord-center")
|
||||
arc((custom-style.width / 6, 0), radius: custom-style.width / 9, start: 90deg, stop: 270deg, anchor: "chord-center")
|
||||
|
||||
line(name: "dual", (to: "11", rel: (custom-style.length + custom-style.width / 3, 0.1)), (to: "21", rel: (-custom-style.length - custom-style.width / 3, 0.1)), mark: (end: if not invert { ">" }, start: if invert { ">" }, scale: 0.7), stroke: 0.5pt, fill: black)
|
||||
content((to: "dual.centroid", rel: (0, 0.1)), constant, anchor: "south")
|
||||
}
|
||||
|
||||
component("gyrator", name, node, draw: draw, ..params)
|
||||
}
|
||||
|
||||
#let nullor(name, node, scale: 1.0, ..params) = {
|
||||
assert(params.pos().len() == 0, message: "nullor only supports one node")
|
||||
|
||||
let custom-style = (
|
||||
width: 5 * scale,
|
||||
height: 5 * scale,
|
||||
length: 0.5 * scale,
|
||||
)
|
||||
|
||||
let draw(ctx, position, style) = {
|
||||
interface((-custom-style.width / 2, -custom-style.height / 2), (custom-style.width / 2, custom-style.height / 2), io: true)
|
||||
|
||||
anchor("11", (-custom-style.width / 2 - custom-style.length, custom-style.height / 3))
|
||||
anchor("12", (-custom-style.width / 2 - custom-style.length, -custom-style.height / 3))
|
||||
anchor("21", (custom-style.width / 2 + custom-style.length, custom-style.height / 3))
|
||||
anchor("22", (custom-style.width / 2 + custom-style.length, -custom-style.height / 3))
|
||||
|
||||
nullator("N1", scale: scale, (to: "11", rel: (custom-style.length + custom-style.width / 3, 0)), (to: "12", rel: (custom-style.length + custom-style.width / 3, 0)))
|
||||
wire("11", "N1.in")
|
||||
wire("12", "N1.out")
|
||||
|
||||
norator("N2", scale: scale, (to: "21", rel: (-custom-style.length - custom-style.width / 3, 0)), (to: "22", rel: (-custom-style.length - custom-style.width / 3, 0)))
|
||||
wire("21", (rel: (-custom-style.length - custom-style.width / 3, 0)))
|
||||
wire("22", (rel: (-custom-style.length - custom-style.width / 3, 0)))
|
||||
}
|
||||
|
||||
component("nullor", name, node, draw: draw, ..params)
|
||||
}
|
||||
|
||||
#let transformer(name, node, scale: 1.0, ..params) = {
|
||||
assert(params.pos().len() == 0, message: "transformer only supports one node")
|
||||
|
||||
let custom-style = (
|
||||
width: 5 * scale,
|
||||
height: 5 * scale,
|
||||
length: 0.5 * scale,
|
||||
)
|
||||
|
||||
let draw(ctx, position, style) = {
|
||||
interface((-custom-style.width / 2, -custom-style.height / 2), (custom-style.width / 2, custom-style.height / 2), io: true)
|
||||
|
||||
anchor("11", (-custom-style.width / 2 - custom-style.length, custom-style.height / 3))
|
||||
anchor("12", (-custom-style.width / 2 - custom-style.length, -custom-style.height / 3))
|
||||
anchor("21", (custom-style.width / 2 + custom-style.length, custom-style.height / 3))
|
||||
anchor("22", (custom-style.width / 2 + custom-style.length, -custom-style.height / 3))
|
||||
|
||||
anchor("C1in", (to: "11", rel: (custom-style.length + custom-style.width / 3, -custom-style.height / 6)))
|
||||
anchor("C1out", (to: "12", rel: (custom-style.length + custom-style.width / 3, custom-style.height / 6)))
|
||||
cetz.decorations.coil(line("C1in", "C1out"), amplitude: custom-style.width / 10, segments: 5)
|
||||
zwire("11", "C1in", ratio: 100%)
|
||||
zwire("12", "C1out", ratio: 100%)
|
||||
|
||||
anchor("C2in", (to: "21", rel: (-custom-style.length - custom-style.width / 3, -custom-style.height / 6)))
|
||||
anchor("C2out", (to: "22", rel: (-custom-style.length - custom-style.width / 3, custom-style.height / 6)))
|
||||
cetz.decorations.coil(line("C2out", "C2in"), amplitude: custom-style.width / 10, segments: 5)
|
||||
zwire("21", "C2in", ratio: 100%)
|
||||
zwire("22", "C2out", ratio: 100%)
|
||||
|
||||
line((custom-style.width * 0.025, -custom-style.height / 5), (custom-style.width * 0.025, custom-style.height / 5))
|
||||
line((-custom-style.width * 0.025, -custom-style.height / 5), (-custom-style.width * 0.025, custom-style.height / 5))
|
||||
|
||||
content((0, custom-style.height / 3), anchor: "south", text(size: 0.75em)[$ü : 1$])
|
||||
}
|
||||
|
||||
component("transformer", name, node, draw: draw, ..params)
|
||||
}
|
||||
|
||||
#let controlled-source(name, node, scale: 1.0, left: "VC", right: "VS", i: none, ..params) = {
|
||||
assert(params.pos().len() == 0, message: "controlled source only supports one node")
|
||||
|
||||
let custom-style = (
|
||||
width: 5 * scale,
|
||||
height: 5 * scale,
|
||||
length: 0.5 * scale,
|
||||
)
|
||||
|
||||
let draw(ctx, position, style) = {
|
||||
interface((-custom-style.width / 2, -custom-style.height / 2), (custom-style.width / 2, custom-style.height / 2), io: true)
|
||||
|
||||
anchor("11", (-custom-style.width / 2 - custom-style.length, custom-style.height / 3))
|
||||
anchor("12", (-custom-style.width / 2 - custom-style.length, -custom-style.height / 3))
|
||||
anchor("21", (custom-style.width / 2 + custom-style.length, custom-style.height / 3))
|
||||
anchor("22", (custom-style.width / 2 + custom-style.length, -custom-style.height / 3))
|
||||
|
||||
if left == "VC" {
|
||||
wire("11", (rel: (custom-style.length + custom-style.width / 3, 0)))
|
||||
wire("12", (to: "12", rel: (custom-style.length + custom-style.width / 3, 0)))
|
||||
} else if left == "CS" {
|
||||
wire("11", (rel: (custom-style.length + custom-style.width / 3, 0)), (to: "12", rel: (custom-style.length + custom-style.width / 3, 0)), "12")
|
||||
} else {
|
||||
assert(false, message: "unknown value for left")
|
||||
}
|
||||
|
||||
if right == "CS" {
|
||||
// isource("source", (rel: (-custom-style.length - custom-style.width / 3, 0), to: "21"), (rel: (-custom-style.length - custom-style.width / 3, 0), to: "22"), scale: scale, dependent: true, i: i)
|
||||
|
||||
anchor("sp", (rel: (-custom-style.length - custom-style.width / 3, 0), to: "21"))
|
||||
anchor("sn", (rel: (-custom-style.length - custom-style.width / 3, 0), to: "22"))
|
||||
} else {
|
||||
assert(false, message: "unknown value for right")
|
||||
}
|
||||
|
||||
wire("21", "sp")
|
||||
wire("22", "sn")
|
||||
|
||||
// arc((-custom-style.width / 6, 0), radius: custom-style.width / 9, start: 90deg, stop: -90deg, anchor: "chord-center")
|
||||
// arc((custom-style.width / 6, 0), radius: custom-style.width / 9, start: 90deg, stop: 270deg, anchor: "chord-center")
|
||||
}
|
||||
|
||||
component("gyrator", name, node, draw: draw, ..params)
|
||||
}
|
||||
|
||||
#let ideal-opamp(name, node, invert: false, scale: 1.0, angle: 0deg, ..params) = {
|
||||
assert(params.pos().len() == 0, message: "opamp supports only one node")
|
||||
|
||||
let custom-style = (
|
||||
width: 1.8 * scale,
|
||||
height: 1.75 * scale,
|
||||
padding: .28 * scale,
|
||||
sign-stroke: .55pt,
|
||||
sign-size: .14 * scale,
|
||||
sign-delta: .45 * scale,
|
||||
)
|
||||
|
||||
let draw(ctx, position, style) = {
|
||||
rotate(angle)
|
||||
|
||||
interface((-custom-style.width / 2, -custom-style.height / 2), (custom-style.width / 2, custom-style.height / 2), io: true)
|
||||
|
||||
let sgn = if invert { -1 } else { 1 }
|
||||
anchor("minus", (-custom-style.width / 2, sgn * custom-style.sign-delta))
|
||||
anchor("plus", (-custom-style.width / 2, -sgn * custom-style.sign-delta))
|
||||
|
||||
scope({
|
||||
translate((-custom-style.width / 6, 0))
|
||||
polygon((0, 0), 3, radius: custom-style.width * 2 / 3, name: "poly")
|
||||
})
|
||||
|
||||
// This is horrendous, don't look at it
|
||||
anchor("ground", ((rel: (0deg, custom-style.width * 2 / 3), to: "poly.default"), 50%, (rel: (-120deg, custom-style.width * 2 / 3), to: "poly.default")))
|
||||
anchor("vcc", ((rel: (0deg, custom-style.width * 2 / 3), to: "poly.default"), 50%, (rel: (120deg, custom-style.width * 2 / 3), to: "poly.default")))
|
||||
|
||||
set-style(stroke: custom-style.sign-stroke)
|
||||
line((rel: (custom-style.padding - custom-style.sign-size, 0), to: "minus"), (rel: (2 * custom-style.sign-size, 0)))
|
||||
line((rel: (custom-style.padding - custom-style.sign-size, 0), to: "plus"), (rel: (2 * custom-style.sign-size, 0)))
|
||||
line((rel: (custom-style.padding, -custom-style.sign-size), to: "plus"), (rel: (0, 2 * custom-style.sign-size)))
|
||||
|
||||
content((custom-style.width / 2, 0), text(size: 12pt * scale)[$ infinity $], anchor: "east", padding: .45 * scale, angle: angle)
|
||||
}
|
||||
|
||||
component("ideal-opamp", name, node, draw: draw, ..params)
|
||||
}
|
||||
|
||||
#let ground(name, node, ..params) = {
|
||||
assert(params.pos().len() == 0, message: "ground supports only one node")
|
||||
|
||||
let custom-style = (
|
||||
width: 0.46,
|
||||
distance: 0.28,
|
||||
)
|
||||
|
||||
let draw(ctx, position, style) = {
|
||||
wire((0, 0), (0, -custom-style.distance))
|
||||
let delta = custom-style.width / 2
|
||||
|
||||
line((-custom-style.width / 2, -custom-style.distance), (custom-style.width / 2, -custom-style.distance))
|
||||
|
||||
interface((-custom-style.width / 2, custom-style.distance), (custom-style.width / 2, -custom-style.distance))
|
||||
anchor("default", (0, 0))
|
||||
}
|
||||
|
||||
component("ground", name, node, draw: draw, ..params)
|
||||
}
|
||||
|
||||
#let offset-line(from, to, dist, func) = {
|
||||
import cetz: vector
|
||||
|
||||
get-ctx(ctx => {
|
||||
let (_, from, to) = cetz.coordinate.resolve(ctx, from, to)
|
||||
|
||||
let line = vector.sub(to, from)
|
||||
|
||||
let normal = (-line.at(1), line.at(0))
|
||||
|
||||
let offset = vector.scale(vector.norm(normal), dist)
|
||||
|
||||
let c = vector.add(from, offset)
|
||||
let d = vector.add(c, line)
|
||||
|
||||
func(c, d)
|
||||
})
|
||||
}
|
||||
|
||||
#let voltage(from, to, distance: 0, anchor: "east", label) = {
|
||||
offset-line(from, to, distance, (from, to) => {
|
||||
line((from, 15%, to), (from, 85%, to), stroke: 0.5pt, mark: (end: (symbol: ">", scale: 0.5, fill: black)), name: "V1")
|
||||
content("V1.centroid", padding: 0.1, anchor: anchor, label)
|
||||
})
|
||||
}
|
||||
|
||||
#let element-voltage(from, to, distance: 0.5, anchor: "east", label) = {
|
||||
voltage(from, to, anchor: anchor, distance: if anchor in ("east", "north") { -distance } else { distance }, label)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user