segment_triangle_intersect Subroutine

public subroutine segment_triangle_intersect(p0, p1, v0, v1, v2, ok, t, h)

Möller–Trumbore法で線分と三角形の交差有無・線分パラメータ t・交点座標を計算する。

Arguments

Type IntentOptional Attributes Name
real(kind=dp), intent(in) :: p0(3)
real(kind=dp), intent(in) :: p1(3)
real(kind=dp), intent(in) :: v0(3)
real(kind=dp), intent(in) :: v1(3)
real(kind=dp), intent(in) :: v2(3)
logical, intent(out) :: ok

線分と三角形が交差した場合に .true.

real(kind=dp), intent(out) :: t

交点の線分内パラメータ(p0 + t*(p1-p0))。

real(kind=dp), intent(out) :: h(3)

交点の線分内パラメータ(p0 + t*(p1-p0))。


Calls

proc~~segment_triangle_intersect~~CallsGraph proc~segment_triangle_intersect segment_triangle_intersect proc~cross cross proc~segment_triangle_intersect->proc~cross

Called by

proc~~segment_triangle_intersect~~CalledByGraph proc~segment_triangle_intersect segment_triangle_intersect proc~find_first_hit_base_grid find_first_hit_base_grid proc~find_first_hit_base_grid->proc~segment_triangle_intersect proc~find_first_hit_base_linear find_first_hit_base_linear proc~find_first_hit_base_linear->proc~segment_triangle_intersect proc~find_first_hit_base find_first_hit_base proc~find_first_hit_base->proc~find_first_hit_base_grid proc~find_first_hit_base->proc~find_first_hit_base_linear proc~find_first_hit find_first_hit 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~find_first_hit_periodic2->proc~find_first_hit_base proc~sample_photo_raycast_particles sample_photo_raycast_particles proc~sample_photo_raycast_particles->proc~find_first_hit proc~sample_photo_species_state sample_photo_species_state proc~sample_photo_species_state->proc~sample_photo_raycast_particles proc~init_particle_batch_from_config init_particle_batch_from_config proc~init_particle_batch_from_config->proc~sample_photo_species_state

Source Code

  subroutine segment_triangle_intersect(p0, p1, v0, v1, v2, ok, t, h)
    real(dp), intent(in) :: p0(3), p1(3), v0(3), v1(3), v2(3)
    logical, intent(out) :: ok
    real(dp), intent(out) :: t, h(3)

    real(dp), parameter :: eps = 1.0d-12
    real(dp) :: d(3), e1(3), e2(3), q(3), s(3), hh(3), a, f, u, v

    d = p1 - p0
    e1 = v1 - v0
    e2 = v2 - v0
    hh = cross(d, e2)
    a = dot_product(e1, hh)
    if (abs(a) < eps) then
      ok = .false.; return
    end if

    f = 1.0d0/a
    s = p0 - v0
    u = f*dot_product(s, hh)
    if (u < 0.0d0 .or. u > 1.0d0) then
      ok = .false.; return
    end if

    q = cross(s, e1)
    v = f*dot_product(d, q)
    if (v < 0.0d0 .or. (u + v) > 1.0d0) then
      ok = .false.; return
    end if

    t = f*dot_product(e2, q)
    if (t < 0.0d0 .or. t > 1.0d0) then
      ok = .false.; return
    end if

    h = p0 + t*d
    ok = .true.
  end subroutine segment_triangle_intersect