A marker artist's best hit: its start, end and intermediate markers drawn.
| Type | Intent | Optional | 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 |
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