Пример #1
0
def volume_tetrahedron(
    point_a: array_like,
    point_b: array_like,
    point_c: array_like,
    point_d: array_like,
) -> np.float64:
    """
    Return the volume of a tetrahedron defined by four points.

    The points are the vertices of the tetrahedron. They must be 3D or less.

    Parameters
    ----------
    point_a, point_b, point_c, point_d : array_like
        The four vertices of the tetrahedron.

    Returns
    -------
    np.float64
        The volume of the tetrahedron.

    References
    ----------
    http://mathworld.wolfram.com/Tetrahedron.html

    Examples
    --------
    >>> from skspatial.measurement import volume_tetrahedron

    >>> volume_tetrahedron([0, 0], [3, 2], [-3, 5], [1, 8])
    0.0

    >>> volume_tetrahedron([0, 0, 0], [2, 0, 0], [1, 1, 0], [0, 0, 1]).round(3)
    0.333

    >>> volume_tetrahedron([0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]).round(3)
    0.167

    """
    vector_ab = Vector.from_points(point_a, point_b)
    vector_ac = Vector.from_points(point_a, point_c)
    vector_ad = Vector.from_points(point_a, point_d)

    vector_cross = vector_ac.cross(vector_ad)

    # Set the dimension to 3 so it matches the cross product.
    vector_ab = vector_ab.set_dimension(3)

    return 1 / 6 * abs(vector_ab.dot(vector_cross))
Пример #2
0
def test_project_point(lines_or_planes, data):
    """Test projecting a point onto a line or plane."""

    dim = data.draw(st.integers(min_value=DIM_MIN, max_value=DIM_MAX))

    array = data.draw(arrays_fixed(dim))
    line_or_plane = data.draw(lines_or_planes(dim))

    point_projected = line_or_plane.project_point(array)

    # The projected point should lie on the line/plane.
    assert line_or_plane.contains_point(point_projected, abs_tol=ATOL)

    # The vector from the point to its projection
    # should be perpendicular to the line/plane.
    vector_projection = Vector.from_points(array, point_projected)

    # The distance from the point to its projection
    # should equal the distance to the line/plane.
    distance_projection = vector_projection.norm()
    distance_to_object = abs(line_or_plane.distance_point(array))
    assert math.isclose(distance_to_object, distance_projection, rel_tol=1e-6)

    # The distance of the projection should be the
    # shortest distance from the point to the object.
    distance_points = line_or_plane.point.distance_point(array)
    assert distance_projection < distance_points or math.isclose(
        distance_projection, distance_points)
Пример #3
0
def test_from_points(arrays):

    array_a, array_b = arrays

    point_a = Point(array_a)
    vector_ab = Vector.from_points(array_a, array_b)

    assert (point_a + vector_ab).is_close(array_b)
Пример #4
0
def area_triangle(point_a: array_like, point_b: array_like,
                  point_c: array_like) -> np.float64:
    """
    Return the area of a triangle defined by three points.

    The points are the vertices of the triangle. They must be 3D or less.

    Parameters
    ----------
    point_a, point_b, point_c : array_like
        The three vertices of the triangle.

    Returns
    -------
    np.float64
        The area of the triangle.

    References
    ----------
    http://mathworld.wolfram.com/TriangleArea.html

    Examples
    --------
    >>> from skspatial.measurement import area_triangle

    >>> area_triangle([0, 0], [0, 1], [1, 0])
    0.5

    >>> area_triangle([0, 0], [0, 2], [1, 1])
    1.0

    >>> area_triangle([3, -5, 1], [5, 2, 1], [9, 4, 2]).round(2)
    12.54

    """
    vector_ab = Vector.from_points(point_a, point_b)
    vector_ac = Vector.from_points(point_a, point_c)

    # Normal vector of plane defined by the three points.
    vector_normal = vector_ab.cross(vector_ac)

    return 0.5 * vector_normal.norm()
Пример #5
0
"""
Point-Plane Projection
======================

Project a point onto a plane.

"""
from skspatial.objects import Plane
from skspatial.objects import Point
from skspatial.objects import Vector
from skspatial.plotting import plot_3d


plane = Plane(point=[0, 0, 2], normal=[1, 0, 2])
point = Point([5, 9, 3])

point_projected = plane.project_point(point)
vector_projection = Vector.from_points(point, point_projected)


plot_3d(
    plane.plotter(lims_x=(0, 10), lims_y=(0, 15), alpha=0.3),
    point.plotter(s=75, c='k'),
    point_projected.plotter(c='r', s=75, zorder=3),
    vector_projection.plotter(point=point, c='k', linestyle='--'),
)
Пример #6
0
def test_from_points(array_a, array_b, vector_expected):

    assert_array_equal(Vector.from_points(array_a, array_b), vector_expected)
def spatial_parameters(point_a_i: array_like, point_b: array_like,
                       point_a_f: array_like) -> Dict[str, np.float64]:
    """
    Calculate spatial gait parameters for a stride.

    Positions are input in temporal order
    (foot A initial, foot B, foot A final).

    Parameters
    ----------
    point_a_i : array_like
        Initial position of foot A.
    point_b : array_like
        Position of foot B.
    point_a_f : array_like
        Final position of foot A.

    Returns
    -------
    dict
        Dictionary consisting of stride length, absolute step length, step length,
        and stride width.

    Examples
    --------
    >>> import numpy as np

    >>> point_l_1 = [764.253, 28.798]
    >>> point_r_1 = [696.834, 37.141]

    >>> point_l_2 = [637.172, 24.508]
    >>> point_r_2 = [579.102, 35.457]

    >>> point_l_3 = [518.030, 30.507]

    >>> values = list(spatial_parameters(point_l_1, point_r_1, point_l_2).values())
    >>> np.round(values, 1)
    array([127.2,  61. ,  60.1,  10.6])

    >>> values = list(spatial_parameters(point_r_1, point_l_2, point_r_2).values())
    >>> np.round(values, 1)
    array([117.7,  59.1,  57.9,  11.8])

    >>> values = list(spatial_parameters(point_l_2, point_r_2, point_l_3).values())
    >>> np.round(values, 1)
    array([119.3,  61.3,  60.7,   8. ])

    """
    line_a = Line.from_points(point_a_i, point_a_f)

    point_b_proj = line_a.project_point(point_b)

    stride_length = line_a.direction.norm()

    absolute_step_length = Vector.from_points(point_b, point_a_f).norm()
    step_length = Vector.from_points(point_b_proj, point_a_f).norm()

    stride_width = Vector.from_points(point_b_proj, point_b).norm()

    return {
        'stride_length': stride_length,
        'absolute_step_length': absolute_step_length,
        'step_length': step_length,
        'stride_width': stride_width,
    }