Skip to content

Commit 89b9921

Browse files
committed
refactor boundingboxes, add tests
1 parent 744c51b commit 89b9921

File tree

3 files changed

+56
-29
lines changed

3 files changed

+56
-29
lines changed

src/boundingboxes.jl

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,40 @@
1-
function Rect(geometry::AbstractArray{<:Point{N,T}}) where {N,T}
2-
return Rect{N,T}(geometry)
1+
# Boundingbox-like Rect constructors
2+
3+
Rect(p::AbstractGeometry{N, T}) where {N, T} = Rect{N, T}(p)
4+
RectT{T}(p::AbstractGeometry{N}) where {N, T} = Rect{N, T}(p)
5+
Rect{N}(p::AbstractGeometry{_N, T}) where {N, _N, T} = Rect{N, T}(p)
6+
7+
Rect(p::AbstractArray{<: VecTypes{N, T}}) where {N, T} = Rect{N, T}(p)
8+
RectT{T}(p::AbstractArray{<: VecTypes{N}}) where {N, T} = Rect{N, T}(p)
9+
Rect{N}(p::AbstractArray{<: VecTypes{_N, T}}) where {N, _N, T} = Rect{N, T}(p)
10+
11+
# compat: bounding boxes also defined Rect{T} constructors
12+
# This is not really compatible with Rect{N}...
13+
# How do you even deprecate this?
14+
# @deprecate Rect{T}(x::AbstractGeometry) where {T <: Number} RectT{T}(x) where {T}
15+
# @deprecate Rect{T}(x::AbstractArray) where {T <: Number} RectT{T}(x) where {T}
16+
17+
# Implementations
18+
# Specialize fully typed Rect constructors
19+
Rect{N, T}(p::AbstractGeometry) where {N, T} = Rect{N, T}(coordinates(p))
20+
21+
function bbox_dim_check(trg, src::Integer)
22+
@assert trg isa Integer "Rect{$trg, $T1} is invalid. This may have happened due to calling Rect{$N1}(obj) to get a bounding box."
23+
if trg < src
24+
throw(ArgumentError("Cannot construct a $trg dimensional bounding box from $src dimensional Points. ($trg must be ≥ $src)"))
25+
end
326
end
427

528
"""
6-
Rect(points::AbstractArray{<: Point})
29+
Rect(points::AbstractArray{<: VecTypes})
730
831
Construct a bounding box containing all the given points.
932
"""
10-
function Rect{N1,T1}(geometry::AbstractArray{PT}) where {N1,T1,PT<:Point}
11-
N2, T2 = length(PT), eltype(PT)
12-
@assert N1 >= N2
33+
function Rect{N1, T1}(points::AbstractArray{<: VecTypes{N2, T2}}) where {N1, T1, N2, T2}
34+
bbox_dim_check(N1, N2)
1335
vmin = Point{N2,T2}(typemax(T2))
1436
vmax = Point{N2,T2}(typemin(T2))
15-
for p in geometry
37+
for p in points
1638
vmin, vmax = _minmax(p, vmin, vmax)
1739
end
1840
o = vmin
@@ -25,29 +47,25 @@ function Rect{N1,T1}(geometry::AbstractArray{PT}) where {N1,T1,PT<:Point}
2547
end
2648
end
2749

50+
2851
"""
2952
Rect(primitive::GeometryPrimitive)
3053
3154
Construct a bounding box for the given primitive.
3255
"""
33-
function Rect(primitive::GeometryPrimitive{N,T}) where {N,T}
34-
return Rect{N,T}(primitive)
35-
end
36-
37-
function Rect{T}(primitive::GeometryPrimitive{N,T}) where {N,T}
38-
return Rect{N,T}(primitive)
39-
end
40-
41-
function Rect{T}(a::Pyramid) where {T}
42-
w, h = a.width / T(2), a.length
56+
function Rect{N, T}(a::Pyramid) where {N, T}
57+
bbox_dim_check(N, 3)
58+
w, h = a.width, a.length
4359
m = Vec{3,T}(a.middle)
44-
return Rect{T}(m .- Vec{3,T}(w, w, 0), m .+ Vec{3,T}(w, w, h))
60+
return Rect{N, T}(m .- Vec{3,T}(w / T(2), w / T(2), 0), Vec{3,T}(w, w, h))
4561
end
4662

47-
function Rect{T}(a::Sphere) where {T}
63+
function Rect{N, T}(a::HyperSphere) where {N, T}
4864
mini, maxi = extrema(a)
49-
return Rect{T}(mini, maxi .- mini)
65+
return Rect{N, T}(mini, maxi .- mini)
5066
end
5167

52-
Rect{T}(a) where {T} = Rect{T}(coordinates(a))
53-
Rect{N,T}(a) where {N,T} = Rect{N,T}(coordinates(a))
68+
# TODO: exact implementation that doesn't rely on coordinates
69+
# function Rect{N, T}(a::Cylinder) where {N, T}
70+
# return Rect{N, T}(...)
71+
# end

src/primitives/rectangles.jl

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,6 @@ Rect{3, T}(o::VecTypes{2}, w::VecTypes{3}) where {T} = Rect{3, T}(Vec(o..., 0),
118118
Rect{3, T}(o::VecTypes{3}, w::VecTypes{2}) where {T} = Rect{3, T}(o, Vec(w..., 0))
119119
Rect{3, T}(o::VecTypes{2}, w::VecTypes{2}) where {T} = Rect{3, T}(Vec(o..., 0), Vec(w..., 0))
120120

121-
# Boundingbox-like constructors
122-
123-
# Rect(r::GeometryPrimitive{N, T}) where {N, T} = Rect{N, T}(minimum(r), widths(r)) # in boundingboxes.jl
124-
RectT{T}(r::GeometryPrimitive{N}) where {N, T} = Rect{N, T}(minimum(r), widths(r))
125-
Rect{N}(r::GeometryPrimitive{_N, T}) where {N, _N, T} = Rect{N, T}(minimum(r), widths(r))
126-
Rect{N, T}(r::GeometryPrimitive) where {N, T} = Rect{N, T}(minimum(r), widths(r))
127-
128121
# centered Rects
129122

130123
centered(R::Type{Rect{N,T}}) where {N,T} = R(Vec{N,T}(-0.5), Vec{N,T}(1))

test/geometrytypes.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,22 @@ end
165165
end
166166

167167
# TODO: test/check for Rect(::GeometryPrimitive) for all primitives
168+
@testset "Boundingbox-like" begin
169+
for constructor in [Rect, Rect{2}, Rect{2, Float32}, Rect3f]
170+
@test constructor(Circle(Point2f(0), 1f0)) == constructor(Point2f(-1, -1), Vec2f(2, 2))
171+
@test constructor(Rect2f(0, 0, 1, 1)) == constructor(Point2f( 0, 0), Vec2f(1, 1))
172+
m = GeometryBasics.mesh(Tessellation(Circle(Point2f(0), 1f0), 5))
173+
@test constructor(m) constructor(Point2f(-1, -1), Vec2f(2, 2))
174+
end
175+
for constructor in [Rect, Rect{3}, Rect{3, Float32}]
176+
@test constructor(Sphere(Point3f(0), 1f0)) == Rect3f(-1, -1, -1, 2, 2, 2)
177+
@test constructor(Rect3f(0, 0, 0, 1, 1, 1)) == Rect3f(0, 0, 0, 1, 1, 1)
178+
@test constructor(Cylinder(Point3f(0, 0, -1), Point3f(0,0,1), 1f0)) Rect3f(-1, -1, -1, 2, 2, 2) atol = 0.05
179+
@test constructor(Pyramid(Point3f(0, 0, -1), 2f0, 2f0)) == Rect3f(-1, -1, -1, 2, 2, 2)
180+
m = GeometryBasics.mesh(Tessellation(Sphere(Point3f(0), 1f0), 5))
181+
@test constructor(m) Rect3f(-1, -1, -1, 2, 2, 2)
182+
end
183+
end
168184
end
169185

170186
# TODO: origin, minimum, maximum, width, height, widths, area, volume with empty constructed Rects

0 commit comments

Comments
 (0)