Function computes intersection of ray with triangle
http://geomalgorithms.com/a06-_intersect-2.html intersect_RayTriangle(): intersect a ray with a 3D triangle Input: a ray R, and a triangle T Output: *I = intersection point (when it exists) Return: -1 = triangle is degenerate (a segment or point) 0 = disjoint (no intersect) 1 = intersect in unique point I1 2 = are in the same planeint todo: when line lies in triangle, need to treat properly
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(tem_line_type), | intent(in) | :: | line |
line segment to check for interection |
||
type(tem_triangle_type), | intent(in) | :: | triangle |
cube to check intersection of line |
||
type(tem_point_type), | intent(out), | optional | :: | intersect_p |
intersection point if there is intersection |
function intersect_RayTriangle( line, triangle, intersect_p ) result(isIntersect) ! ---------------------------------------------------------------------------! !> line segment to check for interection type(tem_line_type), intent(in) :: line !> cube to check intersection of line type(tem_triangle_type), intent(in) :: triangle !> intersection point if there is intersection type( tem_point_type), optional, intent(out) :: intersect_p logical :: isIntersect ! ---------------------------------------------------------------------------! real(kind=rk) :: u(3), v(3), n(3) ! triangle vectors and normal vector real(kind=rk) :: dir(3), w0(3), w(3) ! ray vectors real(kind=rk) :: r, a, b ! params to calc ray-plane intersect real(kind=rk) :: uu, uv, vv, wu, wv, D real(kind=rk) :: s, t real(kind=rk) :: temp_p(3) ! ---------------------------------------------------------------------------! isIntersect = .false. ! set not intersect as default ! get triangle edge vectors u & v, and plane normal n u(:) = triangle%nodes(:,2) - triangle%nodes(:,1) v(:) = triangle%nodes(:,3) - triangle%nodes(:,1) n = cross_product3D( u, v ) ! triangle is degenerate ! do not deal with this case if (all(n .feq. 0._rk)) return dir = line%vec ! ray direction vector w0 = line%origin - triangle%nodes(:,1) a = -dot_product( n, w0); b = dot_product( n, dir); ! if ray parallel to triangle plane, treat it as no intersecting if (abs(b) < eps .and. abs(a) > tiny(a)) return ! { if (a == 0.0_rk) ! ray lies in triangle plane ! return 2; ! else return 0; ! ray disjoint from plane ! } if (abs(b) < eps) then ! origin is very close to triangle plane, but parallel. ! Just use the origin itself as point to check. r = 0.0_rk else ! get intersect point of ray with triangle plane r = a / b if (r < 0._rk ) then ! ray goes away from triangle return endif end if ! for a segment, also test if (r > 1.0) => no intersect ! intersect point of ray and plane temp_p = line%origin + r * dir ! is I inside T? uu = dot_product(u,u) uv = dot_product(u,v) vv = dot_product(v,v) w = temp_p - triangle%nodes(:,1) wu = dot_product(w,u) wv = dot_product(w,v) D = uv * uv - uu * vv ! get and test parametric coords s = (uv * wv - vv * wu) / D ! point is outside triangle if (s < 0._rk-eps .or. s > 1._rk+eps) then return endif t = (uv * wu - uu * wv) / D ! point is outside triangle if (t < 0._rk-eps .or. (s + t) > 1._rk+eps) then return endif isIntersect = .true. ! point is inside triangle if( present( intersect_p ) ) then intersect_p%coord = temp_p endif end function intersect_RayTriangle