find_first_hit Subroutine

public subroutine find_first_hit(mesh, p0, p1, hit, sim, box_min, box_max, require_elem_inside, status)

線分 [p0,p1] に対して最初に衝突する三角形要素を探索し、命中情報を返す。

Arguments

Type IntentOptional Attributes Name
type(mesh_type), intent(in) :: mesh

三角形要素とAABB情報を保持した衝突判定対象メッシュ。

real(kind=dp), intent(in) :: p0(3)
real(kind=dp), intent(in) :: p1(3)
type(hit_info), intent(out) :: hit

最初に命中した要素インデックス・命中位置・線分パラメータを格納。

class(particle_domain_config), intent(in), optional :: sim
real(kind=dp), intent(in), optional :: box_min(3)
real(kind=dp), intent(in), optional :: box_max(3)
logical, intent(in), optional :: require_elem_inside
integer(kind=i32), intent(out) :: status

照会完了状態。不完全な照会は collision_query_ok 以外を返し、扱いは呼び出し側が決める。


Calls

proc~~find_first_hit~~CallsGraph proc~find_first_hit find_first_hit proc~find_first_hit_base find_first_hit_base proc~find_first_hit->proc~find_first_hit_base proc~find_first_hit_periodic2 find_first_hit_periodic2 proc~find_first_hit->proc~find_first_hit_periodic2 proc~initialize_hit initialize_hit proc~find_first_hit->proc~initialize_hit proc~find_first_hit_base->proc~initialize_hit proc~find_first_hit_base_grid find_first_hit_base_grid proc~find_first_hit_base->proc~find_first_hit_base_grid proc~find_first_hit_base_linear find_first_hit_base_linear proc~find_first_hit_base->proc~find_first_hit_base_linear proc~resolve_box_filter_args resolve_box_filter_args proc~find_first_hit_base->proc~resolve_box_filter_args proc~find_first_hit_periodic2->proc~find_first_hit_base proc~find_first_hit_periodic2->proc~initialize_hit proc~point_inside_box_periodic2 point_inside_box_periodic2 proc~find_first_hit_periodic2->proc~point_inside_box_periodic2 proc~prefer_periodic_candidate prefer_periodic_candidate proc~find_first_hit_periodic2->proc~prefer_periodic_candidate proc~find_first_hit_periodic2->proc~resolve_box_filter_args proc~wrap_periodic2_point~2 wrap_periodic2_point proc~find_first_hit_periodic2->proc~wrap_periodic2_point~2 proc~bbox_inside_box bbox_inside_box proc~find_first_hit_base_grid->proc~bbox_inside_box proc~cell_id~2 cell_id proc~find_first_hit_base_grid->proc~cell_id~2 proc~coord_to_cell~2 coord_to_cell proc~find_first_hit_base_grid->proc~coord_to_cell~2 proc~lower_ascii lower_ascii proc~find_first_hit_base_grid->proc~lower_ascii proc~point_inside_box point_inside_box proc~find_first_hit_base_grid->proc~point_inside_box proc~segment_aabb_intersection_t segment_aabb_intersection_t proc~find_first_hit_base_grid->proc~segment_aabb_intersection_t proc~segment_bbox_overlap_precomputed segment_bbox_overlap_precomputed proc~find_first_hit_base_grid->proc~segment_bbox_overlap_precomputed proc~segment_triangle_intersect segment_triangle_intersect proc~find_first_hit_base_grid->proc~segment_triangle_intersect proc~find_first_hit_base_linear->proc~bbox_inside_box proc~find_first_hit_base_linear->proc~point_inside_box proc~find_first_hit_base_linear->proc~segment_bbox_overlap_precomputed proc~find_first_hit_base_linear->proc~segment_triangle_intersect proc~cross~3 cross proc~segment_triangle_intersect->proc~cross~3

Called by

proc~~find_first_hit~~CalledByGraph proc~find_first_hit find_first_hit proc~advance_particle_step advance_particle_step proc~advance_particle_step->proc~find_first_hit proc~advance_particle_step_upper_panel_fourier advance_particle_step_upper_panel_fourier proc~advance_particle_step_upper_panel_fourier->proc~find_first_hit proc~cast_photo_ray cast_photo_ray proc~cast_photo_ray->proc~find_first_hit proc~resolve_particle_boundary_candidate resolve_particle_boundary_candidate proc~resolve_particle_boundary_candidate->proc~find_first_hit proc~sample_photo_ray_slot sample_photo_ray_slot proc~sample_photo_ray_slot->proc~cast_photo_ray

Source Code

  subroutine find_first_hit(mesh, p0, p1, hit, sim, box_min, box_max, require_elem_inside, status)
    type(mesh_type), intent(in) :: mesh
    real(dp), intent(in) :: p0(3), p1(3)
    type(hit_info), intent(out) :: hit
    class(particle_domain_config), intent(in), optional :: sim
    real(dp), intent(in), optional :: box_min(3), box_max(3)
    logical, intent(in), optional :: require_elem_inside
    integer(i32), intent(out) :: status

    logical :: use_periodic2

    use_periodic2 = .false.
    if (any(.not. ieee_is_finite(p0)) .or. any(.not. ieee_is_finite(p1))) then
      call initialize_hit(hit)
      status = collision_query_invalid_segment
      return
    end if
    ! periodic2 の周期軸と周期長は prepare_periodic2_collision_mesh が mesh に解決済み。query ごとに解き直さない。
    if (present(sim)) use_periodic2 = trim(sim%field_bc_mode) == 'periodic2'

    if (use_periodic2) then
      call find_first_hit_periodic2( &
        mesh, p0, p1, hit, sim, box_min, box_max, require_elem_inside, status &
        )
    else
      call find_first_hit_base(mesh, p0, p1, hit, box_min, box_max, require_elem_inside, status)
    end if
  end subroutine find_first_hit