|
80 | 80 | @inferred Meshes.coordround(p₁, digits=10) |
81 | 81 | end |
82 | 82 |
|
| 83 | +@testitem "pairwiseintersect" setup = [Setup] begin |
| 84 | + # helper to sort points and seginds by point coordinates |
| 85 | + function sortedintersection(segs) |
| 86 | + points, inds = Meshes.pairwiseintersect(segs) |
| 87 | + perm = sortperm(points) |
| 88 | + points[perm], inds[perm] |
| 89 | + end |
| 90 | + |
| 91 | + # simple endpoint case |
| 92 | + segs = Segment.([(cart(0, 0), cart(2, 2)), (cart(0, 2), cart(2, 0)), (cart(0, 1), cart(0.5, 1))]) |
| 93 | + points, seginds = sortedintersection(segs) |
| 94 | + @test length(points) == 1 |
| 95 | + @test length(seginds) == 1 |
| 96 | + |
| 97 | + # small number of segments, handling endpoints and precision |
| 98 | + segs = Segment.([(cart(0, 0), cart(2, 2)), (cart(1.5, 1), cart(2, 1)), (cart(1.51, 1.3), cart(2, 0.9))]) |
| 99 | + points, seginds = sortedintersection(segs) |
| 100 | + @test length(points) == 1 |
| 101 | + |
| 102 | + # box case with one segment outside |
| 103 | + segs = |
| 104 | + Segment.([ |
| 105 | + (cart(0, 0), cart(1.1, 1.1)), |
| 106 | + (cart(1, 0), cart(0, 1)), |
| 107 | + (cart(0, 0), cart(0, 1)), |
| 108 | + (cart(0, 0), cart(1, 0)), |
| 109 | + (cart(0, 1), cart(1, 1)), |
| 110 | + (cart(1, 0), cart(1, 1)) |
| 111 | + ]) |
| 112 | + points, seginds = sortedintersection(segs) |
| 113 | + @test length(points) == 2 |
| 114 | + @test length(seginds) == 2 |
| 115 | + @test Set(seginds[1]) == Set([1, 2]) |
| 116 | + @test Set(seginds[2]) == Set([1, 6, 5]) |
| 117 | + |
| 118 | + # multiple intersections, endpoints as intersections |
| 119 | + if T === Float64 |
| 120 | + segs = |
| 121 | + Segment.([ |
| 122 | + (cart(9, 13), cart(6, 9)), |
| 123 | + (cart(2, 12), cart(9, 4.8)), |
| 124 | + (cart(12, 11), cart(4, 7)), |
| 125 | + (cart(2.5, 10), cart(12.5, 2)), |
| 126 | + (cart(13, 6), cart(10, 4)), |
| 127 | + (cart(10.5, 5.5), cart(9, 1)), |
| 128 | + (cart(10, 4), cart(11, -1)), |
| 129 | + (cart(10, 3), cart(10, 5)) |
| 130 | + ]) |
| 131 | + points, seginds = sortedintersection(segs) |
| 132 | + @test length(points) == 4 |
| 133 | + @test length(seginds) == 4 |
| 134 | + @test points[3] ≈ cart(9, 4.8) |
| 135 | + @test points[4] ≈ cart(10, 4) |
| 136 | + @test Set(seginds[1]) == Set([4, 3]) |
| 137 | + @test Set(seginds[2]) == Set([2, 3]) |
| 138 | + @test Set(seginds[3]) == Set([4, 2]) |
| 139 | + @test Set(seginds[4]) == Set([4, 5, 6, 7, 8]) |
| 140 | + end |
| 141 | + |
| 142 | + # finds all intersections in a grid |
| 143 | + n = 10 |
| 144 | + horizontal = [Segment(cart(1, i), cart(n, i)) for i in 1:n] |
| 145 | + vertical = [Segment(cart(i, 1), cart(i, n)) for i in 1:n] |
| 146 | + segs = [horizontal; vertical] |
| 147 | + points, seginds = sortedintersection(segs) |
| 148 | + @test length(points) == n * n - 4 |
| 149 | + @test length(seginds) == n * n - 4 |
| 150 | + @test all(==(2), length.(seginds)) |
| 151 | + |
| 152 | + # number of intersections is invariant under rotations |
| 153 | + for θ in T(π / 6):T(π / 6):T(2π - π / 6) |
| 154 | + # rotation by π in Float32 is not robust, skips test |
| 155 | + T === Float32 && θ == T(π) && continue |
| 156 | + θpoints, θseginds = sortedintersection(segs |> Rotate(θ)) |
| 157 | + @test length(θpoints) == n * n - 4 |
| 158 | + @test length(θseginds) == n * n - 4 |
| 159 | + @test all(==(2), length.(θseginds)) |
| 160 | + end |
| 161 | + |
| 162 | + # tests coverage for when intervals don't overlap |
| 163 | + segs = [ |
| 164 | + Segment(cart(0, 2), cart(2, 0)), |
| 165 | + Segment(cart(0, 0), cart(2, 2)), |
| 166 | + Segment(cart(3, 1), cart(3, 3)), |
| 167 | + Segment(cart(3, 3), cart(3, 3)) |
| 168 | + ] |
| 169 | + points, seginds = sortedintersection(segs) |
| 170 | + @test length(points) == 1 |
| 171 | + |
| 172 | + # inference test |
| 173 | + segs = facets(cartgrid(10, 10)) |
| 174 | + @inferred (Meshes.pairwiseintersect(segs)) |
| 175 | +end |
| 176 | + |
83 | 177 | @testitem "isthreaded" setup = [Setup] begin |
84 | 178 | if Threads.nthreads() > 1 |
85 | 179 | @test Meshes.isthreaded() |
|
0 commit comments