Return true if facet is intersected by ray from origin and oriented as ray direction vector.
This based on Moller–Trumbore intersection algorithm.
Facet's metrix must be already computed.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(facet_object), | intent(in) | :: | self | Facet. |
||
| type(vector_R8P), | intent(in) | :: | ray_origin | Ray origin. |
||
| type(vector_R8P), | intent(in) | :: | ray_direction | Ray direction. |
Intersection test result.
pure function do_ray_intersect(self, ray_origin, ray_direction) result(intersect)
!< Return true if facet is intersected by ray from origin and oriented as ray direction vector.
!<
!< This based on Moller–Trumbore intersection algorithm.
!<
!< @note Facet's metrix must be already computed.
class(facet_object), intent(in) :: self !< Facet.
type(vector_R8P), intent(in) :: ray_origin !< Ray origin.
type(vector_R8P), intent(in) :: ray_direction !< Ray direction.
logical :: intersect !< Intersection test result.
type(vector_R8P) :: h, s, q !< Projection vectors.
real(R8P) :: a, f, u, v, t !< Baricentric abscissa.
intersect = .false.
h = ray_direction.cross.self%E13
a = self%E12.dot.h
if ((a > -EPS).and.(a < EPS)) return
f = 1._R8P / a
s = ray_origin - self%vertex_1
u = f * (s.dot.h)
if ((u < 0._R8P).or.(u > 1._R8P)) return
q = s.cross.self%E12
v = f * ray_direction.dot.q
if ((v < 0._R8P).or.(u + v > 1._R8P)) return
t = f * self%E13.dot.q
if (t > EPS) intersect = .true.
endfunction do_ray_intersect