Added a lot of shit
All checks were successful
Build Typst PDFs (Docker) / build-typst (push) Successful in 19s
All checks were successful
Build Typst PDFs (Docker) / build-typst (push) Successful in 19s
This commit is contained in:
@@ -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
62
src/lib/logic.typ
Normal 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
80
src/lib/table.typ
Normal 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
35
src/lib/truthtable.typ
Normal 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()
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user