Skip to content

Commit

Permalink
add theta
Browse files Browse the repository at this point in the history
  • Loading branch information
LasNikas committed Nov 27, 2023
1 parent fe6eedc commit 4bdd31b
Showing 1 changed file with 20 additions and 10 deletions.
30 changes: 20 additions & 10 deletions src/setups/sphere_shape.jl
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,20 @@ as it will have corners (like a sphere in Minecraft).
struct VoxelSphere end

"""
RoundSphere()
RoundSphere(; theta=2pi)
Construct a sphere by nesting perfectly round concentric spheres.
The resulting ball will be perfectly round, but will not have a regular inner structure.
!!! note "Usage"
See [`SphereShape`](@ref) on how to use this.
"""
struct RoundSphere end
struct RoundSphere
theta::Real
function RoundSphere(; theta=2pi)
new(theta)
end
end

function sphere_shape_coords(::VoxelSphere, particle_spacing, radius, center_position,
n_layers, layer_outwards, tlsph)
Expand Down Expand Up @@ -193,8 +198,9 @@ function sphere_shape_coords(::VoxelSphere, particle_spacing, radius, center_pos
return reinterpret(reshape, ELTYPE, coords)
end

function sphere_shape_coords(::RoundSphere, particle_spacing, radius, center,
function sphere_shape_coords(sphere::RoundSphere, particle_spacing, radius, center,
n_layers, layer_outwards, tlsph)

if n_layers > 0
if layer_outwards
inner_radius = radius
Expand Down Expand Up @@ -227,25 +233,29 @@ function sphere_shape_coords(::RoundSphere, particle_spacing, radius, center,
coords = zeros(length(center), 0)

for layer in 0:(n_layers - 1)
sphere_coords = round_sphere(particle_spacing,
sphere_coords = round_sphere(sphere, particle_spacing,
inner_radius + layer * particle_spacing, center)
coords = hcat(coords, sphere_coords)
end

return coords
end

function round_sphere(particle_spacing, radius, center::SVector{2})
n_particles = round(Int, 2pi * radius / particle_spacing)
function round_sphere(sphere, particle_spacing, radius, center::SVector{2})
n_particles = round(Int, sphere.theta * radius / particle_spacing)

if n_particles <= 2
# 2 or less particles produce weird, asymmetric results.
# Just return one particle at the center.
return collect(reshape(center, (2, 1)))
end

# Remove the last particle at 2pi, which overlaps with the first at 0
t = LinRange(0, 2pi, n_particles + 1)[1:(end - 1)]
if !isapprox(sphere.theta, 2pi)
t = LinRange(0, sphere.theta, n_particles + 1)
else
# Remove the last particle at 2pi, which overlaps with the first at 0
t = LinRange(0, 2pi, n_particles + 1)[1:(end - 1)]
end

particle_coords = Array{Float64, 2}(undef, 2, length(t))

Expand All @@ -256,7 +266,7 @@ function round_sphere(particle_spacing, radius, center::SVector{2})
return particle_coords
end

function round_sphere(particle_spacing, radius, center::SVector{3})
function round_sphere(sphere, particle_spacing, radius, center::SVector{3})
# The number of particles can either be calculated in 2D or in 3D.
# Let δ be the particle spacing and r the sphere radius.
#
Expand Down Expand Up @@ -374,7 +384,7 @@ function round_sphere(particle_spacing, radius, center::SVector{3})
circle_spacing = 1.0
end

circle_coords_2d = round_sphere(circle_spacing, circle_radius,
circle_coords_2d = round_sphere(sphere, circle_spacing, circle_radius,
SVector(center[1], center[2]))
circle_coords_3d = vcat(circle_coords_2d,
center[3] .+ z * ones(1, size(circle_coords_2d, 2)))
Expand Down

0 comments on commit 4bdd31b

Please sign in to comment.