# 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__()

>>> 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
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 = 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__()

>>> 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
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 = 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__()

>>> 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
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 = 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__()

>>> 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
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 = 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