向量夹角的计算

发布于 2023-11-15  407 次阅读


Please refresh the page if equations are not rendered correctly.
---------------------------------------------------------------

与以下代码相似的功能已经集成在PolyKriging包的Vector类中。

可以使用如下的方式导入和调用:

from polykriging.geometry import Vector

v1 = Vector((1, 2, 3))
v2 = Vector((4, 5, 7))

# 2-norm (length of vector)
v1.norm
v2.norm

# unit vector
v1/v1.norm
v2/v2.norm

# angle between v1 and v2
v1.angle_between(v2, radian=False) # default in degrees
v1.angle_between(v2, radian=True) # in radian

旧代码:

import numpy as np

def isInbBox(bbox, point):
    '''
    Determine if point is within a bounding box
    that parallel to the principle aixes in Cartesian coordinate.

    Parameters
    ----------
    bbox : array_like
        The bounding box, [[xmin, ymin, zmin], [xmax, ymax, zmax]]
    point : array_like
        The point, [x, y, z]

    Return:
    -------
    bool
        True if the point is within the bounding box, False otherwise.
    '''
    x, y, z = point[0], point[1], point[2]
    xmin, ymin, zmin   = bbox[0][0], bbox[0][1], bbox[0][2]
    xmax, ymax, zmax = bbox[1][0], bbox[1][1], bbox[1][2]
    boolst = [True, True, True, False, False, False]
    boo = [x>xmin, y > ymin, z > zmin, x > xmax, y> ymax, z > zmax]
    return boo == boolst


def unitVector(vector):
    """
    Returns the unit vector of the vector.

    Parameters
    ----------
    vector : array_like
        The vector, [x, y, z]

    Return:
    -------
        array_like
        The unit vector, [x, y, z]
    """
    if not isinstance(vector, np.ndarray):
        vector  = np.array(vector)
    return vector / np.linalg.norm(vector)


def angle_between(v1, v2, radian = False):
    """ Returns the angle in radians between vectors 'v1' and 'v2'.

    numpy.clip(a, a_min, a_max, out=None, **kwargs)[source]
    Clip (limit) the values in an array.     Given an interval, values outside the interval
    are clipped to the interval edges. For example, if an interval of [0, 1] is specified,
    values smaller than 0 become 0, and values larger than 1 become 1.
    Equivalent to but faster than np.minimum(a_max, np.maximum(a, a_min)).
    No check is performed to ensure a_min < a_max.

    Parameters
    ----------
    v1 : array_like
        The vector, [x, y, z]
    v2 : array_like
        The vector, [x, y, z]
    radian : bool, optional
        If True, return the angle in radians, otherwise in degrees.

    Return:
    -------
        float
        The angle between vectors 'v1' and 'v2'.
    """
    v1_u = unitVector(v1)
    v2_u = unitVector(v2)

    if radian:
        return np.arccos(np.clip(np.dot(v1_u, v2_u), -1.0, 1.0))
    else:
        return np.rad2deg(np.arccos(np.clip(np.dot(v1_u, v2_u), -1.0, 1.0)))
Everything not saved will be lost.
最后更新于 2023-11-15