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.
Todo
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