triBoxOverlap_loc Function

private function triBoxOverlap_loc(boxCenter, boxHalfwidth, triNodes) result(overlaps)

This routine checks for triangle box overlap

this routine is conversion of c-code tribox3.c triBoxOverlap function. use separating axis theorem to test overlap between triangle and box need to test for overlap in these directions: 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle we do not even need to test these) 2) normal of the triangle 3) separating axis test. crossproduct(edge from tri, {x,y,z}-directin) this gives 3x3=9 more 7tests This code is available at: http://fileadmin.cs.lth.se/cs/Personal/Tomas_Akenine-Moller/code/tribox3.txt

Arguments

Type IntentOptional Attributes Name
real(kind=rk), intent(in) :: boxCenter(3)

box center

real(kind=rk), intent(in) :: boxHalfwidth(3)

halfwidth of the box

real(kind=rk), intent(in) :: triNodes(3,3)

nodes of the triangle 1st index denote x,y,z coordinates and 2nd index denote nodes

Return Value logical


Calls

proc~~triboxoverlap_loc~~CallsGraph proc~triboxoverlap_loc triBoxOverlap_loc proc~axistest Axistest proc~triboxoverlap_loc->proc~axistest proc~cross_product3d cross_product3D proc~triboxoverlap_loc->proc~cross_product3d proc~planeboxoverlap planeBoxOverlap proc~triboxoverlap_loc->proc~planeboxoverlap proc~axistest->proc~cross_product3d

Called by

proc~~triboxoverlap_loc~~CalledByGraph proc~triboxoverlap_loc triBoxOverlap_loc proc~tem_trianglecubeoverlap tem_triangleCubeOverlap proc~tem_trianglecubeoverlap->proc~triboxoverlap_loc proc~tem_planecubeoverlap tem_planeCubeOverlap proc~tem_planecubeoverlap->proc~tem_trianglecubeoverlap proc~tem_shape_subtreefromgeominters tem_shape_subTreeFromGeomInters proc~tem_shape_subtreefromgeominters->proc~tem_trianglecubeoverlap proc~tem_stlcubeoverlap tem_stlCubeOverlap proc~tem_shape_subtreefromgeominters->proc~tem_stlcubeoverlap proc~tem_cano_initsubtree tem_cano_initSubTree proc~tem_shape_subtreefromgeominters->proc~tem_cano_initsubtree proc~tem_stlcubeoverlap->proc~tem_trianglecubeoverlap proc~tem_boxcubeoverlap tem_boxCubeOverlap proc~tem_boxcubeoverlap->proc~tem_planecubeoverlap proc~tem_cano_initsubtree->proc~tem_planecubeoverlap proc~tem_cano_initsubtree->proc~tem_boxcubeoverlap proc~tem_shape2subtree tem_shape2subTree proc~tem_shape2subtree->proc~tem_shape_subtreefromgeominters proc~tem_create_subtree_of tem_create_subTree_of proc~tem_create_subtree_of->proc~tem_shape2subtree

Source Code

  function triBoxOverlap_loc( boxCenter, boxHalfwidth, triNodes ) &
    &                         result(overlaps)
    !--------------------------------------------------------------------------!
    !> box center
    real(kind=rk), intent(in) :: boxCenter(3)
    !> halfwidth of the box
    real(kind=rk), intent(in) :: boxHalfwidth(3)
    !> nodes of the triangle
    !! 1st index denote x,y,z coordinates and
    !! 2nd index denote nodes
    real(kind=rk), intent(in) :: triNodes(3,3)
    logical :: overlaps
    !--------------------------------------------------------------------------!
    real(kind=rk) :: nodes(3,3)
    real(kind=rk) :: dirVec1(3), dirVec2(3), dirVec3(3)
    real(kind=rk) :: mmin, mmax
    real(kind=rk) :: normal(3), edge1(3), edge2(3), edge3(3)
    !--------------------------------------------------------------------------!
    overlaps = .false.

    dirVec1 = (/ 1.0_rk, 0.0_rk, 0.0_rk /)
    dirVec2 = (/ 0.0_rk, 1.0_rk, 0.0_rk /)
    dirVec3 = (/ 0.0_rk, 0.0_rk, 1.0_rk /)

    ! move everything so that the box center is in (0,0,0)
    nodes(:,1) = triNodes(:,1) - boxCenter
    nodes(:,2) = triNodes(:,2) - boxCenter
    nodes(:,3) = triNodes(:,3) - boxCenter

    ! compute triangle edges
    edge1 = nodes(:,2) - nodes(:,1)
    edge2 = nodes(:,3) - nodes(:,2)
    edge3 = nodes(:,1) - nodes(:,3)


    ! separating axis test
    if(axistest(dirVec1, edge1, nodes, boxhalfwidth)) return
    if(axistest(dirVec1, edge2, nodes, boxhalfwidth)) return
    if(axistest(dirVec1, edge3, nodes, boxhalfwidth)) return

    if(axistest(dirVec2, edge1, nodes, boxhalfwidth)) return
    if(axistest(dirVec2, edge2, nodes, boxhalfwidth)) return
    if(axistest(dirVec2, edge3, nodes, boxhalfwidth)) return

    if(axistest(dirVec3, edge1, nodes, boxhalfwidth)) return
    if(axistest(dirVec3, edge2, nodes, boxhalfwidth)) return
    if(axistest(dirVec3, edge3, nodes, boxhalfwidth)) return


    ! Bullet 1:
    !  first test overlap in the {x,y,z}-directions
    !  find min, max of the triangle each direction, and test for overlap in
    !  that direction -- this is equivalent to testing a minimal AABB around
    !  the triangle against the AABB
    ! test in X-direction
    mmin = min( nodes(1,1), nodes(1,2), nodes(1,3) )
    mmax = max( nodes(1,1), nodes(1,2), nodes(1,3) )
    if ( mmin > boxhalfwidth(1) .or. mmax < -boxhalfwidth(1) ) return

    ! test in Y-direction
    mmin = min( nodes(2,1), nodes(2,2), nodes(2,3) )
    mmax = max( nodes(2,1), nodes(2,2), nodes(2,3) )
    if ( mmin > boxhalfwidth(2) .or. mmax < -boxhalfwidth(2) ) return

    ! test in Z-direction
    mmin = min( nodes(3,1), nodes(3,2), nodes(3,3) )
    mmax = max( nodes(3,1), nodes(3,2), nodes(3,3) )
    if ( mmin > boxhalfwidth(3) .or. mmax < -boxhalfwidth(3) ) return


    ! Bullet 2:
    !  test if the box intersects the plane of the triangle
    !  compute plane equation of triangle: normal*x+d=0
    normal = cross_product3D(edge1,edge2)

    if( .not. planeBoxOverlap(normal, nodes(:,1), boxhalfwidth)) return

    overlaps = .true.

  end function triBoxOverlap_loc