線分 AABB と canonical mesh AABB の重なりから必要な image shift 範囲を決める。
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(mesh_type), | intent(in) | :: | mesh | |||
| real(kind=dp), | intent(in) | :: | p0(3) | |||
| real(kind=dp), | intent(in) | :: | p1(3) | |||
| integer(kind=i32), | intent(in) | :: | axis | |||
| real(kind=dp), | intent(in) | :: | period_len | |||
| integer(kind=i32), | intent(out) | :: | nmin | |||
| integer(kind=i32), | intent(out) | :: | nmax | |||
| integer(kind=i32), | intent(out), | optional | :: | status |
subroutine compute_periodic_shift_bounds(mesh, p0, p1, axis, period_len, nmin, nmax, status) type(mesh_type), intent(in) :: mesh real(dp), intent(in) :: p0(3), p1(3) integer(i32), intent(in) :: axis real(dp), intent(in) :: period_len integer(i32), intent(out) :: nmin, nmax integer(i32), intent(out), optional :: status integer(i32) :: query_status integer(i64) :: nmin_i64, nmax_i64, i32_min_i64, i32_max_i64 real(dp) :: seg_min, seg_max, mesh_min, mesh_max, tol, lower_bound, upper_bound, i64_limit nmin = 0_i32 nmax = -1_i32 query_status = collision_query_ok seg_min = min(p0(axis), p1(axis)) seg_max = max(p0(axis), p1(axis)) mesh_min = mesh%grid_bb_min(axis) mesh_max = mesh%grid_bb_max(axis) tol = 1.0d-12*max(1.0d0, abs(seg_min), abs(seg_max), abs(mesh_min), abs(mesh_max), period_len) lower_bound = (seg_min - mesh_max - tol)/period_len upper_bound = (seg_max - mesh_min + tol)/period_len if (.not. ieee_is_finite(lower_bound) .or. .not. ieee_is_finite(upper_bound)) then call finalize_collision_query(collision_query_index_range, status) return end if i64_limit = real(huge(0_i64), dp) if (lower_bound <= -i64_limit .or. lower_bound >= i64_limit .or. & upper_bound <= -i64_limit .or. upper_bound >= i64_limit) then call finalize_collision_query(collision_query_index_range, status) return end if nmin_i64 = ceiling(lower_bound, kind=i64) nmax_i64 = floor(upper_bound, kind=i64) i32_max_i64 = int(huge(0_i32), i64) i32_min_i64 = -i32_max_i64 - 1_i64 if (nmin_i64 < i32_min_i64 .or. nmin_i64 > i32_max_i64 .or. & nmax_i64 < i32_min_i64 .or. nmax_i64 > i32_max_i64) then call finalize_collision_query(collision_query_index_range, status) return end if nmin = int(nmin_i64, i32) nmax = int(nmax_i64, i32) call finalize_collision_query(query_status, status) end subroutine compute_periodic_shift_bounds