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