-
Notifications
You must be signed in to change notification settings - Fork 4
/
circular.jl
103 lines (81 loc) · 2.61 KB
/
circular.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
export CircularAperture,
CircularAnnulus
"""
CircularAperture(x, y, r)
CircularAperture([x, y], r)
A circular aperture.
# Examples
```jldoctest
julia> ap = CircularAperture(0, 0, 10)
CircularAperture(0, 0, r=10)
```
"""
struct CircularAperture{T <: Number} <: AbstractAperture
x::T
y::T
r::T
end
CircularAperture(center::AbstractVector, r) = CircularAperture(center..., r)
CircularAperture(x, y, r) = CircularAperture(promote(x, y, r)...)
function Base.show(io::IO, c::CircularAperture)
print(io, "CircularAperture($(c.x), $(c.y), r=$(c.r))")
end
bbox(c::CircularAperture{<:Integer}) = (c.x - c.r, c.x + c.r, c.y - c.r, c.y + c.r)
function bbox(c::CircularAperture{<:AbstractFloat})
xmin = floor(Int, c.x - c.r + 0.5)
xmax = ceil(Int, c.x + c.r + 0.5)
ymin = floor(Int, c.y - c.r + 0.5)
ymax = ceil(Int, c.y + c.r + 0.5)
return (xmin, xmax, ymin, ymax)
end
function mask(c::CircularAperture; method = :exact)
bounds = edges(c)
box = bbox(c)
ny, nx = size(c)
return circular_overlap(bounds..., nx, ny, c.r, method = method)
end
#######################################################
"""
CircularAnnulus(x, y, r_in, r_out)
CircularAnnulus([x, y], r_in, r_out)
A circular aperture.
# Examples
```jldoctest
julia> ap = CircularAnnulus(0, 0, 5, 10)
CircularAnnulus(0, 0, r_in=5, r_out=10)
```
"""
struct CircularAnnulus{T <: Number} <: AbstractAperture
x::T
y::T
r_in::T
r_out::T
end
CircularAnnulus(center::AbstractVector, r_in, r_out) = CircularAnnulus(center..., r_in, r_out)
CircularAnnulus(x, y, r_in, r_out) = CircularAnnulus(promote(x, y, r_in, r_out)...)
function Base.show(io::IO, c::CircularAnnulus)
print(io, "CircularAnnulus($(c.x), $(c.y), r_in=$(c.r_in), r_out=$(c.r_out))")
end
bbox(c::CircularAnnulus{<:Integer}) = (c.x - c.r_out, c.x + c.r_out, c.y - c.r_out, c.y + c.r_out)
function bbox(c::CircularAnnulus{<:AbstractFloat})
xmin = floor(Int, c.x - c.r_out + 0.5)
xmax = ceil(Int, c.x + c.r_out + 0.5)
ymin = floor(Int, c.y - c.r_out + 0.5)
ymax = ceil(Int, c.y + c.r_out + 0.5)
return (xmin, xmax, ymin, ymax)
end
function mask(c::CircularAnnulus; method = :exact)
bounds = edges(c)
box = bbox(c)
ny, nx = size(c)
out = circular_overlap(bounds..., nx, ny, c.r_out, method = method)
out .-= circular_overlap(bounds..., nx, ny, c.r_in, method = method)
end
function edges(c::Union{CircularAperture,CircularAnnulus})
ibox = bbox(c)
xmin = ibox[1] - c.x - 0.5
xmax = ibox[2] - c.x + 0.5
ymin = ibox[3] - c.y - 0.5
ymax = ibox[4] - c.y + 0.5
return (xmin, xmax, ymin, ymax)
end