Skip to content

Commit

Permalink
Fixups
Browse files Browse the repository at this point in the history
  • Loading branch information
johannes-wolf committed Dec 6, 2023
1 parent fced1b5 commit ae8dccd
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 44 deletions.
13 changes: 1 addition & 12 deletions src/anchor.typ
Original file line number Diff line number Diff line change
Expand Up @@ -110,22 +110,11 @@
}
pts += intersection.line-path(..test-line, drawable)
}
assert(pts.len() > 0, message: strfmt("{} {} {}", test-line, drawables, angle))

if pts.len() == 1 {
return pts.first()
}

// Find the furthest intersection point from center
let pt = pts.first()
let d = vector.dist(center, pts.first())
for i in range(1, pts.len()) {
let nd = vector.dist(center, pts.at(i))
if nd > d {
d = nd
pt = pts.at(i)
}
}

return pt
return util.sort-points-by-distance(center, pts).last()
}
42 changes: 10 additions & 32 deletions src/draw/shapes.typ
Original file line number Diff line number Diff line change
Expand Up @@ -600,9 +600,7 @@
let element-line-intersection(ctx, elem, a, b) = {
// Vectors a and b are not transformed yet, but the vectors of the
// drawable are.
let (ta, tb) = (a, b).map(v => {
matrix.mul-vec(ctx.transform, vector.as-vec(v, init: (0,0,0,1)))
})
let (ta, tb) = util.apply-transform(ctx.transform, a, b)

let pts = ()
for drawable in elem.at("drawables", default: ()) {
Expand All @@ -611,19 +609,11 @@
return if pts == () {
a
} else {
let pt = pts.at(0)
let d = vector.dist(pt, b)
for i in range(1, pts.len()) {
let nd = vector.dist(pts.at(i), b)
if nd < d {
pt = pts.at(i)
d = nd
}
}
// Find the nearest point
let pt = util.sort-points-by-distance(b, pts).first()

// Reverse the transformation
return matrix.mul-vec(matrix.inverse(ctx.transform),
vector.as-vec(pt, init: (0,0,0,1))).slice(0, 3)
return util.revert-transform(ctx.transform, pt)
}
}

Expand All @@ -636,28 +626,16 @@

let (ctx, ..pts) = coordinate.resolve(ctx, ..pts)

// If the first element, test for intersection
// of that element and a line from the two first coordinates of this
// If the first/last element, test for intersection
// of that element and a line from the two first/last coordinates of this
// line strip.
pts.first() = if first-is-elem {
if first-is-elem {
let elem = ctx.nodes.at(first-elem)

let (a, b) = pts.slice(0, 2)
element-line-intersection(ctx, elem, a, b)
} else {
pts.first()
pts.first() = element-line-intersection(ctx, elem, ..pts.slice(0, 2))
}

// If the last coordinate is an element, test for intersection
// of that element and a line from the two last coordinates of this
// line strip.
pts.last() = if last-is-elem {
if last-is-elem {
let elem = ctx.nodes.at(last-elem)

let (a, b) = pts.slice(-2)
element-line-intersection(ctx, elem, a, b)
} else {
pts.last()
pts.last() = element-line-intersection(ctx, elem, ..pts.slice(-2))
}

let style = styles.resolve(ctx.style, merge: style, root: "line")
Expand Down
18 changes: 18 additions & 0 deletions src/util.typ
Original file line number Diff line number Diff line change
Expand Up @@ -308,3 +308,21 @@
south-east: se,
)
}

/// Sort list of points/vectors by distance to base
/// - base (vector): Vector to meassure distance to
/// - pts (array of vector): List of points
/// -> array Sorted list of points
#let sort-points-by-distance(base, pts) = {
if pts.len() == 1 {
return pts
}

// Sort by transforming points into tuples of (point, distance),
// sorting them by key 1 and then transforming them back to points.
return pts.map(p => {
return (p, vector.dist(p, base))
})
.sorted(key: t => t.at(1))
.map(t => t.at(0))
}

0 comments on commit ae8dccd

Please sign in to comment.