Determinate is a point is inside or not to a polyhedron described by STL facets by means ray intersections count.
STL's metrix must be already computed.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(file_stl_object), | intent(in) | :: | self | File STL. |
||
| type(vector_R8P), | intent(in) | :: | point | Point coordinates. |
Check result.
pure function is_point_inside_polyhedron_ri(self, point) result(is_inside)
!< Determinate is a point is inside or not to a polyhedron described by STL facets by means ray intersections count.
!<
!< @note STL's metrix must be already computed.
class(file_stl_object), intent(in) :: self !< File STL.
type(vector_R8P), intent(in) :: point !< Point coordinates.
logical :: is_inside !< Check result.
logical :: is_inside_by_x !< Test result by x-aligned ray intersections.
logical :: is_inside_by_y !< Test result by y-aligned ray intersections.
logical :: is_inside_by_z !< Test result by z-aligned ray intersections.
is_inside_by_x = is_inside_by_ray_intersect(ray_origin=point, ray_direction= ex_R8P + EPS * ey_R8P + EPS * ez_R8P)
is_inside_by_y = is_inside_by_ray_intersect(ray_origin=point, ray_direction=EPS * ex_R8P + ey_R8P + EPS * ez_R8P)
if (is_inside_by_x.and.is_inside_by_y) then
is_inside = .true.
else
is_inside_by_z = is_inside_by_ray_intersect(ray_origin=point, ray_direction=EPS * ex_R8P + EPS * ey_R8P + ez_R8P)
is_inside = ((is_inside_by_x.and.is_inside_by_y).or.&
(is_inside_by_x.and.is_inside_by_z).or.&
(is_inside_by_y.and.is_inside_by_z))
endif
contains
pure function is_inside_by_ray_intersect(ray_origin, ray_direction) result(is_inside_by)
!< Generic line intersect test.
type(vector_R8P), intent(in) :: ray_origin !< Ray origin.
type(vector_R8P), intent(in) :: ray_direction !< Ray direction.
integer(I4P) :: intersections_number !< Ray intersections number of STL polyhedra with respect point.
integer(I4P) :: f !< Counter.
logical :: is_inside_by !< Test result.
intersections_number = 0
if (self%aabb%is_initialized) then
! exploit AABB refinement levels
intersections_number = self%aabb%ray_intersections_number(ray_origin=ray_origin, ray_direction=ray_direction)
else
! brute-force search over all facets
do f=1, self%facets_number
if (self%facet(f)%do_ray_intersect(ray_origin=ray_origin, ray_direction=ray_direction)) &
intersections_number = intersections_number + 1
enddo
endif
if (mod(intersections_number, 2) == 0) then
is_inside_by = .false.
else
is_inside_by = .true.
endif
endfunction is_inside_by_ray_intersect
endfunction is_point_inside_polyhedron_ri