Skip to content

Instantly share code, notes, and snippets.

@asinghvi17
Created October 17, 2024 17:08
Show Gist options
  • Save asinghvi17/4163c63e2c525bd5f2d0f3b34d085524 to your computer and use it in GitHub Desktop.
Save asinghvi17/4163c63e2c525bd5f2d0f3b34d085524 to your computer and use it in GitHub Desktop.
An icosphere refinement algorithm that skips triangles. It's a bug (but looks super cool!)
using GeometryBasics, LinearAlgebra
function add_vertex!(vertex_list, vertex)
push!(vertex_list, LinearAlgebra.normalize(vertex))
return length(vertex_list)
end
function get_middle_point!(vertex_list, midpoint_cache, p1::Int, p2::Int)
first_is_smaller = p1 < p2
smaller_index = first_is_smaller ? p1 : p2
larger_index = first_is_smaller ? p2 : p1
key = smaller_index << 32 + larger_index
if haskey(midpoint_cache, key)
return midpoint_cache[key]
else
midpoint = @. (vertex_list[p1] + vertex_list[p2]) / 2
midpoint_idx = add_vertex!(vertex_list, midpoint)
midpoint_cache[key] = midpoint_idx
return midpoint_idx
end
end
function refined_faces!(face, vertex_list, midpoint_cache)
p1, p2, p3 = face
p12 = get_middle_point!(vertex_list, midpoint_cache, p1, p2)
p13 = get_middle_point!(vertex_list, midpoint_cache, p1, p3)
p23 = get_middle_point!(vertex_list, midpoint_cache, p2, p3)
return (
TriangleFace{Int}(p1, p12, p13),
TriangleFace{Int}(p2, p23, p12),
TriangleFace{Int}(p3, p13, p23),
)
end
function icosphere(n_refinements::Int = 2)
ϕ = (1+√5)/2
vertices = LinearAlgebra.normalize.(Point3{Float64}[
(-1, ϕ, 0),
( 1, ϕ, 0),
(-1, -ϕ, 0),
( 1, -ϕ, 0),
(0, -1, ϕ),
(0, 1, ϕ),
(0, -1, -ϕ),
(0, 1, -ϕ),
( ϕ, 0, -1),
( ϕ, 0, 1),
( -ϕ, 0, -1),
( -ϕ, 0, 1),
])
faces = TriangleFace{Int}.([(1, 12, 6),
(1, 6, 2),
(1, 2, 8),
(1, 8, 11),
(1, 11, 12),
(2, 6, 10),
(6, 12, 5),
(12, 11, 3),
(11, 8, 7),
(8, 2, 9),
(4, 10, 5),
(4, 5, 3),
(4, 3, 7),
(4, 7, 9),
(4, 9, 10),
(6, 5, 10),
(3, 5, 12),
(7, 3, 11),
(9, 7, 8),
(10, 9, 2),
])
midpoint_cache = Dict{Int, Int}()
for _ in 1:n_refinements
new_faces = TriangleFace{Int}[]
for face in faces
append!(new_faces, refined_faces!(face, vertices, midpoint_cache))
end
faces = new_faces
end
return vertices, faces
end
# To plot,
f, a, p = wireframe(GeometryBasics.Mesh(icosphere(6)...))
mp = mesh!(Sphere(Point3f(0), 0.95); color = :white)
f
@asinghvi17
Copy link
Author

Screenshot 2024-10-17 at 10 06 26 AM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment