Skip to content

Commit e4b25ed

Browse files
committed
move coordinates into orthogonal_vector and always return a vector
1 parent 992314e commit e4b25ed

File tree

3 files changed

+28
-28
lines changed

3 files changed

+28
-28
lines changed

src/geometry_primitives.jl

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -140,19 +140,19 @@ function collect_with_eltype!(result::AbstractVector{T}, iter) where {T}
140140
end
141141

142142
"""
143-
orthogonal_vector(vertices)
143+
orthogonal_vector([target_type = Vec3f], points)
144144
145-
Calculates an orthogonal vector to a face or polygon defined by a set of
146-
ordered points contained in the point vector `vertices`. Note that for 2D points
147-
a scalar is returned (the dot product of the orthogonal vector with the
148-
positive Z-direction).
145+
Calculates an orthogonal vector to a polygon defined by a vector of ordered
146+
`points`. Note that the orthogonal vector to a collection of 2D points needs to
147+
expand to 3D space.
149148
"""
150-
function orthogonal_vector(::Type{VT},vertices) where VT
151-
c = zeros(VT) # Inherit vector type from input
152-
j = length(vertices)
153-
@inbounds for i in eachindex(vertices) # Use shoelace approach
154-
c += cross(vertices[j],vertices[i]) # Add each edge contribution
155-
j = i
149+
function orthogonal_vector(::Type{VT}, vertices) where {VT <: VecTypes{3}}
150+
c = zeros(VT) # Inherit vector type from input
151+
prev = to_ndim(VT, last(coordinates(vertices)), 0)
152+
@inbounds for p in coordinates(vertices) # Use shoelace approach
153+
v = to_ndim(VT, p, 0)
154+
c += cross(prev, v) # Add each edge contribution
155+
prev = v
156156
end
157157
return c
158158
end
@@ -177,8 +177,8 @@ orthogonal_vector(vertices) = orthogonal_vector(Vec3f, vertices)
177177
Compute vertex normals from the given `positions` and `faces`.
178178
179179
This runs through all faces, computing a face normal each and adding it to every
180-
involved vertex. The direction of the face normal is based on winding direction
181-
and assumed counter-clockwise faces. At the end the summed face normals are
180+
involved vertex. The direction of the face normal is based on winding direction
181+
and assumed counter-clockwise faces. At the end the summed face normals are
182182
normalized again to produce a vertex normal.
183183
"""
184184
function normals(vertices::AbstractVector{Point{3,T}}, faces::AbstractVector{F};
@@ -188,10 +188,10 @@ end
188188

189189
function normals(vertices::AbstractVector{<:Point{3}}, faces::AbstractVector{<: NgonFace},
190190
::Type{NormalType}) where {NormalType}
191-
191+
192192
normals_result = zeros(NormalType, length(vertices))
193193
for face in faces
194-
v = coordinates(vertices[face])
194+
v = vertices[face]
195195
# we can get away with two edges since faces are planar.
196196
n = orthogonal_vector(NormalType, v)
197197
for i in 1:length(face)
@@ -211,15 +211,15 @@ Compute face normals from the given `positions` and `faces` and returns an
211211
appropriate `FaceView`.
212212
"""
213213
function face_normals(
214-
positions::AbstractVector{<:Point3{T}}, fs::AbstractVector{<: AbstractFace};
214+
positions::AbstractVector{<:Point3{T}}, fs::AbstractVector{<: AbstractFace};
215215
normaltype = Vec3{T}) where {T}
216216
return face_normals(positions, fs, normaltype)
217217
end
218-
218+
219219
@generated function face_normals(positions::AbstractVector{<:Point3}, fs::AbstractVector{F},
220220
::Type{NormalType}) where {F<:NgonFace,NormalType}
221-
222-
# If the facetype is not concrete it likely varies and we need to query it
221+
222+
# If the facetype is not concrete it likely varies and we need to query it
223223
# doing the iteration
224224
FT = ifelse(isconcretetype(F), :($F), :(typeof(f)))
225225

@@ -228,7 +228,7 @@ end
228228
faces = resize!(F[], length(fs))
229229

230230
for (i, f) in enumerate(fs)
231-
ps = coordinates(positions[f])
231+
ps = positions[f]
232232
n = orthogonal_vector(NormalType, ps)
233233
normals[i] = normalize(n)
234234
faces[i] = $(FT)(i)

src/meshes.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,9 @@ end
213213
Calculate the signed volume of one tetrahedron. Be sure the orientation of your
214214
surface is right.
215215
"""
216-
function volume(triangle::Triangle)
217-
sig = sign(orthogonal_vector(triangle.points) v1)
216+
function volume(triangle::Triangle{3, T}) where {T}
217+
v1, v2, v3 = triangle
218+
sig = sign(orthogonal_vector(Vec3{T}, triangle) v1)
218219
return sig * abs(v1 (v2 × v3)) / 6
219220
end
220221

src/triangulation.jl

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
1717
1818
Calculate the area of one face.
1919
"""
20-
function area(vertices::AbstractVector{<:Point},
21-
face::NgonFace)
20+
function area(vertices::AbstractVector{<:Point}, face::NgonFace)
2221
return 0.5 * norm(orthogonal_vector(vertices[face]))
2322
end
2423

@@ -27,8 +26,7 @@ end
2726
2827
Calculate the area of all faces.
2928
"""
30-
function area(vertices::AbstractVector{<:Point},
31-
faces::AbstractVector{<:NgonFace})
29+
function area(vertices::AbstractVector{<:Point}, faces::AbstractVector{<:NgonFace})
3230
return sum(x -> area(vertices, x), faces)
3331
end
3432

@@ -41,11 +39,12 @@ For 2D points, the oriented area is returned (negative when the points are
4139
oriented clockwise).
4240
"""
4341
function area(vertices::AbstractVector{Point{2,T}}) where {T}
44-
length(vertices) < 3 && return zero(T)
45-
return T(0.5) * orthogonal_vector(vertices)
42+
length(vertices) < 3 && return zero(T)
43+
return T(0.5) * orthogonal_vector(vertices)[3]
4644
end
4745

4846
function area(vertices::AbstractVector{Point{3,T}}) where {T}
47+
length(vertices) < 3 && return zero(T)
4948
return T(0.5) * norm(orthogonal_vector(vertices))
5049
end
5150

0 commit comments

Comments
 (0)