Normals per vertex: the faces' around it, weighted by their areas.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | v(:,:) |
(3, n) vertices |
||
| integer, | intent(in) | :: | tri(:,:) |
(3, m) triangles, vertex numbers (1-based) |
pure function vertex_normals(v, tri) result(normals) real(wp), intent(in) :: v(:,:) !! (3, n) vertices integer, intent(in) :: tri(:,:) !! (3, m) triangles, vertex numbers (1-based) real(wp) :: normals(3, size(v, 2)), f(3), len_ integer :: k, i normals = 0.0_wp do k = 1, size(tri, 2) f = cross(v(:, tri(2, k)) - v(:, tri(1, k)), v(:, tri(3, k)) - v(:, tri(1, k))) ! (twice the area) do i = 1, 3 normals(:, tri(i, k)) = normals(:, tri(i, k)) + f end do end do do i = 1, size(v, 2) len_ = norm2(normals(:, i)) if (len_ > 0.0_wp) then normals(:, i) = normals(:, i) / len_ else normals(:, i) = [0.0_wp, 0.0_wp, 1.0_wp] end if end do end function vertex_normals