Compute the (minimum) distance from a point to the triangulated surface.
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. |
||
| logical, | intent(in), | optional | :: | is_signed | Sentinel to trigger signed distance. |
|
| character(len=*), | intent(in), | optional | :: | sign_algorithm | Algorithm used for "point in polyhedron" test. |
|
| logical, | intent(in), | optional | :: | is_square_root | Sentinel to trigger square-root distance. |
Minimum distance from point to the triangulated surface.
pure function distance(self, point, is_signed, sign_algorithm, is_square_root)
!< Compute the (minimum) distance from a point to the triangulated surface.
!<
!< @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, intent(in), optional :: is_signed !< Sentinel to trigger signed distance.
character(*), intent(in), optional :: sign_algorithm !< Algorithm used for "point in polyhedron" test.
logical, intent(in), optional :: is_square_root !< Sentinel to trigger square-root distance.
real(R8P) :: distance !< Minimum distance from point to the triangulated surface.
real(R8P) :: distance_ !< Minimum distance, temporary buffer.
character(len=:), allocatable :: sign_algorithm_ !< Algorithm used for "point in polyhedron" test, local variable.
integer(I4P) :: f !< Counter.
if (self%facets_number > 0) then
if (self%aabb%is_initialized) then
! exploit AABB refinement levels
distance = self%aabb%distance(point=point)
else
! brute-force search over all facets
distance = MaxR8P
do f=1, self%facets_number
distance_ = self%facet(f)%distance(point=point)
if (abs(distance_) <= abs(distance)) distance = distance_
enddo
endif
endif
if (present(is_square_root)) then
if (is_square_root) distance = sqrt(distance)
endif
if (present(is_signed)) then
if (is_signed) then
sign_algorithm_ = 'ray_intersections' ; if (present(sign_algorithm)) sign_algorithm_ = sign_algorithm
select case(sign_algorithm_)
case('solid_angle')
if (self%is_point_inside_polyhedron_sa(point=point)) distance = -distance
case('ray_intersections')
if (self%is_point_inside_polyhedron_ri(point=point)) distance = -distance
case default
! raise error: "unknown point in polyhedron algorithm"
endselect
endif
endif
endfunction distance