marker_pick Subroutine

private subroutine marker_pick(a, frame, cam, m, hits, n)

A marker artist's best hit: its start, end and intermediate markers drawn.

Arguments

Type IntentOptional Attributes Name
class(MarkerArtist), intent(in), target :: a

the artist

class(ReferenceFrame), intent(in), target :: frame

the frame drawing it (for the hit)

type(PickCamera), intent(in) :: cam

the pick camera

real(kind=wp), intent(in) :: m(4,4)

the frame's transform to the root frame

type(PickHit), intent(inout), allocatable :: hits(:)

hits are added to hits(1:n)

integer, intent(inout) :: n

number of hits


Calls

proc~~marker_pick~~CallsGraph proc~marker_pick marker_pick proc~add_pick_hit add_pick_hit proc~marker_pick->proc~add_pick_hit proc~better better proc~marker_pick->proc~better proc~drawn_marker MarkerArtist%drawn_marker proc~marker_pick->proc~drawn_marker proc~point_pick point_pick proc~marker_pick->proc~point_pick proc~source_points source_points proc~marker_pick->proc~source_points proc~point LineChain%point proc~drawn_marker->proc~point proc~project project proc~point_pick->proc~project proc~num_points Trajectory%num_points proc~source_points->proc~num_points proc~verify_data Trajectory%verify_data proc~source_points->proc~verify_data proc~line_buffer line_buffer proc~point->proc~line_buffer interface~vkf_line_points vkf_line_points proc~line_buffer->interface~vkf_line_points

Called by

proc~~marker_pick~~CalledByGraph proc~marker_pick marker_pick proc~drawable_pick DrawableTrajectory%drawable_pick proc~drawable_pick->proc~marker_pick

Source Code

    subroutine marker_pick(a, frame, cam, m, hits, n)
        class(MarkerArtist), intent(in), target :: a !! the artist
        class(ReferenceFrame), intent(in), target :: frame  !! the frame drawing it (for the hit)
        type(PickCamera), intent(in) :: cam         !! the pick camera
        real(wp), intent(in) :: m(4,4)              !! the frame's transform to the root frame
        type(PickHit), allocatable, intent(inout) :: hits(:)  !! hits are added to hits(1:n)
        integer, intent(inout) :: n                 !! number of hits
        real(wp) :: extra, v(3), px, depth, best_px, best_depth, best_v(3)
        integer :: k, which, best_which, best_k, npts
        type(PickHit) :: h
        extra = 0.5_wp * a%size_ * cam%pixel_ratio
        best_px = huge(1.0_wp)
        best_depth = huge(1.0_wp)
        best_which = 0
        best_k = 0
        best_v = 0.0_wp
        do which = 1, 3                                         ! start, end, the intermediate ones
            select case (which)
            case (1)
                if (a%drawn_marker(MARKER_START, v)) call consider(MARKER_START, 0)
            case (2)
                if (a%drawn_marker(MARKER_END, v)) call consider(MARKER_END, 0)
            case (3)
                do k = a%inter_first, a%inter_first + a%n_inter_drawn - 1
                    if (a%drawn_marker(MARKER_INTERMEDIATE, v, k)) call consider(MARKER_INTERMEDIATE, k)
                end do
            end select
        end do
        if (best_which == 0) return
        h%kind = PICK_MARKER
        h%frame => frame
        h%artist => a
        h%marker = best_which
        npts = 0
        if (associated(a%traj)) then
            h%trajectory => a%traj
            npts = source_points(a%traj, a%sources_)
        end if
        select case (best_which)
        case (MARKER_START)
            h%index = min(1, npts)
            if (npts > 0) h%time = a%traj%time(1)
        case (MARKER_END)
            h%index = npts
            if (npts > 0) h%time = a%traj%time(npts)
        case default
            h%index = best_k
            h%time = a%inter_t(best_k)
        end select
        h%local = best_v
        h%position = matmul(m(1:3, 1:3), best_v) + m(1:3, 4)
        h%distance = best_depth
        h%pixels = best_px
        call add_pick_hit(hits, n, h)

    contains

        !> Take the marker at `v` (`kind`, intermediate number k) as the best hit if picked and better.
        subroutine consider(kind, k)
            integer, intent(in) :: kind, k                  !! MARKER_START, _END or _INTERMEDIATE; its number
            if (.not. point_pick(cam, matmul(m(1:3, 1:3), v) + m(1:3, 4), px, depth, extra)) return
            if (.not. better(px, depth, best_px, best_depth)) return
            best_px = px
            best_depth = depth
            best_which = kind
            best_k = k
            best_v = v
        end subroutine consider

    end subroutine marker_pick