Skip to content

Commit 3071dbd

Browse files
Fixed concave shapes
1 parent 040884d commit 3071dbd

1 file changed

Lines changed: 47 additions & 21 deletions

File tree

src/common/m_model.fpp

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -846,8 +846,8 @@ contains
846846
real(wp) :: dist_min, dist_proj, dist_v, dist_e, t
847847
real(wp) :: v1(1:3), v2(1:3), v3(1:3)
848848
real(wp) :: e0(1:3), e1(1:3), pv(1:3)
849-
real(wp) :: n(1:3), proj(1:3)
850-
real(wp) :: d, ndot, denom
849+
real(wp) :: n(1:3), proj(1:3), normals(1:3), norm_vec(1:3)
850+
real(wp) :: d, ndot, denom, norm_mag
851851
real(wp) :: u, v_bary, w
852852
real(wp) :: l00, l01, l11, l20, l21
853853
real(wp) :: edge(1:3), pe(1:3)
@@ -897,8 +897,8 @@ contains
897897
! If projection is inside triangle
898898
if (u >= 0._wp .and. v_bary >= 0._wp .and. w >= 0._wp) then
899899
dist_proj = sqrt((point(1) - proj(1))**2 + &
900-
(point(2) - proj(2))**2 + &
901-
(point(3) - proj(3))**2)
900+
(point(2) - proj(2))**2 + &
901+
(point(3) - proj(3))**2)
902902

903903
if (dist_proj < dist_min) then
904904
dist_min = dist_proj
@@ -925,20 +925,35 @@ contains
925925

926926
if (dist_e < dist_min) then
927927
dist_min = dist_e
928-
normals(:) = n(:)
928+
norm_vec(:) = point(:) - verts(:, j)
929+
norm_mag = sqrt(dot_product(norm_vec, norm_vec))
930+
if (norm_mag > 0._wp) norm_vec = norm_vec / norm_mag
931+
normals(:) = norm_vec(:)
932+
end if
933+
else if (t < 0._wp) then
934+
dist_v = sqrt((point(1) - verts(1, j))**2 + &
935+
(point(2) - verts(2, j))**2 + &
936+
(point(3) - verts(3, j))**2)
937+
938+
if (dist_v < dist_min) then
939+
dist_min = dist_v
940+
norm_vec(:) = point(:) - verts(:, j)
941+
norm_mag = sqrt(dot_product(norm_vec, norm_vec))
942+
if (norm_mag > 0._wp) norm_vec = norm_vec / norm_mag
943+
normals(:) = norm_vec(:)
944+
end if
945+
else
946+
dist_v = sqrt((point(1) - verts(1, mod(j, 3) + 1))**2 + &
947+
(point(2) - verts(2, mod(j, 3) + 1))**2 + &
948+
(point(3) - verts(3, mod(j, 3) + 1))**2)
949+
950+
if (dist_v < dist_min) then
951+
dist_min = dist_v
952+
norm_vec(:) = point(:) - verts(:, mod(j, 3) + 1)
953+
norm_mag = sqrt(dot_product(norm_vec, norm_vec))
954+
if (norm_mag > 0._wp) norm_vec = norm_vec / norm_mag
955+
normals(:) = norm_vec(:)
929956
end if
930-
end if
931-
end do
932-
933-
! Check three vertices
934-
do j = 1, 3
935-
dist_v = sqrt((point(1) - verts(1, j))**2 + &
936-
(point(2) - verts(2, j))**2 + &
937-
(point(3) - verts(3, j))**2)
938-
939-
if (dist_v < dist_min) then
940-
dist_min = dist_v
941-
normals(:) = n(:)
942957
end if
943958
end do
944959
end if
@@ -967,12 +982,13 @@ contains
967982
real(wp), intent(out) :: distance
968983

969984
integer :: i
970-
real(wp) :: dist_min, dist, t
985+
real(wp) :: dist_min, dist, t, norm_mag
971986
real(wp) :: v1(1:2), v2(1:2), edge(1:2), pv(1:2)
972-
real(wp) :: edge_len_sq, proj(1:2)
987+
real(wp) :: edge_len_sq, proj(1:2), norm(1:2), c
973988

974989
dist_min = initial_distance_buffer
975990
normals = 0._wp
991+
norm = 0._wp
976992

977993
do i = 1, boundary_edge_count
978994
! Edge endpoints
@@ -998,16 +1014,26 @@ contains
9981014
if (t >= 0._wp .and. t <= 1._wp) then
9991015
proj = v1 + t*edge
10001016
dist = sqrt((point(1) - proj(1))**2 + (point(2) - proj(2))**2)
1017+
norm(1) = boundary_v(i, 3, 1, pid)
1018+
norm(2) = boundary_v(i, 3, 2, pid)
10011019
else if (t < 0._wp) then ! negative t means that v1 is the closest point on the edge
10021020
dist = sqrt((point(1) - v1(1))**2 + (point(2) - v1(2))**2)
1021+
norm(1) = point(1) - v1(1)
1022+
norm(2) = point(2) - v1(2)
1023+
norm_mag = sqrt(dot_product(norm, norm))
1024+
norm = norm / norm_mag
10031025
else ! t > 1 means that v2 is the closest point on the line edge
10041026
dist = sqrt((point(1) - v2(1))**2 + (point(2) - v2(2))**2)
1027+
norm(1) = point(1) - v2(1)
1028+
norm(2) = point(2) - v2(2)
1029+
norm_mag = sqrt(dot_product(norm, norm))
1030+
norm = norm / norm_mag
10051031
end if
10061032

10071033
if (dist < dist_min) then
10081034
dist_min = dist
1009-
normals(1) = boundary_v(i, 3, 1, pid)
1010-
normals(2) = boundary_v(i, 3, 2, pid)
1035+
normals(1) = norm(1)
1036+
normals(2) = norm(2)
10111037
end if
10121038
end do
10131039

0 commit comments

Comments
 (0)