線分 p(t)=p0+t*d (0<=t<=1) とAABBの交差区間 [t_entry,t_exit] を返す。
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=dp), | intent(in) | :: | p0(3) | |||
| real(kind=dp), | intent(in) | :: | d(3) | |||
| real(kind=dp), | intent(in) | :: | bb_min(3) | |||
| real(kind=dp), | intent(in) | :: | bb_max(3) | |||
| logical, | intent(out) | :: | ok | |||
| real(kind=dp), | intent(out) | :: | t_entry | |||
| real(kind=dp), | intent(out) | :: | t_exit |
pure subroutine segment_aabb_intersection_t(p0, d, bb_min, bb_max, ok, t_entry, t_exit) real(dp), intent(in) :: p0(3), d(3), bb_min(3), bb_max(3) logical, intent(out) :: ok real(dp), intent(out) :: t_entry, t_exit real(dp), parameter :: eps = 1.0d-14 real(dp) :: t0, t1, t_near, t_far, inv_d, tmp integer(i32) :: axis t0 = 0.0d0 t1 = 1.0d0 do axis = 1, 3 if (abs(d(axis)) <= eps) then if (p0(axis) < bb_min(axis) .or. p0(axis) > bb_max(axis)) then ok = .false. t_entry = 0.0d0 t_exit = -1.0d0 return end if else inv_d = 1.0d0/d(axis) t_near = (bb_min(axis) - p0(axis))*inv_d t_far = (bb_max(axis) - p0(axis))*inv_d if (t_near > t_far) then tmp = t_near t_near = t_far t_far = tmp end if if (t_near > t0) t0 = t_near if (t_far < t1) t1 = t_far if (t0 > t1) then ok = .false. t_entry = 0.0d0 t_exit = -1.0d0 return end if end if end do ok = .true. t_entry = t0 t_exit = t1 end subroutine segment_aabb_intersection_t