Skip to content

Commit 2b62573

Browse files
committed
test the rest of Rect
1 parent 9c97cf9 commit 2b62573

File tree

2 files changed

+92
-32
lines changed

2 files changed

+92
-32
lines changed

src/primitives/rectangles.jl

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,13 @@ RectT{T}(r::GeometryPrimitive{N}) where {N, T} = Rect{N, T}(minimum(r), widths(r
125125
Rect{N}(r::GeometryPrimitive{_N, T}) where {N, _N, T} = Rect{N, T}(minimum(r), widths(r))
126126
Rect{N, T}(r::GeometryPrimitive) where {N, T} = Rect{N, T}(minimum(r), widths(r))
127127

128+
# centered Rects
129+
130+
centered(R::Type{Rect{N,T}}) where {N,T} = R(Vec{N,T}(-0.5), Vec{N,T}(1))
131+
centered(R::Type{RectT{T}}) where {T} = R(Vec{2,T}(-0.5), Vec{2,T}(1))
132+
centered(R::Type{Rect{N}}) where {N} = R(Vec{N,Float32}(-0.5), Vec{N,Float32}(1))
133+
centered(R::Type{Rect}) = R(Vec{2,Float32}(-0.5), Vec{2,Float32}(1))
134+
128135
# TODO These are kinda silly
129136
function Rect2(xy::NamedTuple{(:x, :y)}, wh::NamedTuple{(:width, :height)})
130137
return Rect2(xy.x, xy.y, wh.width, wh.height)
@@ -337,11 +344,11 @@ function Base.intersect(h1::Rect{N}, h2::Rect{N}) where {N}
337344
return Rect{N}(m, mm - m)
338345
end
339346

340-
function update(b::Rect{N,T}, v::Vec{N,T2}) where {N,T,T2}
347+
function update(b::Rect{N,T}, v::VecTypes{N,T2}) where {N,T,T2}
341348
return update(b, Vec{N,T}(v))
342349
end
343350

344-
function update(b::Rect{N,T}, v::Vec{N,T}) where {N,T}
351+
function update(b::Rect{N,T}, v::VecTypes{N,T}) where {N,T}
345352
m = min.(minimum(b), v)
346353
maxi = maximum(b)
347354
mm = if any(isnan, maxi)
@@ -353,11 +360,11 @@ function update(b::Rect{N,T}, v::Vec{N,T}) where {N,T}
353360
end
354361

355362
# Min maximum distance functions between hrectangle and point for a given dimension
356-
function min_dist_dim(rect::Rect{N,T}, p::Vec{N,T}, dim::Int) where {N,T}
363+
function min_dist_dim(rect::Rect{N,T}, p::VecTypes{N,T}, dim::Int) where {N,T}
357364
return max(zero(T), max(minimum(rect)[dim] - p[dim], p[dim] - maximum(rect)[dim]))
358365
end
359366

360-
function max_dist_dim(rect::Rect{N,T}, p::Vec{N,T}, dim::Int) where {N,T}
367+
function max_dist_dim(rect::Rect{N,T}, p::VecTypes{N,T}, dim::Int) where {N,T}
361368
return max(maximum(rect)[dim] - p[dim], p[dim] - minimum(rect)[dim])
362369
end
363370

@@ -373,7 +380,7 @@ function max_dist_dim(rect1::Rect{N,T}, rect2::Rect{N,T}, dim::Int) where {N,T}
373380
end
374381

375382
# Total minimum maximum distance functions
376-
function min_euclideansq(rect::Rect{N,T}, p::Union{Vec{N,T},Rect{N,T}}) where {N,T}
383+
function min_euclideansq(rect::Rect{N,T}, p::Union{VecTypes{N,T},Rect{N,T}}) where {N,T}
377384
minimum_dist = T(0.0)
378385
for dim in 1:length(p)
379386
d = min_dist_dim(rect, p, dim)
@@ -382,7 +389,7 @@ function min_euclideansq(rect::Rect{N,T}, p::Union{Vec{N,T},Rect{N,T}}) where {N
382389
return minimum_dist
383390
end
384391

385-
function max_euclideansq(rect::Rect{N,T}, p::Union{Vec{N,T},Rect{N,T}}) where {N,T}
392+
function max_euclideansq(rect::Rect{N,T}, p::Union{VecTypes{N,T},Rect{N,T}}) where {N,T}
386393
maximum_dist = T(0.0)
387394
for dim in 1:length(p)
388395
d = max_dist_dim(rect, p, dim)
@@ -391,29 +398,29 @@ function max_euclideansq(rect::Rect{N,T}, p::Union{Vec{N,T},Rect{N,T}}) where {N
391398
return maximum_dist
392399
end
393400

394-
function min_euclidean(rect::Rect{N,T}, p::Union{Vec{N,T},Rect{N,T}}) where {N,T}
401+
function min_euclidean(rect::Rect{N,T}, p::Union{VecTypes{N,T},Rect{N,T}}) where {N,T}
395402
return sqrt(min_euclideansq(rect, p))
396403
end
397404

398-
function max_euclidean(rect::Rect{N,T}, p::Union{Vec{N,T},Rect{N,T}}) where {N,T}
405+
function max_euclidean(rect::Rect{N,T}, p::Union{VecTypes{N,T},Rect{N,T}}) where {N,T}
399406
return sqrt(max_euclideansq(rect, p))
400407
end
401408

402409
# Functions that return both minimum and maximum for convenience
403-
function minmax_dist_dim(rect::Rect{N,T}, p::Union{Vec{N,T},Rect{N,T}},
410+
function minmax_dist_dim(rect::Rect{N,T}, p::Union{VecTypes{N,T},Rect{N,T}},
404411
dim::Int) where {N,T}
405412
minimum_d = min_dist_dim(rect, p, dim)
406413
maximum_d = max_dist_dim(rect, p, dim)
407414
return minimum_d, maximum_d
408415
end
409416

410-
function minmax_euclideansq(rect::Rect{N,T}, p::Union{Vec{N,T},Rect{N,T}}) where {N,T}
417+
function minmax_euclideansq(rect::Rect{N,T}, p::Union{VecTypes{N,T},Rect{N,T}}) where {N,T}
411418
minimum_dist = min_euclideansq(rect, p)
412419
maximum_dist = max_euclideansq(rect, p)
413420
return minimum_dist, maximum_dist
414421
end
415422

416-
function minmax_euclidean(rect::Rect{N,T}, p::Union{Vec{N,T},Rect{N,T}}) where {N,T}
423+
function minmax_euclidean(rect::Rect{N,T}, p::Union{VecTypes{N,T},Rect{N,T}}) where {N,T}
417424
minimumsq, maximumsq = minmax_euclideansq(rect, p)
418425
return sqrt(minimumsq), sqrt(maximumsq)
419426
end
@@ -502,10 +509,6 @@ Base.:(==)(b1::Rect, b2::Rect) = minimum(b1) == minimum(b2) && widths(b1) == wid
502509

503510
Base.isequal(b1::Rect, b2::Rect) = b1 == b2
504511

505-
centered(R::Type{Rect{N,T}}) where {N,T} = R(Vec{N,T}(-0.5), Vec{N,T}(1))
506-
centered(R::Type{Rect{N}}) where {N} = R(Vec{N,Float32}(-0.5), Vec{N,Float32}(1))
507-
centered(R::Type{Rect}) = R(Vec{2,Float32}(-0.5), Vec{2,Float32}(1))
508-
509512
##
510513
# Rect2 decomposition
511514

test/geometrytypes.jl

Lines changed: 74 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ end
121121
@test constructor(Vec2(1,2),3,4.0) == expected_rect(constructor, Point(1,2), Vec(3,4.0))
122122
@test constructor((1,2),Point2(3,4)) == expected_rect(constructor, Point(1,2), Vec(3,4))
123123
@test constructor(1.0,2,Vec2(3,4)) == expected_rect(constructor, Point(1,2), Vec(3,4))
124+
@test_throws ArgumentError constructor(1,2,3)
124125
end
125126
end
126127
end
@@ -135,6 +136,7 @@ end
135136
@test constructor(Vec3(1,2,3),4,5,6) == expected_rect(constructor, Point3(1,2,3), Vec(4,5,6))
136137
@test constructor((1,2,3),Point3(4,5,6)) == expected_rect(constructor, Point(1,2,3), Vec(4,5,6))
137138
@test constructor(Vec3(1,2,3),4,5,6) == expected_rect(constructor, Point(1,2,3), Vec(4,5,6))
139+
@test_throws ArgumentError constructor(1,2,3)
138140
end
139141
end
140142
end
@@ -152,6 +154,14 @@ end
152154
@test Rect2(((1, 2), 3, 4)) == Rect2f((1,2), 3, 4)
153155
@test Rect((1, 2, 3, 4)) == Rect2f(1, 2, 3, 4)
154156
@test Rect2((x = 1, y = 2), (width = 3, height = 4)) == Rect2f(1, 2, 3, 4)
157+
158+
for constructor in [Rect, RectT, Rect2, Rect{2}, RectT{Float32},
159+
Rect2f, Rect{2, Float16}, Rect2{Float16}, RectT{Float64, 2}]
160+
@test centered(constructor) == constructor(Point2d(-0.5), Vec2d(1))
161+
end
162+
for constructor in [Rect3, Rect{3}, Rect3d, Rect{3, Float16}, Rect3{Float64}, RectT{Float32, 3}]
163+
@test centered(constructor) == constructor(Point3d(-0.5), Vec3d(1))
164+
end
155165
end
156166

157167
# TODO: test/check for Rect(::GeometryPrimitive) for all primitives
@@ -306,8 +316,17 @@ end
306316
@test widths(split1) == widths(split2)
307317
@test origin(split1) == Vec(0, 0)
308318
@test origin(split2) == Vec(0, 1)
309-
@test in(split1, rect1)
310-
@test !in(rect1, split1)
319+
@test in(split1, rect1) && in(split2, rect1)
320+
@test !(in(rect1, split1) || in(rect1, split2))
321+
322+
rect1 = Rect(Vec(0.0, 0.0, -1.0), Vec(1.0, 2.0, 1.0))
323+
split1, split2 = GeometryBasics.split(rect1, 1, 0.75)
324+
@test widths(split1) == Vec(0.75, 2, 1)
325+
@test widths(split2) == Vec(0.25, 2, 1)
326+
@test origin(split1) == Vec(0, 0, -1)
327+
@test origin(split2) == Vec(0.75, 0, -1)
328+
@test in(split1, rect1) && in(split2, rect1)
329+
@test !(in(rect1, split1) || in(rect1, split2))
311330

312331
prim = Rect(0.0, 0.0, 1.0, 1.0)
313332
@test length(prim) == 2
@@ -338,19 +357,33 @@ end
338357
v = Vec(1.0, 2.0)
339358
@test update(b, v) isa GeometryBasics.HyperRectangle{2,Float64}
340359

341-
p = Vec(5.0, 4.0)
342-
rect = Rect(0.0, 0.0, 1.0, 1.0)
343-
@test min_dist_dim(rect, p, 1) == 4.0
344-
@test min_dist_dim(rect, p, 2) == 3.0
345-
@test max_dist_dim(rect, p, 1) == 5.0
346-
@test max_dist_dim(rect, p, 2) == 4.0
347-
348-
rect1 = Rect(0.0, 0.0, 1.0, 1.0)
349-
rect2 = Rect(3.0, 1.0, 4.0, 2.0)
350-
@test min_dist_dim(rect1, rect2, 1) == 2.0
351-
@test min_dist_dim(rect1, rect2, 2) == 0.0
352-
@test max_dist_dim(rect1, rect2, 1) == 7.0
353-
@test max_dist_dim(rect1, rect2, 2) == 3.0
360+
@testset "euclidean distances" begin
361+
p = Vec(5.0, 4.0)
362+
rect = Rect(0.0, 0.0, 1.0, 1.0)
363+
@test min_dist_dim(rect, p, 1) == 4.0
364+
@test min_dist_dim(rect, p, 2) == 3.0
365+
@test max_dist_dim(rect, p, 1) == 5.0
366+
@test max_dist_dim(rect, p, 2) == 4.0
367+
@test minmax_dist_dim(rect, p, 1) == (4.0, 5.0)
368+
369+
rect1 = Rect(0.0, 0.0, 1.0, 1.0)
370+
rect2 = Rect(3.0, 1.0, 4.0, 2.0)
371+
@test min_dist_dim(rect1, rect2, 1) == 2.0
372+
@test min_dist_dim(rect1, rect2, 2) == 0.0
373+
@test max_dist_dim(rect1, rect2, 1) == 7.0
374+
@test max_dist_dim(rect1, rect2, 2) == 3.0
375+
@test minmax_dist_dim(rect1, rect2, 1) == (2.0, 7.0)
376+
377+
r = Rect2f(-1, -1, 2, 3)
378+
p = Point2f(1, 2) + Point2f(3, 4)
379+
@test min_euclidean(r, p) == 5f0
380+
@test max_euclidean(r, p) sqrt(5*5 + 7*7)
381+
382+
r2 = Rect2f(0, 0, 2, 3)
383+
@test min_euclidean(r, r2) == 0f0
384+
@test max_euclidean(r, r2) == 5f0
385+
@test minmax_euclidean(r, r2) == (0f0, 5f0)
386+
end
354387

355388
@test !before(rect1, rect2)
356389
rect1 = Rect(0.0, 0.0, 1.0, 1.0)
@@ -397,5 +430,29 @@ end
397430
rect2 = Rect(Vec(1, 2, 3, 4), Vec(5, 6, 7, 8))
398431
@test rect1 == rect2
399432

400-
@test_throws ArgumentError Rect(1, 2, 3)
401-
end
433+
@testset "Matrix Multiplications" begin
434+
r = Rect2f(-1, -2, 4, 3)
435+
436+
# TODO: this seems quite dangerous: We pad points with ones which makes
437+
# sense for translations if we go to D+1, but is nonsense if we
438+
# go higher dimensions than that.
439+
M = rand(Mat4f)
440+
ps = Point2f[M * Point(p..., 1, 1) for p in coordinates(r)]
441+
@test Rect2f(ps) == M * r
442+
443+
M = Mat2f(0.5, -0.3, 0.7, 1.5)
444+
ps = Point2f[M * p for p in coordinates(r)]
445+
@test Rect2f(ps) == M * r
446+
447+
r = Rect3f(-1, -2, -3, 2, 4, 1)
448+
M = rand(Mat4f)
449+
ps = Point3f[M * Point(p..., 1) for p in coordinates(r)]
450+
@test Rect3f(ps) == M * r
451+
end
452+
453+
# TODO: this is effectively 0-indexed... should it be?
454+
M = reshape(collect(11:100), 10, 9)[1:9, :]
455+
r = Rect2i(2, 4, 2, 4)
456+
@test M[r] == [53 63 73 83; 54 64 74 84]
457+
458+
end

0 commit comments

Comments
 (0)