From f962fd40bdc091ca64d8418d78b871341c671abe Mon Sep 17 00:00:00 2001 From: Johannes Wolf <519002+johannes-wolf@users.noreply.github.com> Date: Thu, 28 Nov 2024 13:21:12 +0100 Subject: [PATCH] intersection: Provide sort functions (#759) --- src/draw/grouping.typ | 13 ++++++++++++- src/lib.typ | 1 + src/sorting.typ | 29 +++++++++++++++++++++++++++++ tests/intersection/ref/1.png | Bin 35405 -> 53375 bytes tests/intersection/test.typ | 25 +++++++++++++++++++++---- 5 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 src/sorting.typ diff --git a/src/draw/grouping.typ b/src/draw/grouping.typ index d3dc791fa..ed6a04606 100644 --- a/src/draw/grouping.typ +++ b/src/draw/grouping.typ @@ -115,7 +115,13 @@ /// - name (str): Name to prepend to the generated anchors. (Not to be confused with other `name` arguments that allow the use of anchor coordinates.) /// - ..elements (elements,str): Elements and/or element names to calculate intersections with. Elements referred to by name are (unlike elements passed) not drawn by the intersections function! /// - samples (int): Number of samples to use for non-linear path segments. A higher sample count can give more precise results but worse performance. -#let intersections(name, ..elements, samples: 10) = { +/// - sort (none,function): A function of the form `(context, array) -> array` +/// that gets called with the list of intersection points. +/// +/// CeTZ provides the following sorting functions: +/// - sorting.points-by-distace(points, reference: (0, 0, 0)) +/// - sorting.points-by-angle(points, reference: (0, 0, 0)) +#let intersections(name, ..elements, samples: 10, sort: none) = { samples = calc.clamp(samples, 2, 2500) assert(type(name) == str and name != "", @@ -169,6 +175,11 @@ } } } + + if sort != none { + pts = (sort)(ctx, pts) + } + let anchors = (:) for (i, pt) in pts.enumerate() { anchors.insert(str(i), pt) diff --git a/src/lib.typ b/src/lib.typ index a471dcd36..7bd907247 100644 --- a/src/lib.typ +++ b/src/lib.typ @@ -15,6 +15,7 @@ #import "path-util.typ" #import "mark.typ" #import "mark-shapes.typ" +#import "sorting.typ" // Libraries #import "lib/palette.typ" diff --git a/src/sorting.typ b/src/sorting.typ new file mode 100644 index 000000000..3778b8c4e --- /dev/null +++ b/src/sorting.typ @@ -0,0 +1,29 @@ +#import "/src/vector.typ" +#import "/src/util.typ" + +/// Sort list of points by distance to a +/// reference point. +/// +/// - points (array): List of points to sort +/// - reference (vec): Reference point +/// -> List of points +#let points-by-distance(ctx, points, reference: (0, 0, 0)) = { + let reference = util.apply-transform(ctx.transform, reference) + return points.sorted(key: pt => { + vector.dist(pt, reference) + }) +} + +/// Sort list of 2D points by angle to a +/// reference 2D point in CCW order. +/// Z component is ignored. +/// +/// - points (array): List of points to sort +/// - reference (vec): Reference point +/// -> List of points +#let points-by-angle(ctx, points, reference: (0, 0, 0)) = { + let (rx, ry, ..) = util.apply-transform(ctx.transform, reference) + return points.sorted(key: ((px, py, ..)) => { + 360deg - calc.atan2(rx - px, ry - py) + }) +} diff --git a/tests/intersection/ref/1.png b/tests/intersection/ref/1.png index 07d005fae0b0459d97201d9296e7e2e46a5b6760..18157bd0459f7c1287e8fa8d002703ac3bdb5d8b 100644 GIT binary patch delta 18481 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 diff --git a/tests/intersection/test.typ b/tests/intersection/test.typ index 2744ba81c..1d36007d3 100644 --- a/tests/intersection/test.typ +++ b/tests/intersection/test.typ @@ -1,5 +1,6 @@ #set page(width: auto, height: auto) #import "/src/lib.typ": * +#import "/tests/helper.typ": * #let test(body) = canvas(length: 1cm, { import draw: * @@ -66,7 +67,7 @@ }) }) -#box(stroke: 2pt + red, canvas({ +#test-case({ import draw: * intersections("i", { @@ -76,9 +77,9 @@ line("a.default", "b.default", stroke: none) }) line("i.0", "i.1", mark: (end: ">")) -})) +}) -#box(stroke: 2pt + red, canvas({ +#test-case({ import draw: * circle((0,0), name: "a") @@ -89,4 +90,20 @@ for-each-anchor("i", (name) => { circle("i."+name, radius: .1, fill: red) }) -})) +}) + +#test-case(fn => { + import draw: * + + let c = circle((1,1), name: "a", radius: 1.25) + let r = rect((0,0), (2,2), name: "b") + intersections("i", r, c, sort: fn) + + for-each-anchor("i", (name) => { + content((), [#name], frame: "circle", fill: white) + }) +}, args: ( + none, + sorting.points-by-angle.with(reference: (1, 1)), + sorting.points-by-distance.with(reference: (0, 0.1)), +))