sphere_near Function

public function sphere_near(cam, c, r, extra) result(near)

A sphere (root frame: center c, radius r) might be within the tolerance (plus extra pixels) of the cursor on the screen (false only if it surely isn't: to skip what it bounds).

Arguments

Type IntentOptional Attributes Name
type(PickCamera), intent(in) :: cam

the camera and cursor of the pick

real(kind=wp), intent(in) :: c(3)

the sphere's center (root frame) and radius (scene units)

real(kind=wp), intent(in) :: r

the sphere's center (root frame) and radius (scene units)

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

added to the tolerance (framebuffer pixels)

Return Value logical


Calls

proc~~sphere_near~~CallsGraph proc~sphere_near sphere_near proc~project project proc~sphere_near->proc~project

Called by

proc~~sphere_near~~CalledByGraph proc~sphere_near sphere_near proc~curve_pick curve_pick proc~curve_pick->proc~sphere_near proc~drawable_pick DrawableTrajectory%drawable_pick proc~drawable_pick->proc~curve_pick

Source Code

    logical function sphere_near(cam, c, r, extra) result(near)
        type(PickCamera), intent(in) :: cam                 !! the camera and cursor of the pick
        real(wp), intent(in) :: c(3), r                     !! the sphere's center (root frame) and radius (scene units)
        real(wp), intent(in), optional :: extra             !! added to the tolerance (framebuffer pixels)
        real(wp) :: sx, sy, depth, scale, reach
        near = .true.
        if (dot_product(c - cam%eye, cam%forward) - r > cam%max_depth) then   ! (all deeper than a hit already found)
            near = .false.
            return
        end if
        if (cam%perspective) then
            depth = dot_product(c - cam%eye, cam%forward)
            if (depth <= r + cam%near) then                     ! (the eye inside it, or close: can't tell)
                near = depth > -r
                return
            end if
            if (.not. project(cam, c, sx, sy, depth)) return
            scale = cam%half_h / (cam%tan_y * (depth - r))      ! pixels per scene unit at its nearest
        else
            if (.not. project(cam, c, sx, sy, depth)) return
            scale = 2.0_wp * cam%half_h / (cam%ortho(4) - cam%ortho(3))
        end if
        reach = cam%tolerance
        if (present(extra)) reach = reach + extra
        near = hypot(sx, sy) <= r * scale + reach
    end function sphere_near