コード例 #1
0
def quaternion_between_vectors(v1: np.ndarray, v2: np.ndarray) -> quaternion:
    """
    Construct rotation quaternion to rotate direction given by v1 towards v2

    :param v1: "source" direction
    :param v2: "destination" direction
    :return: Quaternion of rotation, such that ret.rotate(v1) == v2
    """

    v1 = vector_normalize(v1)
    v2 = vector_normalize(v2)

    if np.allclose(v1, - v2):
        return quaternion_from_scalar_and_vector(scalar=0, vector=vector_normalize(orthogonal(v1)))

    half = vector_normalize(v1 + v2)
    # noinspection PyTypeChecker
    return quaternion_from_scalar_and_vector(scalar=np.dot(v1, half), vector=np.cross(v1, half))
コード例 #2
0
def look_at(eyePosition3D, center3D, upVector3D):
    """
    Reimplementation of lookat from opengl. Very likely broken very much.
    """
    matrix = np.zeros(16)

    forward = vector_normalize(center3D - eyePosition3D)

    # Side = forward x up
    side = np.zeros(3)
    side[0] = (forward[1] * upVector3D[2]) - (forward[2] * upVector3D[1])
    side[1] = (forward[2] * upVector3D[0]) - (forward[0] * upVector3D[2])
    side[2] = (forward[0] * upVector3D[1]) - (forward[1] * upVector3D[0])
    side = vector_normalize(side)
    # Recompute up as: up = side x forward
    up = np.zeros(3)
    up[0] = (side[1] * forward[2]) - (side[2] * forward[1])
    up[1] = (side[2] * forward[0]) - (side[0] * forward[2])
    up[2] = (side[0] * forward[1]) - (side[1] * forward[0])
    #print(side, up, forward)
    matrix[0] = side[0]
    matrix[4] = side[1]
    matrix[8] = side[2]
    # matrix[12] = 0.0
    # --------------------
    matrix[1] = up[0]
    matrix[5] = up[1]
    matrix[9] = up[2]
    # matrix[13] = 0.0
    # --------------------
    matrix[2] = -forward[0]
    matrix[6] = -forward[1]
    matrix[10] = -forward[2]
    # matrix[14] = 0.0
    # --------------------
    # matrix[3] = matrix[7] = matrix[11] = 0.0
    matrix[15] = 1.0
    # --------------------
    res = np.reshape(matrix, (4, 4))
    tm = translation_matrix(-eyePosition3D)

    return res @ tm
コード例 #3
0
def quaternion_slerp_old(quat0: np.ndarray, quat1: np.ndarray, fraction, spin=0, shortestpath=True):
    """Return spherical linear interpolation between two quaternions.

    >>> _q0 = random_quaternion()
    >>> _q1 = random_quaternion()
    >>> q = quaternion_slerp(_q0, _q1, 0)
    >>> np.allclose(q, _q0)
    True
    >>> q = quaternion_slerp(_q0, _q1, 1, 1)
    >>> np.allclose(q, _q1)
    True
    >>> q = quaternion_slerp(_q0, _q1, 0.5)
    >>> ang = acos(np.dot(_q0, q))
    >>> np.allclose(2, acos(np.dot(_q0, _q1)) / ang) or np.allclose(2, acos(-np.dot(_q0, _q1)) / ang)
    True

    """
    q0 = vector_normalize(quat0)
    q1 = vector_normalize(quat1)
    if fraction == 0.0:
        return q0
    elif fraction == 1.0:
        return q1
    d = np.dot(q0, q1)
    if abs(abs(d) - 1.0) < EPS:
        return q0
    if shortestpath and d < 0.0:
        # invert rotation
        d = -d
        np.negative(q1, q1)
    angle = acos(d) + spin * pi
    if abs(angle) < EPS:
        return q0
    isin = 1.0 / sin(angle)
    q0 *= sin((1.0 - fraction) * angle) * isin
    q1 *= sin(fraction * angle) * isin
    q0 += q1
    return q0