Skip to content

Commit 8f5e20a

Browse files
committed
add point_in_tetrahedron routine
1 parent e5b8839 commit 8f5e20a

File tree

1 file changed

+58
-10
lines changed

1 file changed

+58
-10
lines changed

ext/Gmsh_utils.jl

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
module Gmsh_utils
44

5-
using GridapGmsh
5+
using GridapGmsh, StaticArrays
66

77
import GeophysicalModelGenerator: import_Gmsh, FEData
88

9+
910
"""
1011
fe_data, tag_names = import_Gmsh(fname::String)
1112
@@ -16,19 +17,19 @@ function import_Gmsh(fname::String)
1617
mesh = GmshDiscreteModel(fname, renumber=false)
1718

1819
# Extract vertices
19-
nverts = length(mesh.grid.node_coordinates);
20-
dims = length(mesh.grid.node_coordinates[1])
21-
vertices=[mesh.grid.node_coordinates[n][i] for i=1:dims,n=1:nverts]
20+
nverts = length(mesh.grid.node_coordinates);
21+
dims = length(mesh.grid.node_coordinates[1])
22+
vertices = [mesh.grid.node_coordinates[n][i] for i=1:dims,n=1:nverts]
2223

2324
# write coords as 1D double array
24-
nvertices_cell = length(mesh.grid.cell_node_ids[1])
25-
connectivity = [c[i] for i=1:nvertices_cell, c in mesh.grid.cell_node_ids]
25+
nvertices_cell = length(mesh.grid.cell_node_ids[1])
26+
connectivity = [c[i] for i=1:nvertices_cell, c in mesh.grid.cell_node_ids]
2627

27-
28-
regions, tag_names = cell_tags_from_gmsh(mesh) # extract number of each of the tetrahedrons
28+
# extract tag of each of the tetrahedrons
29+
regions, tag_names = cell_tags_from_gmsh(mesh)
2930

30-
cellfields = (regions=regions,)
31-
fields=nothing
31+
cellfields = (regions=regions,)
32+
fields = nothing
3233

3334
return FEData(vertices,connectivity, fields, cellfields), tag_names
3435
end
@@ -63,4 +64,51 @@ function cell_tags_from_gmsh(mesh)
6364
end
6465

6566

67+
68+
69+
70+
"""
71+
inside = point_in_tetrahedron(p::_T, a::_T, b::_T, c::_T, d::_T, tol=1e-10)
72+
Determines if a point `p` is inside a tetrahedron specified by `a`,`b`,`c`,`d` or not
73+
"""
74+
function point_in_tetrahedron(p::_T, a::_T, b::_T, c::_T, d::_T, tol=1e-10) where _T<:Vector{Float64}
75+
76+
# check bounding box
77+
xmin = min(a[1],b[1],c[1],d[1])
78+
xmax = max(a[1],b[1],c[1],d[1])
79+
ymin = min(a[2],b[2],c[2],d[2])
80+
ymax = max(a[2],b[2],c[2],d[2])
81+
zmin = min(a[3],b[3],c[3],d[3])
82+
zmax = max(a[3],b[3],c[3],d[3])
83+
84+
inside = true
85+
if p[1] < xmin || p[1] > xmax
86+
inside = false
87+
end
88+
if (p[2] < ymin || p[2] > ymax) && inside
89+
inside = false
90+
end
91+
if (p[3] < zmin || p[3] > zmax) && inside
92+
inside = false
93+
end
94+
95+
if inside
96+
v0 = @SVector [d[i] - a[i] for i in 1:3]
97+
v1 = @SVector [b[i] - a[i] for i in 1:3]
98+
v2 = @SVector [c[i] - a[i] for i in 1:3]
99+
v3 = @SVector [p[i] - a[i] for i in 1:3]
100+
101+
denom = dot(v0, cross(v1, v2))
102+
103+
u = dot(v3, cross(v1, v2)) / denom
104+
v = dot(v0, cross(v3, v2)) / denom
105+
w = dot(v0, cross(v1, v3)) / denom
106+
107+
inside = (u >= -tol) && (v >= -tol) && (w >= -tol) && (u + v + w <= 1 + tol)
108+
end
109+
110+
return inside
111+
end
112+
113+
66114
end

0 commit comments

Comments
 (0)