Added a lot of shit
All checks were successful
Build Typst PDFs (Docker) / build-typst (push) Successful in 19s

This commit is contained in:
alexander
2026-01-30 21:47:21 +01:00
parent 5a8d8dff75
commit d113b66dcd
5 changed files with 475 additions and 57 deletions

View File

@@ -3,16 +3,6 @@
#import zap: interface
#let registerAllCustom() = {
cetz.draw.set-ctx(ctx => {
ctx.zap.style.insert("einTor", (
scale: auto,
fill: auto,
height: 3mm,
width: 6mm,
))
ctx
})
cetz.draw.set-ctx(ctx => {
ctx.zap.style.insert("zweiTor", (
scale: auto,
@@ -20,8 +10,39 @@
height: 10mm,
width: 10mm,
))
ctx.zap.style.insert("einTor", (
scale: auto,
fill: auto,
height: 3mm,
width: 6mm,
))
ctx.zap.style.insert("fet", (
scale: auto,
fill: none,
height: 5mm,
width: 10mm,
))
for it in ("lnot", "land", "lnand", "lor", "lnor", "lxor", "lxnor") {
ctx.zap.style.insert(it, (
width: 0.7,
min-height: 0.9,
spacing: 0.4,
padding: 0.25,
fill: white,
stroke: auto,
)
)
}
ctx
})
}
#let einTor(name, node, flip: false, ..params) = {
@@ -83,4 +104,53 @@
// Component call
component("zweiTor", name, node, draw: draw, ..params)
}
#let fet(name, node, type: "N", scale: 1, angle: 0, thickness: 0.5pt, ..params) = {
import cetz.draw: line, circle, anchor, rotate
import zap: component
// Drawing function
let draw(ctx, position, style) = {
let zap-style = ctx.zap.style
let height = style.height * scale;
let width = style.width * scale;
let wireThink = ctx.zap.style.wire.stroke.thickness;
rotate(angle);
if(type == "N") {
line((0, height), (0, height*(1-0.45)), stroke: (thickness: wireThink))
} else {
line((0, height), (0, height*(1-0.2)), stroke: (thickness: wireThink))
circle((0, height*(1-0.3) - thickness/2), radius: (height/2)*0.2, stroke: (thickness: wireThink))
}
line(
(width/2, 0),
(width*0.4/2, 0),
(width*0.4/2, 0),
(width*0.4/2, height*(1-0.6)),
(-width*0.4/2, height*(1-0.6)),
(-width*0.4/2, 0),
(-width/2, 0), stroke: (thickness: wireThink)
)
line(
(width*0.42/2, height*(1-0.45)),
(-width*0.42/2, height*(1-0.45)),
stroke: (thickness: wireThink)
)
anchor("G", (0, height))
anchor("D", (-width/2, 0))
anchor("S", (width/2, 0))
interface((-width / 2, -height / 2), (width / 2, height / 2), io: true)
}
// Component call
component("fet", name, node, draw: draw, ..params)
}

62
src/lib/logic.typ Normal file
View File

@@ -0,0 +1,62 @@
#import "@preview/zap:0.5.0": *
#import "@preview/cetz:0.4.2": (
draw.anchor, draw.arc-through, draw.circle, draw.content, draw.line, draw.rect, draw.rotate, draw.get-ctx, draw.bezier
)
#let logic(name, node, text: $"&"$, invert: false, mirror: false, invert-inputs: (), angle: 0deg, inputs: 2, ..params) = {
assert(inputs >= 1, message: "logic supports minimum one inputs")
let style = (
width: 0.7,
min-height: 0.9,
spacing: 0.4,
padding: 0.25,
fill: white,
stroke: auto,
)
// Drawing function
let draw(ctx, position, _) = {
rotate(angle)
let height = calc.max(style.min-height, (inputs - 1) * style.spacing + 2 * style.padding)
let width = style.width * if mirror { -1 } else { 1 }
interface((-width / 2, -height / 2), (width / 2, height / 2), io: false)
rect((-width / 2, -height / 2), (rel: (width, height)), fill: style.fill, stroke: style.stroke)
content((0, height / 2 - style.padding / 2), text, anchor: "north", angle: angle)
let ball-radius = calc.min(height, width) * 0.1
for input in range(1, inputs + 1) {
let pad = (height - (inputs - 1) * style.spacing) / 2
let y = height / 2 - pad - (input - 1) * style.spacing;
if input in invert-inputs {
circle((-width / 2 - ball-radius, y), radius: ball-radius, stroke: style.stroke, fill: style.fill)
anchor("in" + str(input), (-width / 2, y))
} else {
anchor("in" + str(input), (-width / 2, y))
}
}
if invert {
circle((width / 2 + ball-radius, 0), radius: ball-radius, stroke: style.stroke, fill: style.fill)
anchor("out", (width / 2, 0))
} else {
anchor("out", (width / 2, 0))
}
}
// Component call
component("logic", name, node, draw: draw, ..params)
}
#let lnot(name, node, ..params) = logic(name, node, ..params, text: $1$, invert: true)
#let land(name, node, ..params) = logic(name, node, ..params, text: $"&"$)
#let lnand(name, node, ..params) = logic(name, node, ..params, text: $"&"$, invert: true)
#let lor(name, node, ..params) = logic(name, node, ..params, text: $>=1$)
#let lnor(name, node, ..params) = logic(name, node, ..params, text: $>=1$, invert: true)
#let lxor(name, node, ..params) = logic(name, node, ..params, text: $=1$)
#let lxnor(name, node, ..params) = logic(name, node, ..params, text: $=1$, invert: true)

80
src/lib/table.typ Normal file
View File

@@ -0,0 +1,80 @@
#import "@preview/zap:0.5.0"
#import "logic.typ"
#let circuit(body) = zap.circuit({
import zap: *
set-style(
node: (
radius: 0.04,
)
)
body
})
#table(
columns: (1fr, 1fr),
align: center + horizon,
stroke: (x, y) => (
left: if x > 0 { 0.5pt },
top: if y == 1 { 1pt } else if y > 0 { 0.5pt },
),
table.header([DNF], [KNF]),
circuit({
import zap: *
logic.land("A1", (0, 0.75), invert-inputs: (1,))
logic.land("A2", (0, -0.75), invert-inputs: (2,))
logic.lor("O1", (1.25, 0))
zwire("A1.out", "O1.in1", ratio: 50%)
zwire("A2.out", "O1.in2", ratio: 50%)
wire((-1, 1.25), (-1, -1.25), name: "A")
wire((-0.75, 1.25), (-0.75, -1.25), name: "B")
cetz.draw.content("A.in", [a], anchor: "south", padding: 2pt)
cetz.draw.content("B.in", [b], anchor: "south", padding: 2pt)
node("N4", ("A1.in1", "-|", "A.in"))
wire("A1.in1", "N4")
node("N3", ("A1.in2", "-|", "B.in"))
wire("A1.in2", "N3")
node("N2", ("A2.in1", "-|", "A.in"))
wire("A2.in1", "N2")
node("N1", ("A2.in2", "-|", "B.in"))
wire("A2.in2", "N1")
wire("O1.out", (rel: (0.3, 0)))
}),
circuit({
import zap: *
logic.lor("A1", (0, 0.75))
logic.lor("A2", (0, -0.75), invert-inputs: (1,2))
logic.land("O1", (1.25, 0))
zwire("A1.out", "O1.in1", ratio: 50%)
zwire("A2.out", "O1.in2", ratio: 50%)
wire((-1, 1.25), (-1, -1.25), name: "A")
wire((-0.75, 1.25), (-0.75, -1.25), name: "B")
cetz.draw.content("A.in", [a], anchor: "south", padding: 2pt)
cetz.draw.content("B.in", [b], anchor: "south", padding: 2pt)
node("N4", ("A1.in1", "-|", "A.in"))
wire("A1.in1", "N4")
node("N3", ("A1.in2", "-|", "B.in"))
wire("A1.in2", "N3")
node("N2", ("A2.in1", "-|", "A.in"))
wire("A2.in1", "N2")
node("N1", ("A2.in2", "-|", "B.in"))
wire("A2.in2", "N1")
wire("O1.out", (rel: (0.3, 0)))
})
)

35
src/lib/truthtable.typ Normal file
View File

@@ -0,0 +1,35 @@
#let truth-table(outputs: (), inputs: none) = {
let variables = calc.max(..outputs.map(output => calc.ceil(calc.log(output.at(1).len()) / calc.log(2))))
if inputs == none {
inputs = ($a$, $b$, $c$, $d$).slice(0, variables)
}
assert(outputs.len() >= 1, message: "There has to be at least one output")
assert(inputs.len() == variables, message: "There aren't enough variables to label")
let num-to-bin(x, digits) = {
let bits = ()
while x != 0 {
bits.push(calc.rem(x, 2))
x = calc.floor(x / 2)
}
range(digits).map(x => bits.at(digits - x - 1, default: 0))
}
table(
columns: (auto,) * (variables + outputs.len()),
stroke: (x, y) => (
left: if x == variables { 1pt } else if x > 0 { 0.5pt },
top: if y == 1 { 1pt } else if y > 0 { 0.5pt },
),
inset: 4pt,
if inputs != none { table.header(..inputs.map(x => [#x]), ..outputs.map(((x, _)) => [#x])) },
..range(calc.pow(2, variables))
.map(x => (..num-to-bin(x, variables).map(y => [#y]), ..outputs.map(((_, y)) => [#y.at(x, default: [])])))
.flatten()
)
}