Function computes intersection of ray with cube
The algorithm for lineCubeOverlap used in this function is taken from http://www.siggraph.org/education/materials/HyperGraph/raytrace/ rtinter3.htm http://gamedev.stackexchange.com/questions/18436/ most-efficient-aabb-vs-ray-collision-algorithms
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(tem_line_type), | intent(in) | :: | line |
line segment to check for interection |
||
type(tem_cube_type), | intent(in) | :: | cube |
cube to check intersection of line |
||
real(kind=rk), | intent(out), | optional | :: | pntIntersect(3) |
intersection point if there is intersection |
function rayCubeOverlap( line, cube, pntIntersect ) result(overlap)
! ---------------------------------------------------------------------------!
!> line segment to check for interection
type(tem_line_type), intent(in) :: line
!> cube to check intersection of line
type(tem_cube_type), intent(in) :: cube
!> intersection point if there is intersection
real(kind=rk), optional, intent(out) :: pntIntersect(3)
logical :: overlap
! ---------------------------------------------------------------------------!
integer :: i
real(kind=rk) :: t_near, t_far
real(kind=rk) :: T_1, T_2, tmp
! ---------------------------------------------------------------------------!
!initialize near point and var point
t_near = 0.0_rk
t_far = huge(t_far)
dirLoop: do i=1,3 !x,y,z
if (line%vec(i) .feq. 0._rk) then
!line parallel to planes in this direction.
!Line exactly on the cube origin is considered as overlap
if ( (line%origin(i) < cube%origin(i)) &
& .or. (line%origin(i) >= cube%endPnt(i)) ) then
!parallel and outside cube : no intersection possible
overlap = .false.
return
end if
else
!line not parallel to cube
!1st intersection point on one side of the cube plane
T_1 = (cube%origin(i) - line%origin(i)) / line%vec(i)
!2nd intersection point on one side of the cube plane
T_2 = (cube%endPnt(i) - line%origin(i)) / line%vec(i)
if (T_1 > T_2) then
! we want T_1 to hold values for intersection with near plane
tmp = T_2
T_2 = T_1
T_1 = tmp
end if
if (T_1 > t_near) t_near = T_1
if (T_2 < t_far) t_far = T_2
if ( (t_near > t_far) .or. (t_far < 0) ) then
overlap = .false.
return
end if
end if
end do dirLoop
!point of intersection
if(present(pntIntersect)) then
pntIntersect = line%origin + t_near * line%vec
endif
!If we made it here, there is an intesection
overlap = .true.
end function rayCubeOverlap