Skip to content

Commit 3361076

Browse files
authored
Add 3D capability to earcut_triangulate
This method assumes two things: - The first three points in the polygon are not NaN - The first three points in the polygon are all different - The polygon lies in a single plane, that can be described by its first three points
1 parent 159f118 commit 3361076

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

src/triangulation.jl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,33 @@ function earcut_triangulate(polygon::Vector{Vector{Point{2,Int32}}})
208208
return unsafe_wrap(Vector{GLTriangleFace}, array[1], array[2]; own=true)
209209
end
210210

211+
function earcut_triangulate(polygon::Vector{Vector{Point{3, <: Real}}})
212+
# Here, we are assuming that the polygon is actually planar,
213+
# but the plane is in 3D, and not necessarily the XY plane.
214+
# So, we can find the plane of best fit using the first three points of the polygon!
215+
p1, p2, p3 = polygon[1][1], polygon[1][2], polygon[1][3]
216+
# First, we subtract the points to get two co-planar vectors.
217+
v1 = p2 - p1
218+
v2 = p3 - p1
219+
# The normal vector is the cross product of these vectors.
220+
normal = cross(v1, v2)
221+
# Then, the x component of the plane is the first coplanar vector,
222+
x = v1
223+
# and the y component of the plane is the second coplanar vector.
224+
y = cross(normal, x)
225+
226+
# We project every point in the polygon,
227+
projected_polygon = map(
228+
ring -> map(p -> Point2{Float64}(dot(p, x), dot(p, y)), ring),
229+
polygon
230+
)
231+
232+
# and then call earcut on the new, 2D polygon.
233+
# This only returns a vector of faces, so we don't care about
234+
# the actual points.
235+
return earcut_triangulate(projected_polygon)
236+
end
237+
211238
best_earcut_eltype(x) = Float64
212239
best_earcut_eltype(::Type{Float64}) = Float64
213240
best_earcut_eltype(::Type{<:AbstractFloat}) = Float32

0 commit comments

Comments
 (0)