This function checks intesection of solid cube and cylinder.
The test is done by projecting each cube vertices on the cylinder axis and check whether the projected point is within the cylinder length. If yes then use the projected point as the origin of sphere and do sphere-cube intersection.
HK: The algorithm used in here is not correct! @todo KM: BUG in defining cylinder with fixed length. This implementation works only for cylinder with infinite length
we check for all vertices to find if any of the cube vertices intersect with cylinder check whether cylinder axis intersect by cube if true then no need to check for intersection of each cube vertices on cylinder
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(tem_cylinder_type), | intent(in) | :: | cylinder | |||
type(tem_cube_type), | intent(in) | :: | cube |
function tem_cylinderCubeOverlap(cylinder, cube) result(overlap)
! --------------------------------------------------------------------------!
!inferface variables
type(tem_cylinder_type), intent(in) :: cylinder !< cylinder geometry data
type(tem_cube_type), intent(in) :: cube
logical :: overlap !< return value
! --------------------------------------------------------------------------!
! local variables
real(kind=rk) :: proj
real(kind=rk) :: cubeVer(15,3)
type(tem_sphere_type) :: sphere
type(tem_line_type) :: line
integer :: iVer
real(kind=rk) :: pntIntersect(3)
! --------------------------------------------------------------------------!
overlap = .false.
!! we check for all vertices to find if any of the cube vertices
!! intersect with cylinder
cubeVer(1,:) = cube%center
cubeVer(2,:) = cube%center + [ cube%halfwidth, 0.0_rk, 0.0_rk]
cubeVer(3,:) = cube%center + [-cube%halfwidth, 0.0_rk, 0.0_rk]
cubeVer(4,:) = cube%center + [0.0_rk, cube%halfwidth, 0.0_rk]
cubeVer(5,:) = cube%center + [0.0_rk, -cube%halfwidth, 0.0_rk]
cubeVer(6,:) = cube%center + [0.0_rk, 0.0_rk, cube%halfwidth]
cubeVer(7,:) = cube%center + [0.0_rk, 0.0_rk, -cube%halfwidth]
cubeVer(8,:) = cube%origin
cubeVer(9,:) = [cube%endPnt(1), cube%origin(2), cube%origin(3)]
cubeVer(10,:) = [cube%origin(1), cube%endPnt(2), cube%origin(3)]
cubeVer(11,:) = [cube%origin(1), cube%origin(2), cube%endPnt(3)]
cubeVer(12,:) = [cube%endPnt(1), cube%endPnt(2), cube%origin(3)]
cubeVer(13,:) = [cube%endPnt(1), cube%origin(2), cube%endPnt(3)]
cubeVer(14,:) = [cube%origin(1), cube%endPnt(2), cube%endPnt(3)]
cubeVer(15,:) = cube%endPnt
sphere%radius = cylinder%radius
sphere%only_surface = cylinder%only_surface
!! check whether cylinder axis intersect by cube
!! if true then no need to check for intersection of each cube vertices
!! on cylinder
line%origin = cylinder%origin
line%vec = cylinder%vec
if(tem_lineCubeOverlap(line, cube, pntIntersect)) then
! project intersected point on cylinder to check for
! sphere cube overlap
proj = dot_product((pntIntersect - cylinder%origin), &
& cylinder%vec) &
& / dot_product(cylinder%vec, cylinder%vec)
! compute the actual coordinate position of projected
! point on the line
sphere%origin = cylinder%origin + proj*cylinder%vec
overlap = tem_sphereCubeOverlap( sphere, cube )
! return if overlap is true
if(overlap) return
endif
do iVer=1,15
! Find the projection of cubever on line and check
! whether projection point is between 0 and 1.
! If projection < 0 then the point is before the line
! if projection > 0 then the point is after the line
proj = dot_product((cubeVer(iVer,:) - cylinder%origin), &
& cylinder%vec) &
& / dot_product(cylinder%vec, cylinder%vec)
if( (proj .fge. 0.0_rk) .and. (proj .fle. 1.0_rk)) then
! compute the actual coordinate position of projected
! point on the line
sphere%origin = cylinder%origin + proj*cylinder%vec
overlap = tem_sphereCubeOverlap( sphere, cube )
! return if overlap is true
if(overlap) return
endif
enddo
end function tem_cylinderCubeOverlap