Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/canvas.typ
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
transform:
((1, 0,-.5, 0),
(0,-1,+.5, 0),
(0, 0, .0, 0),
(0, 0, 0, 0), // FIXME: This should not be zero for Z! Changing it destroys mark & decorations in 3D space.
(0, 0, .0, 1)),
// Nodes, stores anchors and paths
nodes: (:),
Expand Down
2 changes: 1 addition & 1 deletion src/coordinate.typ
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
// dictionary of numbers
return vector.scale(
c.bary.pairs().fold(
vector.new(3),
(0, 0, 0),
(vec, (k, v)) => {
vector.add(
vec,
Expand Down
22 changes: 12 additions & 10 deletions src/matrix.typ
Original file line number Diff line number Diff line change
Expand Up @@ -248,15 +248,17 @@
/// -> vector
#let mul4x4-vec3(mat, vec, w: 1) = {
assert(vec.len() <= 4)
let out = (0, 0, 0)
for m in range(0, 3) {
let v = (mat.at(m).at(0) * vec.at(0, default: 0)
+ mat.at(m).at(1) * vec.at(1, default: 0)
+ mat.at(m).at(2) * vec.at(2, default: 0)
+ mat.at(m).at(3) * vec.at(3, default: w))
out.at(m) = v
}
return out

let x = vec.at(0)
let y = vec.at(1)
let z = vec.at(2, default: 0)
let w = vec.at(3, default: w)

let ((a1,a2,a3,a4), (b1,b2,b3,b4), (c1,c2,c3,c4), _) = mat
return (
a1 * x + a2 * y + a3 * z + a4 * w,
b1 * x + b2 * y + b3 * z + b4 * w,
c1 * x + c2 * y + c3 * z + c4 * w)
}

// Multiply matrix with vector
Expand Down Expand Up @@ -319,7 +321,7 @@
return inverted
}

/// Swaps the ath column with the bth column.
/// Swaps the a-th column with the b-th column.
///
/// - mat (matrix): Matrix
/// - a (int): The index of column a.
Expand Down
64 changes: 20 additions & 44 deletions src/vector.typ
Original file line number Diff line number Diff line change
@@ -1,25 +1,3 @@
/// Returns a new vector of dimension `dim` with all fields set to `init` (defaults to 0).
///
/// - dim (int): Vector dimension
/// - init (float): Initial value of all fields
/// -> vector
#let new(dim, init: 0) = {
return range(0, dim).map(x => init)
}

/// Returns the dimension of a vector.
///
/// - v (vector): The vector to find the dimension of.
/// -> int
#let dim(v) = {
assert(
type(v) == array,
message: "Expected vector to be of array type, got: " + repr(v)
)
return v.len()
}


/// Converts a vector to a row or column matrix.
///
/// - v (vector): The vector to convert.
Expand All @@ -35,13 +13,13 @@
}
}

/// Ensures a vector has an exact dimension. This is done by passing another vector `init` that has the required dimension. If the original vector does not have enough dimensions, the values from `init` will be inserted. It is recommended to use a zero vector for `init`.
/// Ensures a vector has an exact number of components. This is done by passing another vector `init` that has the required dimension. If the original vector does not have enough dimensions, the values from `init` will be inserted. It is recommended to use a zero vector for `init`.
///
/// - v (vector): The vector to ensure.
/// - init (vector): The vector to check the dimension against.
/// -> vector
#let as-vec(v, init: (0, 0, 0)) = {
for i in range(0, calc.min(dim(v), dim(init))) {
for i in range(0, calc.min(v.len(), init.len())) {
init.at(i) = v.at(i)
}
return init
Expand All @@ -62,12 +40,9 @@
/// - v2 (vector): The vector on the right hand side.
/// -> vector
#let add(v1, v2) = {
if dim(v1) != dim(v2) {
v1 = as-vec(v1)
v2 = as-vec(v2)
}
assert(dim(v1) == dim(v2), message: "Cannot add vectors, " + repr(v1) + " and " + repr(v2) + " are not of the same dimensions.")
return v1.zip(v2).map(((a, b)) => a + b)
range(0, calc.max(v1.len(), v2.len())).map(i => {
v1.at(i, default: 0) + v2.at(i, default: 0)
})
}

/// Subtracts two vectors of the same dimension
Expand All @@ -76,12 +51,9 @@
/// - v2 (vector): The vector on the right hand side.
/// -> vector
#let sub(v1, v2) = {
if dim(v1) != dim(v2) {
v1 = as-vec(v1)
v2 = as-vec(v2)
}
assert(dim(v1) == dim(v2), message: "Cannot subtract vectors, " + repr(v1) + " and " + repr(v2) + " are not of the same dimensions.")
return v1.zip(v2).map(((a, b)) => a - b)
range(0, calc.max(v1.len(), v2.len())).map(i => {
v1.at(i, default: 0) - v2.at(i, default: 0)
})
}

/// Calculates the distance between two vectors by subtracting the length of vector `a` from vector `b`.
Expand Down Expand Up @@ -122,7 +94,7 @@
/// - v2 (vector): The vector on the right hand side.
/// -> float
#let dot(v1, v2) = {
assert(dim(v1) == dim(v2))
assert(v1.len() == v2.len())
return v1.enumerate().fold(0, (s, t) => s + t.at(1) * v2.at(t.at(0)))
}

Expand All @@ -131,11 +103,14 @@
/// - v2 (vector): The vector on the right hand side.
/// -> vector
#let cross(v1, v2) = {
assert(dim(v1) == 3 and dim(v2) == 3)
let x = v1.at(1) * v2.at(2) - v1.at(2) * v2.at(1)
let y = v1.at(2) * v2.at(0) - v1.at(0) * v2.at(2)
let z = v1.at(0) * v2.at(1) - v1.at(1) * v2.at(0)
return (x, y, z)
assert(v1.len() == 3 and v2.len() == 3)

let (x1, y1, z1) = v1
let (x2, y2, z2) = v2

return (y1 * z2 - z1 * y2,
z1 * x2 - x1 * z2,
x1 * y2 - y1 * x2)
}

/// Calculates the angle between two vectors and the x-axis in 2d space
Expand All @@ -152,8 +127,9 @@
/// - c (vector): The vector to measure the angle at.
/// - v2 (vector): The vector to measure the angle to.
#let angle(v1, c, v2) = {
assert(dim(v1) == dim(v2), message: "Vectors " + repr(v1) + " and " + repr(v2) + " do not have the same dimensions.")
if dim(v1) == 2 or dim(v1) == 3 {
assert(v1.len() == v2.len(),
message: "Vectors " + repr(v1) + " and " + repr(v2) + " do not have the same dimensions.")
if v1.len() == 2 or v1.len() == 3 {
v1 = sub(v1, c)
v2 = sub(v2, c)
return calc.acos(dot(norm(v1), norm(v2)))
Expand Down
2 changes: 1 addition & 1 deletion tests/transform-precission/test.typ
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
set-ctx(ctx => {
ctx.transform = ((calc.cos(th), -calc.sin(th), 0, 0),
(-calc.sin(th), -calc.cos(th), 0, 0),
(0, 0, 0, 0),
(0, 0, 1, 0),
(0, 0, 0, 1),)
return ctx
})
Expand Down
Loading