cone_is_visible Function

private function cone_is_visible(self, point, min_distance, max_distance) result(visible)

Whether point (in the cone's frame) is inside the cone, between distances min_distance and max_distance along the boresight (defaults 0 and unlimited): inside the polygon of the vertices' directions (OpenFrames' isVisible; its PolyhedralCone always answers false).

Type Bound

PolyhedralCone

Arguments

Type IntentOptional Attributes Name
class(PolyhedralCone), intent(in) :: self
real(kind=wp), intent(in) :: point(3)

in the cone's frame (scene units)

real(kind=wp), intent(in), optional :: min_distance

along the boresight (scene units)

real(kind=wp), intent(in), optional :: max_distance

along the boresight (scene units)

Return Value logical


Calls

proc~~cone_is_visible~~CallsGraph proc~cone_is_visible PolyhedralCone%cone_is_visible proc~in_range in_range proc~cone_is_visible->proc~in_range proc~side side proc~cone_is_visible->proc~side

Source Code

    logical function cone_is_visible(self, point, min_distance, max_distance) result(visible)
        class(PolyhedralCone), intent(in) :: self
        real(wp), intent(in) :: point(3)                    !! in the cone's frame (scene units)
        real(wp), intent(in), optional :: min_distance, max_distance  !! along the boresight (scene units)
        real(wp) :: q(2), a(2), b(2)
        integer :: i, n, winding
        visible = in_range(point, min_distance, max_distance)
        if (.not. visible .or. norm2(point) == 0.0_wp) return
        q = point(1:2) / (-point(3))                            ! on the plane z = -1
        n = size(self%clock)
        winding = 0                                             ! winding number of the polygon around q
        do i = 1, n
            a = tan(self%cone(i)) * [cos(self%clock(i)), sin(self%clock(i))]
            b = tan(self%cone(modulo(i, n) + 1)) * [cos(self%clock(modulo(i, n) + 1)), sin(self%clock(modulo(i, n) + 1))]
            if (a(2) <= q(2)) then
                if (b(2) > q(2) .and. side(a, b, q) > 0.0_wp) winding = winding + 1
            else
                if (b(2) <= q(2) .and. side(a, b, q) < 0.0_wp) winding = winding - 1
            end if
        end do
        visible = winding /= 0
    end function cone_is_visible