@@ -140,19 +140,19 @@ function collect_with_eltype!(result::AbstractVector{T}, iter) where {T}
140140end
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
158158end
@@ -177,8 +177,8 @@ orthogonal_vector(vertices) = orthogonal_vector(Vec3f, vertices)
177177Compute vertex normals from the given `positions` and `faces`.
178178
179179This 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
182182normalized again to produce a vertex normal.
183183"""
184184function normals (vertices:: AbstractVector{Point{3,T}} , faces:: AbstractVector{F} ;
@@ -188,10 +188,10 @@ end
188188
189189function 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
211211appropriate `FaceView`.
212212"""
213213function 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)
217217end
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
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)
0 commit comments