95 lines
1.9 KiB
Typst
95 lines
1.9 KiB
Typst
#let is-vec(vec) = {
|
|
if type(vec) != dictionary {return false}
|
|
if vec.at("type", default: none) != "vector" {return false}
|
|
return true
|
|
}
|
|
|
|
#let _check(vec) = {
|
|
if not is-vec(vec) {
|
|
panic("Argument is not a vector")
|
|
}
|
|
}
|
|
|
|
#let vec(..args) = {
|
|
let comps = args.pos()
|
|
let size = comps.len()
|
|
return (
|
|
type: "vector",
|
|
comps: comps,
|
|
size: size
|
|
)
|
|
}
|
|
|
|
#let copy(vec) = {
|
|
_check(vec)
|
|
return vec(..vec.comps)
|
|
}
|
|
|
|
#let of-size(size) = {
|
|
let comps = (0,) * size
|
|
return vec(..comps)
|
|
}
|
|
|
|
#let display(vec) = {
|
|
_check(vec)
|
|
math.vec(..vec.comps.map(c => [#c]))
|
|
}
|
|
|
|
#let add(vec1, vec2) = {
|
|
_check(vec1)
|
|
_check(vec2)
|
|
if vec1.size != vec2.size {
|
|
panic("Can't add vectors of size " + str(vec1.size) + " and " + str(vec2.size))
|
|
}
|
|
|
|
let comps = vec1.comps.zip(vec2.comps).map(p => p.sum())
|
|
return vec(..comps)
|
|
}
|
|
|
|
#let sub(vec1, vec2) = {
|
|
_check(vec1)
|
|
_check(vec2)
|
|
if vec1.size != vec2.size {
|
|
panic("Can't subtract vectors of size " + str(vec1.size) + " and " + str(vec2.size))
|
|
}
|
|
|
|
let comps = vec1.comps.zip(vec2.comps).map(p => p.first() - p.last())
|
|
return vec(..comps)
|
|
}
|
|
|
|
#let dot(vec1, vec2) = {
|
|
_check(vec1)
|
|
_check(vec2)
|
|
if vec1.size != vec2.size {
|
|
panic("Can't compute dot product of vectors of size " + str(vec1.size) + " and " + str(vec2.size))
|
|
}
|
|
|
|
let res = vec1.comps.zip(vec2.comps)
|
|
.map(p => p.product())
|
|
.sum(default: 0)
|
|
|
|
return res
|
|
}
|
|
|
|
#let cross(vec1, vec2) = {
|
|
_check(vec1)
|
|
_check(vec2)
|
|
if vec1.size != 3 or vec2.size != 3 {
|
|
panic("Can only compute cross product of vectors of size 3")
|
|
}
|
|
|
|
let vec3 = of-size(3)
|
|
for i in range(3) {
|
|
let i1 = calc.rem(i + 1, 3)
|
|
let i2 = calc.rem(i1 + 1, 3)
|
|
vec3.comps.at(i) = vec1.comps.at(i1) * vec2.comps.at(i2)
|
|
vec3.comps.at(i) -= vec1.comps.at(i2) * vec2.comps.at(i1)
|
|
}
|
|
return vec3
|
|
}
|
|
|
|
#let to-mat(vec) = {
|
|
_check(vec)
|
|
import "mat.typ" as _mat
|
|
return _mat.mat(..vec.comps.map(c => (c,)))
|
|
} |