Source code for pyrr.plane

# -*- coding: utf-8 -*-
"""Provide functions for the creation and manipulation of Planes.

Planes are represented using a numpy.array of shape (4,).
The values represent the plane equation using the values A,B,C,D.

The first three values are the normal vector.
The fourth value is the distance of the origin from the plane, down the normal.
A negative value indicates the origin is behind the plane, relative to the normal.

.. seealso: http://en.wikipedia.org/wiki/Plane_(geometry)
.. seealso: http://mathworld.wolfram.com/Plane.html
"""
from __future__ import absolute_import, division, print_function
import numpy as np
from . import vector
from .utils import all_parameters_as_numpy_arrays, parameters_as_numpy_arrays


[docs]def create(normal=None, distance=0.0, dtype=None): """Creates a plane oriented toward the normal, at distance below the origin. If no normal is provided, the plane will by created at the origin with a normal of [0, 0, 1]. Negative distance indicates the plane is facing toward the origin. :rtype: numpy.array :return: A plane with the specified normal at a distance from the origin of -distance. """ if normal is None: normal = [0.0, 0.0, 1.0] return np.array([normal[0], normal[1], normal[2], distance], dtype=dtype)
[docs]@parameters_as_numpy_arrays('vector1', 'vector2', 'vector3') def create_from_points(vector1, vector2, vector3, dtype=None): """Create a plane from 3 co-planar vectors. The vectors must all lie on the same plane or an exception will be thrown. The vectors must not all be in a single line or the plane is undefined. The order the vertices are passed in will determine the normal of the plane. :param numpy.array vector1: a vector that lies on the desired plane. :param numpy.array vector2: a vector that lies on the desired plane. :param numpy.array vector3: a vector that lies on the desired plane. :raise ValueError: raised if the vectors are co-incident (in a single line). :rtype: numpy.array :return: A plane that contains the 3 specified vectors. """ dtype = dtype or vector1.dtype # make the vectors relative to vector2 relV1 = vector1 - vector2 relV2 = vector3 - vector2 # cross our relative vectors normal = np.cross(relV1, relV2) if np.count_nonzero(normal) == 0: raise ValueError("Vectors are co-incident") # create our plane return create_from_position(position=vector2, normal=normal, dtype=dtype)
[docs]@parameters_as_numpy_arrays('position', 'normal') def create_from_position(position, normal, dtype=None): """Creates a plane at position with the normal being above the plane and up being the rotation of the plane. :param numpy.array position: The position of the plane. :param numpy.array normal: The normal of the plane. Will be normalized during construction. :rtype: numpy.array :return: A plane that crosses the specified position with the specified normal. """ dtype = dtype or position.dtype # -d = a * x + b * y + c * z n = vector.normalize(normal) d = -np.sum(n * position) return create(n, -d, dtype)
[docs]def create_xy(invert=False, distance=0., dtype=None): """Create a plane on the XY plane, starting at the origin with +Z being the up vector. The plane is distance units along the Z axis. -Z if inverted. """ pl = np.array([0., 0., 1., distance]) if invert: pl = invert_normal(pl) return pl
[docs]def create_xz(invert=False, distance=0., dtype=None): """Create a plane on the XZ plane, starting at the origin with +Y being the up vector. The plane is distance units along the Y axis. -Y if inverted. """ pl = np.array([0., 1., 0., distance]) if invert: pl = invert_normal(pl) return pl
[docs]def create_yz(invert=False, distance=0., dtype=None): """Create a plane on the YZ plane, starting at the origin with +X being the up vector. The plane is distance units along the X axis. -X if inverted. """ pl = np.array([1., 0., 0., distance]) if invert: pl = invert_normal(pl) return pl
[docs]def invert_normal(plane): """Flips the normal of the plane. The plane is **not** changed in place. :rtype: numpy.array :return: The plane with the normal inverted. """ # flip the normal, and the distance return -plane
[docs]def position(plane): """Extracts the position vector from a plane. This will be a vector co-incident with the plane's normal. :param numpy.array plane: The plane. :rtype: numpy.array :return: A valid position that lies on the plane. """ return normal(plane) * distance(plane)
[docs]def normal(plane): """Extracts the normal vector from a plane. :param numpy.array plane: The plane. :rtype: numpy.array :return: The normal vector of the plane. """ return plane[:3].copy()
[docs]def distance(plane): """Distance the plane is from the origin along its the normal. Negative value indicates the plane is facing the origin. """ return plane[3]