-
-
Notifications
You must be signed in to change notification settings - Fork 54
/
spheres.jl
74 lines (59 loc) · 2.19 KB
/
spheres.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
"""
HyperSphere{N, T}
A `HyperSphere` is a generalization of a sphere into N-dimensions.
A `center` and radius, `r`, must be specified.
"""
struct HyperSphere{N,T} <: GeometryPrimitive{N,T}
center::Point{N,T}
r::T
end
"""
Circle{T}
An alias for a HyperSphere of dimension 2. (i.e. `HyperSphere{2, T}`)
"""
const Circle{T} = HyperSphere{2,T}
"""
Sphere{T}
An alias for a HyperSphere of dimension 3. (i.e. `HyperSphere{3, T}`)
"""
const Sphere{T} = HyperSphere{3,T}
HyperSphere{N}(p::Point{N,T}, number) where {N,T} = HyperSphere{N,T}(p, convert(T, number))
widths(c::HyperSphere{N,T}) where {N,T} = Vec{N,T}(radius(c) * 2)
radius(c::HyperSphere) = c.r
origin(c::HyperSphere) = c.center
Base.minimum(c::HyperSphere{N,T}) where {N,T} = Vec{N,T}(origin(c)) - Vec{N,T}(radius(c))
Base.maximum(c::HyperSphere{N,T}) where {N,T} = Vec{N,T}(origin(c)) + Vec{N,T}(radius(c))
function Base.in(x::AbstractPoint{2}, c::Circle)
@inbounds ox, oy = origin(c)
xD = abs(ox - x)
yD = abs(oy - y)
return xD <= c.r && yD <= c.r
end
centered(S::Type{HyperSphere{N,T}}) where {N,T} = S(Vec{N,T}(0), T(0.5))
function centered(::Type{T}) where {T<:HyperSphere}
return centered(HyperSphere{ndims_or(T, 3),eltype_or(T, Float32)})
end
function coordinates(s::Circle, nvertices=64)
rad = radius(s)
inner(fi) = Point(rad * sin(fi + pi), rad * cos(fi + pi)) .+ origin(s)
return (inner(fi) for fi in LinRange(0, 2pi, nvertices))
end
function texturecoordinates(s::Circle, nvertices=64)
return coordinates(Circle(Point2f0(0.5), 0.5f0), nvertices)
end
function coordinates(s::Sphere, nvertices=24)
θ = LinRange(0, pi, nvertices)
φ = LinRange(0, 2pi, nvertices)
inner(θ, φ) = Point(cos(φ) * sin(θ), sin(φ) * sin(θ), cos(θ)) .* s.r .+ s.center
return ivec((inner(θ, φ) for θ in θ, φ in φ))
end
function texturecoordinates(s::Sphere, nvertices=24)
ux = LinRange(0, 1, nvertices)
return ivec(((φ, θ) for θ in reverse(ux), φ in ux))
end
function faces(sphere::Sphere, nvertices=24)
return faces(Rect(0, 0, 1, 1), (nvertices, nvertices))
end
function normals(s::Sphere{T}, nvertices=24) where {T}
return coordinates(Sphere(Point{3,T}(0), 1), nvertices)
end