Created
October 17, 2024 17:08
-
-
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!)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Author
asinghvi17
commented
Oct 17, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment