-
Notifications
You must be signed in to change notification settings - Fork 89
/
Copy pathregular.jl
92 lines (73 loc) · 3.34 KB
/
regular.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
# ------------------------------------------------------------------
# Licensed under the MIT License. See LICENSE in the project root.
# ------------------------------------------------------------------
"""
RegularSampling(n1, n2, ..., np)
Generate samples regularly using `n1` points along the first
parametric dimension, `n2` points along the second parametric
dimension, ..., `np` points along the last parametric dimension.
## Examples
Sample sphere regularly with 360 longitudes and 180 latitudes:
```julia
sample(Sphere((0,0,0), 1), RegularSampling(360, 180))
```
"""
struct RegularSampling{N} <: ContinuousSamplingMethod
sizes::Dims{N}
end
RegularSampling(sizes::Vararg{Int,N}) where {N} = RegularSampling(sizes)
function sample(::AbstractRNG, geom::Geometry, method::RegularSampling)
T = numtype(lentype(geom))
D = paramdim(geom)
sz = fitdims(method.sizes, D)
δₛ = firstoffset(geom)
δₑ = lastoffset(geom)
tₛ = ntuple(i -> T(0 + δₛ[i](sz[i])), D)
tₑ = ntuple(i -> T(1 - δₑ[i](sz[i])), D)
rs = (range(tₛ[i], stop=tₑ[i], length=sz[i]) for i in 1:D)
iᵣ = (geom(uv...) for uv in Iterators.product(rs...))
iₚ = (p for p in extrapoints(geom, sz))
Iterators.flatmap(identity, (iᵣ, iₚ))
end
firstoffset(g::Geometry) = _firstoffset(g, Val(embeddim(g)))
lastoffset(g::Geometry) = _lastoffset(g, Val(embeddim(g)))
extrapoints(g::Geometry, sz) = _extrapoints(g, Val(embeddim(g)), sz)
_firstoffset(g::Geometry, ::Val) = ntuple(i -> (n -> zero(n)), paramdim(g))
_lastoffset(g::Geometry, ::Val) = ntuple(i -> (n -> isperiodic(g)[i] ? inv(n) : zero(n)), paramdim(g))
_extrapoints(::Geometry, ::Val, sz) = ()
firstoffset(d::Disk) = (n -> inv(n), firstoffset(boundary(d))...)
lastoffset(d::Disk) = (n -> zero(n), lastoffset(boundary(d))...)
extrapoints(d::Disk, sz) = (center(d),)
firstoffset(b::Ball) = (n -> inv(n), firstoffset(boundary(b))...)
lastoffset(b::Ball) = (n -> zero(n), lastoffset(boundary(b))...)
extrapoints(b::Ball, sz) = (center(b),)
_firstoffset(::Sphere, ::Val{3}) = (n -> inv(n + 1), n -> zero(n))
_lastoffset(::Sphere, ::Val{3}) = (n -> inv(n + 1), n -> inv(n))
_extrapoints(s::Sphere, ::Val{3}, sz) = (s(0, 0), s(1, 0))
firstoffset(::Ellipsoid) = (n -> inv(n + 1), n -> zero(n))
lastoffset(::Ellipsoid) = (n -> inv(n + 1), n -> inv(n))
extrapoints(e::Ellipsoid, sz) = (e(0, 0), e(1, 0))
firstoffset(::Cylinder) = (n -> inv(n), n -> zero(n), n -> zero(n))
lastoffset(::Cylinder) = (n -> zero(n), n -> inv(n), n -> zero(n))
function extrapoints(c::Cylinder, sz)
T = numtype(lentype(c))
b = bottom(c)(0, 0)
t = top(c)(0, 0)
s = Segment(b, t)
[s(t) for t in range(zero(T), one(T), sz[3])]
end
firstoffset(::CylinderSurface) = (n -> zero(n), n -> zero(n))
lastoffset(::CylinderSurface) = (n -> inv(n), n -> zero(n))
extrapoints(c::CylinderSurface, sz) = (bottom(c)(0, 0), top(c)(0, 0))
firstoffset(::ConeSurface) = (n -> zero(n), n -> zero(n))
lastoffset(::ConeSurface) = (n -> inv(n), n -> inv(n))
extrapoints(c::ConeSurface, sz) = (base(c)(0, 0), apex(c))
firstoffset(::FrustumSurface) = (n -> zero(n), n -> zero(n))
lastoffset(::FrustumSurface) = (n -> inv(n), n -> zero(n))
extrapoints(c::FrustumSurface, sz) = (bottom(c)(0, 0), top(c)(0, 0))
# --------------
# SPECIAL CASES
# --------------
function sample(rng::AbstractRNG, grid::OrthoRegularGrid, method::RegularSampling)
sample(rng, boundingbox(grid), method)
end