1.2.1. Points and Vectors

1.2.1.1. Two Dimensions

class raysect.core.math.point.Point2D

Represents a point in 2D affine space.

A 2D point is a location in 2D space which is defined by its x and y coordinates in a given coordinate system. Vector2D objects can be added/subtracted from Point2D yielding another Vector2D. You can also find the Vector2D and distance between two Point2Ds, and transform a Point2D from one coordinate system to another.

If no initial values are passed, Point2D defaults to the origin: Point2D(0.0, 0.0)

Parameters:
  • x (float) – initial x coordinate, defaults to x = 0.0.
  • y (float) – initial y coordinate, defaults to y = 0.0.
Variables:
  • x (float) – x-coordinate
  • y (float) – y-coordinate
>>> from raysect.core import Point2D
>>>
>>> a = Point2D(1, 1)
__add__

Addition operator.

>>> Point2D(1, 0) + Vector2D(0, 1)
Point2D(1.0, 1.0)
__getitem__

Returns the point coordinates by index ([0,1] -> [x,y]).

>>> a = Point2D(1, 0)
>>> a[0]
1
__iter__

Iterates over the coordinates (x, y)

>>> a = Point2D(1, 1)
>>> x, y = a
>>> x, y
(1.0, 1.0)
__setitem__

Sets the point coordinates by index ([0,1] -> [x,y]).

>>> a = Point2D(1, 0)
>>> a[1] = 2
>>> a
Point2D(1.0, 2.0)
__sub__

Subtraction operator.

>>> Point2D(1, 0) - Vector2D(0, 1)
Point2D(1.0, -1.0)
copy()

Returns a copy of the point.

Return type:Point2D
>>> a = Point2D(1, 1)
>>> a.copy()
Point2D(1.0, 1.0)
distance_to()

Returns the distance between this point and the passed point.

Parameters:p (Point2D) – the point to which the distance will be calculated
Return type:float
>>> a = Point2D(1, 0)
>>> b = Point2D(1, 1)
>>> a.distance_to(b)
1.0
vector_to()

Returns a vector from this point to the passed point.

Parameters:p (Point2D) – point to which a vector will be calculated
Return type:Vector2D
>>> a = Point2D(1, 0)
>>> b = Point2D(1, 1)
>>> a.vector_to(b)
Vector2D(0.0, 1.0)
class raysect.core.math.vector.Vector2D

Represents a vector in 2D space.

2D vectors are described by their (x, y) coordinates. Standard Vector2D operations are supported such as addition, subtraction, scaling, dot product, cross product and normalisation.

If no initial values are passed, Vector2D defaults to a unit vector aligned with the x-axis: Vector2D(1.0, 0.0)

Parameters:
  • x (float) – initial x coordinate, defaults to x = 0.0.
  • y (float) – initial y coordinate, defaults to y = 0.0.
Variables:
  • x (float) – x-coordinate
  • y (float) – y-coordinate
>>> from raysect.core import Vector2D
>>> a = Vector2D(1, 0)
__add__

Addition operator.

>>> Vector2D(1, 0) + Vector2D(0, 1)
Vector2D(1.0, 1.0)
__getitem__

Returns the vector coordinates by index ([0,1] -> [x,y]).

>>> a = Vector2D(1, 0)
>>> a[0]
1
__iter__

Iterates over the vector coordinates (x, y)

>>> a = Vector2D(1, 0)
>>> x, y = a
>>> x, y
(1.0, 0.0)
__mul__

Multiplication operator.

>>> 2 * Vector3D(1, 2)
Vector2D(2.0, 4.0)
__neg__

Returns a vector with the reverse orientation (negation operator).

>>> a = Vector2D(1, 0)
>>> -a
Vector2D(-1.0, -0.0)
__setitem__

Sets the vector coordinates by index ([0,1] -> [x,y]).

>>> a = Vector2D(1, 0)
>>> a[1] = 2
>>> a
Vector2D(1.0, 2.0)
__sub__

Subtraction operator.

>>> Vector2D(1, 0) - Vector2D(0, 1)
Vector2D(1.0, -1.0)
__truediv__

Division operator.

>>> Vector2D(1, 1) / 2
Vector2D(0.5, 0.5)
copy()

Returns a copy of the vector.

Return type:Vector2D
>>> a = Vector2D(1, 1)
>>> a.copy()
Vector2D(1.0, 1.0)
cross()

Calculates the 2D cross product analogue between this vector and the supplied vector

C = A.cross(B) <=> C = A x B <=> det(A, B) = A.x B.y - A.y B.x

Note that for 2D vectors, the cross product is the equivalent of the determinant of a 2x2 matrix. The result is a scalar.

Parameters:v (Vector2D) – An input vector with which to calculate the cross product.
Return type:float
>>> a = Vector2D(1, 1)
>>> b = Vector2D(0, 1)
>>> a.cross(b)
>>> 1.0
dot()

Calculates the dot product between this vector and the supplied vector.

Return type:float
>>> a = Vector2D(1, 1)
>>> b = Vector2D(0, 1)
>>> a.dot(b)
1.0
length

The vector’s length.

Raises a ZeroDivisionError if an attempt is made to change the length of a zero length vector. The direction of a zero length vector is undefined hence it can not be lengthened.

>>> a = Vector2D(1, 1)
>>> a.length
1.4142135623730951
normalise()

Returns a normalised copy of the vector.

The returned vector is normalised to length 1.0 - a unit vector.

Return type:Vector2D
>>> a = Vector2D(1, 1)
>>> a.normalise()
Vector2D(0.7071067811865475, 0.7071067811865475)
orthogonal()

Returns a unit vector that is guaranteed to be orthogonal to the vector.

Return type:vector2D
>>> a = Vector2D(1, 1)
>>> a.orthogonal()
Vector2D(-0.7071067811865475, 0.7071067811865475

1.2.1.2. Three Dimensions

class raysect.core.math.point.Point3D

Represents a point in 3D affine space.

A point is a location in 3D space which is defined by its x, y and z coordinates in a given coordinate system. Vectors can be added/subtracted from Points yielding another Vector3D. You can also find the Vector3D and distance between two Points, and transform a Point3D from one coordinate system to another.

If no initial values are passed, Point3D defaults to the origin: Point3D(0.0, 0.0, 0.0)

Parameters:
  • x (float) – initial x coordinate, defaults to x = 0.0.
  • y (float) – initial y coordinate, defaults to y = 0.0.
  • z (float) – initial z coordinate, defaults to z = 0.0.
Variables:
  • x (float) – x-coordinate
  • y (float) – y-coordinate
  • z (float) – z-coordinate
>>> from raysect.core import Point3D
>>> a = Point3D(0, 1, 2)
__add__

Addition operator.

>>> Point3D(1, 0, 0) + Vector3D(0, 1, 0)
Point3D(1.0, 1.0, 0.0)
__getitem__

Returns the point coordinates by index ([0,1,2] -> [x,y,z]).

>>> a = Point3D(1, 0, 0)
>>> a[0]
1
__iter__

Iterates over the coordinates (x, y, z)

>>> a = Point3D(0, 1, 2)
>>> x, y, z = a
>>> x, y, z
(0.0, 1.0, 2.0)
__mul__

Multiplication operator.

Parameters:
Returns:

Matrix multiplication of a 3D transformation matrix with the input point.

Return type:

Point3D

__setitem__

Sets the point coordinates by index ([0,1,2] -> [x,y,z]).

>>> a = Point3D(1, 0, 0)
>>> a[1] = 2
>>> a
Point3D(1.0, 2.0, 0.0)
__sub__

Subtraction operator.

>>> Point3D(1, 0, 0) - Vector3D(0, 1, 0)
Point3D(1.0, -1.0, 0.0)
copy()

Returns a copy of the point.

Return type:Point3D
>>> a = Point3D(0, 1, 2)
>>> a.copy()
Point3D(0.0, 1.0, 2.0)
distance_to()

Returns the distance between this point and the passed point.

Parameters:p (Point3D) – the point to which the distance will be calculated
Return type:float
>>> a = Point3D(0, 1, 2)
>>> b = Point3D(1, 1, 1)
>>> a.distance_to(b)
1.4142135623730951
transform()

Transforms the point with the supplied Affine Matrix.

The point is transformed by premultiplying the point by the affine matrix.

For cython code this method is substantially faster than using the multiplication operator of the affine matrix.

This method expects a valid affine transform. For speed reasons, minimal checks are performed on the matrix.

Parameters:m (AffineMatrix3D) – The affine matrix describing the required coordinate transformation.
Returns:A new instance of this point that has been transformed with the supplied Affine Matrix.
Return type:Point3D
vector_to()

Returns a vector from this point to the passed point.

Parameters:p (Point3D) – the point to which a vector will be calculated.
Return type:Vector3D
>>> a = Point3D(0, 1, 2)
>>> b = Point3D(1, 1, 1)
>>> a.vector_to(b)
Vector3D(1.0, 0.0, -1.0)
class raysect.core.math.vector.Vector3D

Represents a vector in 3D affine space.

Vectors are described by their (x, y, z) coordinates in the chosen coordinate system. Standard Vector3D operations are supported such as addition, subtraction, scaling, dot product, cross product, normalisation and coordinate transformations.

If no initial values are passed, Vector3D defaults to a unit vector aligned with the z-axis: Vector3D(0.0, 0.0, 1.0)

Parameters:
  • x (float) – initial x coordinate, defaults to x = 0.0.
  • y (float) – initial y coordinate, defaults to y = 0.0.
  • z (float) – initial z coordinate, defaults to z = 0.0.
Variables:
  • x (float) – x-coordinate
  • y (float) – y-coordinate
  • z (float) – z-coordinate
>>> from raysect.core import Vector3D
>>> a = Vector3D(1, 0, 0)
__add__

Addition operator.

>>> Vector3D(1, 0, 0) + Vector3D(0, 1, 0)
Vector3D(1.0, 1.0, 0.0)
__getitem__

Returns the vector coordinates by index ([0,1,2] -> [x,y,z]).

>>> a = Vector3D(1, 0, 0)
>>> a[0]
1
__iter__

Iterates over the vector coordinates (x, y, z)

>>> a = Vector3D(0, 1, 2)
>>> x, y, z = a
>>> x, y, z
(0.0, 1.0, 2.0)
__mul__

Multiplication operator.

3D vectors can be multiplied with both scalars and transformation matrices.

>>> from raysect.core import Vector3D, rotate_x
>>> 2 * Vector3D(1, 2, 3)
Vector3D(2.0, 4.0, 6.0)
>>> rotate_x(90) * Vector3D(0, 0, 1)
Vector3D(0.0, -1.0, 0.0)
__neg__

Returns a vector with the reverse orientation (negation operator).

>>> a = Vector3D(1, 0, 0)
>>> -a
Vector3D(-1.0, -0.0, -0.0)
__setitem__

Sets the vector coordinates by index ([0,1,2] -> [x,y,z]).

>>> a = Vector3D(1, 0, 0)
>>> a[1] = 2
>>> a
Vector3D(1.0, 2.0, 0.0)
__sub__

Subtraction operator.

>>> Vector3D(1, 0, 0) - Vector3D(0, 1, 0)
Vector3D(1.0, -1.0, 0.0)
__truediv__

Division operator.

>>> Vector3D(1, 1, 1) / 2
Vector3D(0.5, 0.5, 0.5)
angle()

Calculates the angle between this vector and the supplied vector.

Returns the angle in degrees.

>>> a = Vector3D(1, 1, 1)
>>> b = Vector3D(1, 0, 0)
>>> a.angle(b)
54.735610317245346
copy()

Returns a copy of the vector.

Return type:Vector3D
>>> a = Vector3D(1, 1, 1)
>>> a.copy()
Vector3D(1.0, 1.0, 1.0)
cross()

Calculates the cross product between this vector and the supplied vector

C = A.cross(B) <=> \(\vec{C} = \vec{A} \times \vec{B}\)

Parameters:v (Vector3D) – An input vector with which to calculate the cross product.
Return type:Vector3D
>>> a = Vector3D(1, 0, 0)
>>> b= Vector3D(0, 1, 0)
>>> a.cross(b)
Vector3D(0.0, 0.0, 1.0)
dot()

Calculates the dot product between this vector and the supplied vector.

Return type:float
>>> a = Vector3D(1, 1, 1)
>>> b = Vector3D(1, 0, 0)
>>> a.dot(b)
1.0
length

The vector’s length.

Raises a ZeroDivisionError if an attempt is made to change the length of a zero length vector. The direction of a zero length vector is undefined hence it can not be lengthened.

>>> a = Vector3D(1, 1, 1)
>>> a.length
1.7320508075688772
lerp()

Returns the linear interpolation between this vector and the supplied vector.

\[v = t \times \vec{a} + (1-t) \times \vec{b}\]
Parameters:
  • b (Vector3D) – The other vector that bounds the interpolation.
  • t (double) – The parametric interpolation point t in (0, 1).
>>> a = Vector3D(1, 0, 0)
>>> b = Vector3D(0, 1, 0)
>>> a.lerp(b, 0.5)
Vector3D(0.5, 0.5, 0.0)
normalise()

Returns a normalised copy of the vector.

The returned vector is normalised to length 1.0 - a unit vector.

Return type:Vector3D
>>> a = Vector3D(1, 1, 1)
>>> a.normalise()
Vector3D(0.5773502691896258, 0.5773502691896258, 0.5773502691896258)
orthogonal()

Returns a unit vector that is guaranteed to be orthogonal to the vector.

Return type:vector3D
>>> a = Vector3D(1, 0, 0)
>>> a.orthogonal()
Vector3D(0.0, 1.0, 0.0)
slerp()

Performs spherical vector interpolation between two vectors.

The difference between this function and lerp (linear interpolation) is that the vectors are treated as directions and their angles and magnitudes are interpolated separately.

Let \(\theta_0\) be the angle between two arbitrary vectors \(\vec{a}\) and \(\vec{b}\). \(\theta_0\) can be calculated through the dot product relationship.

\[\theta_0 = \cos{^{-1}(\vec{a} \cdot \vec{b})}\]

The interpolated vector, \(\vec{v}\), has angle \(\theta\) measured from \(\vec{a}\).

\[\theta = t \times \theta_0\]

Next we need to find the basis vector \(\hat{e}\) such that {\(\hat{a}\), \(\hat{e}\)} form an orthonormal basis in the same plane as {\(\vec{a}\), \(\vec{b}\)}.

\[\hat{e} = \frac{\vec{b} - \vec{a} \times (\vec{a} \cdot \vec{b})}{|\vec{b} - \vec{a} \times (\vec{a} \cdot \vec{b})|}\]

The resulting interpolated direction vector can now be defined as

\[\hat{v} = \hat{a} \times \cos{\theta} + \hat{e} \times \sin{\theta}.\]

Finally, the magnitude can be interpolated separately by linearly interpolating the original vector magnitudes.

\[\vec{v} = \hat{v} \times (t \times |\vec{a}| + (1-t) \times |\vec{b}|)\]
Parameters:
  • b (Vector3D) – The other vector that bounds the interpolation.
  • t (double) – The parametric interpolation point t in (0, 1).
>>> a = Vector3D(1, 0, 0)
>>> b = Vector3D(0, 1.5, 0)
>>> a.slerp(b, 0.5)
Vector3D(0.8838834764831844, 0.8838834764831843, 0.0)
transform()

Transforms the vector with the supplied AffineMatrix3D.

The vector is transformed by pre-multiplying the vector by the affine matrix.

\[\vec{C} = \textbf{A} \times \vec{B}\]

This method is substantially faster than using the multiplication operator of AffineMatrix3D when called from cython code.

Parameters:m (AffineMatrix3D) – The affine matrix describing the required coordinate transformation.
Returns:A new instance of this vector that has been transformed with the supplied Affine Matrix.
Return type:Vector3D
>>> z = Vector3D(0, 0, 1)
>>> y = z.transform(rotate_x(90))
>>> y
Vector3D(0.0, -1.0, 6.123233995736766e-17)
class raysect.core.math.normal.Normal3D

Represents a normal vector in 3D affine space.

A Normal3D is just a special case of a Vector3D that is perpendicular to a surface. A normal can be generated by taking the cross product of two non parallel Vectors that lie inside the surface. Because a Normal3D is defined in terms of a surface it supports a reduced set of operations when compared with Vectors.

If no initial values are passed, Normal3D defaults to a unit vector aligned with the z-axis: Normal3D(0.0, 0.0, 1.0)

Parameters:
  • x (float) – initial x coordinate, defaults to x = 0.0.
  • y (float) – initial y coordinate, defaults to y = 0.0.
  • z (float) – initial z coordinate, defaults to z = 0.0.
Variables:
  • x (float) – x-coordinate
  • y (float) – y-coordinate
  • z (float) – z-coordinate
>>> from raysect.core import Normal3D
>>> a = Normal3D(0, 0, 1)
as_vector()

Returns a Vector3D copy of the normal.

Return type:Vector3D
transform_with_inverse()

Transforms the normal with the supplied inverse Affine Matrix.

If an inverse matrix is already available in scope, this method is considerably faster than the transform() method - it skips a matrix inversion required to calculate the transformed normal (see the transform() documentation).

For cython code this method is substantially faster than using the multiplication operator of the affine matrix.

Parameters:m (AffineMatrix3D) – An inverse affine matrix of the required coordinate transformation.
Returns:A new instance of this normal vector that has been transformed.
Return type:Normal3D