quat_from_vectors Function

public pure function quat_from_vectors(from, to) result(q)

The shortest rotation taking the direction of from to that of to (OpenSceneGraph's osg::Quat::makeRotate(from, to)); a half turn about a perpendicular axis if they are opposite, the identity if either is zero.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: from(3)

directions (any length)

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

directions (any length)

Return Value real(kind=wp), (4)


Calls

proc~~quat_from_vectors~~CallsGraph proc~quat_from_vectors quat_from_vectors proc~cross cross proc~quat_from_vectors->proc~cross proc~quat_normalize quat_normalize proc~quat_from_vectors->proc~quat_normalize

Called by

proc~~quat_from_vectors~~CalledByGraph proc~quat_from_vectors quat_from_vectors proc~place place proc~place->proc~quat_from_vectors proc~world_to_view View%world_to_view proc~world_to_view->proc~quat_from_vectors proc~fly fly proc~fly->proc~world_to_view proc~get_camera WindowProxy%get_camera proc~get_camera->proc~world_to_view proc~home View%home proc~home->proc~world_to_view proc~place_camera place_camera proc~place_camera->proc~world_to_view proc~place_camera->proc~fly proc~place_camera->proc~home proc~set_camera WindowProxy%set_camera proc~set_camera->proc~world_to_view proc~shadow_late_update ShadowCones%shadow_late_update proc~shadow_late_update->proc~place proc~track_view track_view proc~track_view->proc~world_to_view proc~frame WindowProxy%frame proc~frame->proc~place_camera proc~frame->proc~track_view proc~dispatch_events dispatch_events proc~frame->proc~dispatch_events proc~view_camera view_camera proc~view_camera->proc~get_camera proc~cursor_ray WindowProxy%cursor_ray proc~cursor_ray->proc~view_camera proc~resize WindowProxy%resize proc~resize->proc~frame proc~run WindowProxy%run proc~run->proc~frame proc~screen_position WindowProxy%screen_position proc~screen_position->proc~view_camera proc~window_pick WindowProxy%window_pick proc~window_pick->proc~view_camera proc~drag_handle drag_handle proc~drag_handle->proc~cursor_ray proc~grab_handle grab_handle proc~grab_handle->proc~cursor_ray proc~hover_handle hover_handle proc~hover_handle->proc~window_pick proc~dispatch_event dispatch_event proc~dispatch_event->proc~drag_handle proc~dispatch_event->proc~grab_handle proc~dispatch_event->proc~hover_handle proc~release_handle release_handle proc~dispatch_event->proc~release_handle proc~release_handle->proc~hover_handle proc~dispatch_events->proc~dispatch_event

Source Code

    pure function quat_from_vectors(from, to) result(q)
        real(wp), intent(in) :: from(3), to(3)          !! directions (any length)
        real(wp) :: q(4)
        real(wp), parameter :: eps = 1.0e-12_wp
        real(wp) :: u(3), v(3), d, axis(3)
        q = quat_identity
        if (norm2(from) == 0.0_wp .or. norm2(to) == 0.0_wp) return
        u = from / norm2(from)
        v = to / norm2(to)
        d = dot_product(u, v)
        if (d >= 1.0_wp - eps) return
        if (d <= -1.0_wp + eps) then
            axis = cross(u, [1.0_wp, 0.0_wp, 0.0_wp])
            if (norm2(axis) < 1.0e-6_wp) axis = cross(u, [0.0_wp, 1.0_wp, 0.0_wp])
            q = [axis / norm2(axis), 0.0_wp]
            return
        end if
        q = quat_normalize([cross(u, v), 1.0_wp + d])
    end function quat_from_vectors