ray_to_rectangle Subroutine

public subroutine ray_to_rectangle(hx, hy, dx, dy, x_min, x_max, y_min, y_max, z_plane, p, edge_id)

XY平面上で、中心からのレイと長方形境界の最短交点を返す。

Arguments

Type IntentOptional Attributes Name
real(kind=dp), intent(in) :: hx
real(kind=dp), intent(in) :: hy
real(kind=dp), intent(in) :: dx
real(kind=dp), intent(in) :: dy
real(kind=dp), intent(in) :: x_min
real(kind=dp), intent(in) :: x_max
real(kind=dp), intent(in) :: y_min
real(kind=dp), intent(in) :: y_max
real(kind=dp), intent(in) :: z_plane
real(kind=dp), intent(out) :: p(3)
integer(kind=i32), intent(out) :: edge_id

Called by

proc~~ray_to_rectangle~~CalledByGraph proc~ray_to_rectangle ray_to_rectangle proc~make_plate_hole make_plate_hole proc~make_plate_hole->proc~ray_to_rectangle proc~build_one_template build_one_template proc~build_one_template->proc~make_plate_hole proc~build_template_mesh build_template_mesh proc~build_template_mesh->proc~build_one_template proc~build_mesh_from_config build_mesh_from_config proc~build_mesh_from_config->proc~build_template_mesh proc~load_or_init_run_state load_or_init_run_state proc~load_or_init_run_state->proc~build_mesh_from_config program~main main program~main->proc~load_or_init_run_state

Source Code

  subroutine ray_to_rectangle(hx, hy, dx, dy, x_min, x_max, y_min, y_max, z_plane, p, edge_id)
    real(dp), intent(in) :: hx, hy, dx, dy, x_min, x_max, y_min, y_max, z_plane
    real(dp), intent(out) :: p(3)
    integer(i32), intent(out) :: edge_id
    real(dp) :: s_best, s, x, y
    real(dp), parameter :: eps = 1.0d-12

    s_best = huge(1.0d0)
    edge_id = 0_i32
    p = 0.0d0

    if (dx > eps) then
      s = (x_max - hx)/dx
      y = hy + s*dy
      if (s > eps .and. y >= y_min - eps .and. y <= y_max + eps .and. s < s_best) then
        s_best = s
        edge_id = 2_i32
        p = [x_max, y, z_plane]
      end if
    else if (dx < -eps) then
      s = (x_min - hx)/dx
      y = hy + s*dy
      if (s > eps .and. y >= y_min - eps .and. y <= y_max + eps .and. s < s_best) then
        s_best = s
        edge_id = 1_i32
        p = [x_min, y, z_plane]
      end if
    end if
    if (dy > eps) then
      s = (y_max - hy)/dy
      x = hx + s*dx
      if (s > eps .and. x >= x_min - eps .and. x <= x_max + eps .and. s < s_best) then
        s_best = s
        edge_id = 4_i32
        p = [x, y_max, z_plane]
      end if
    else if (dy < -eps) then
      s = (y_min - hy)/dy
      x = hx + s*dx
      if (s > eps .and. x >= x_min - eps .and. x <= x_max + eps .and. s < s_best) then
        edge_id = 3_i32
        p = [x, y_min, z_plane]
      end if
    end if

    if (edge_id == 0_i32) error stop "failed to intersect ray with rectangle boundary"
  end subroutine ray_to_rectangle