Module pyxyz.vector3
3d vector class and helper functions
Expand source code
"""3d vector class and helper functions"""
import math
import numpy as np
class InvalidOperationException(Exception):
"""Exception thrown when there's an invalid operation with vectors"""
def __init__(self, op, type1, type2):
super().__init__(self)
self.op = op
self.type1 = type1
self.type2 = type2
def __str__(self):
"""Returns a readable version of the exception"""
return f"Invalid operation ({self.op}) between {self.type1} and {self.type2}!"
class Vector3:
"""3d vector class.
It stores XYZ values as floats."""
def __init__(self, x=0, y=0, z=0):
"""
Arguments:
x {number} -- X component,defaults to 0
y {number} -- Y component, defaults to 0
z {number} -- Z component, defaults to 0
"""
self.x = x
"""{number} - X component"""
self.y = y
"""{number} - Y component"""
self.z = z
"""{number} - Z component"""
def __str__(self):
"""Converts the 3d vector to a displayable string
Returns:
String - Vector in text format (x,y,z)"""
return "(" + str(self.x) + "," + str(self.y) + "," + str(self.z) + ")"
def __add__(self, v):
"""Adds this Vector3 to another.
If we try to add anything other than a Vector3 to it, it throws the
InvalidOperationException.
Arguments:
v {Vector3} -- Vector to add
Returns:
Vector3 - Sum of this Vector3 and the given one
"""
if isinstance(v, Vector3):
return Vector3(self.x + v.x, self.y + v.y, self.z + v.z)
else:
raise InvalidOperationException("add", type(self), type(v))
def __sub__(self, v):
"""Subtracts a Vector3 from this one.
If we try to subtract anything other than a Vector3, it throws the
InvalidOperationException.
Arguments:
v {Vector3} -- Vector to subtract
Returns:
Vector3 - Subraction of the given vector from this one
"""
if isinstance(v, Vector3):
return Vector3(self.x - v.x, self.y - v.y, self.z - v.z)
else:
raise InvalidOperationException("sub", type(self), type(v))
def __mul__(self, v):
"""Multiplies this Vector3 by a scalar.
If we try to multiply anything other than a scalar, it throws the
InvalidOperationException.
Arguments:
v {number} -- Scalar to multiply: all components of the vector are
multiplied by this number
Returns:
Vector3 - Multiplication of the Vector3
"""
if isinstance(v, (int, float)):
return Vector3(self.x * v, self.y * v, self.z * v)
else:
raise InvalidOperationException("mult", type(self), type(v))
def __rmul__(self, v):
"""Multiplies this Vector3 by a scalar.
If we try to multiply anything other than a scalar, it throws the InvalidOperationException
Arguments:
v {number} -- Scalar to multiply: all components of the vector are multiplied by
this number
Returns:
Vector3 - Multiplication of the Vector3
"""
if isinstance(v, (int, float)):
return Vector3(self.x * v, self.y * v, self.z * v)
else:
raise InvalidOperationException("mult", type(self), type(v))
def __truediv__(self, v):
"""Divides this Vector3 by a scalar.
If we try to divide anything other than a scalar, it throws the InvalidOperationException
Arguments:
v {number} -- Scalar to divide: all components of the vector are divided by this number
Returns:
Vector3 - Division of the Vector3
"""
if isinstance(v, (int, float)):
return Vector3(self.x / v, self.y / v, self.z / v)
else:
raise InvalidOperationException("mult", type(self), type(v))
def __eq__(self, v):
"""Checks if this Vector3 is equal to the given one, with a tolerance of 0.0001.
Exception InvalidOperationException is thrown if we compare something other than a
Vector3.
Arguments:
v {Vector3} -- Vector to compare
Returns:
Bool - True if the vectors are the same, false otherwise
"""
if isinstance(v, Vector3):
return ((self - v).magnitude()) < 0.0001
else:
raise InvalidOperationException("eq", type(self), type(v))
def __ne__(self, v):
"""Checks if this Vector3 is different to the given one, with a tolerance of 0.0001.
Exception InvalidOperationException is thrown if we compare something other than a
Vector3.
Arguments:
v {Vector3} -- Vector to compare
Returns:
Bool - True if the vectors are different, false otherwise
"""
if isinstance(v, Vector3):
return ((self - v).magnitude()) > 0.0001
else:
raise InvalidOperationException("neq", type(self), type(v))
def __isub__(self, v):
"""Subtracts a Vector3 from this one.
If we try to subtract anything other than a Vector3, it throws the
InvalidOperationException.
Arguments:
v {Vector3} -- Vector to subtract
Returns:
Vector3 - Subraction of the given vector from this one
"""
return self - v
def __iadd__(self, v):
"""Adds this Vector3 to another.
If we try to add anything other than a Vector3 to it, it throws the
InvalidOperationException.
Arguments:
v {Vector3} -- Vector to add
Returns:
Vector3 - Sum of this Vector3 and the given one
"""
return self + v
def __imul__(self, v):
"""Multiplies this Vector3 by a scalar.
If we try to multiply anything other than a scalar, it throws the
InvalidOperationException.
Arguments:
v {number} -- Scalar to multiply: all components of the vector are
multiplied by this number.
Returns:
Vector3 - Multiplication of the Vector3
"""
return self * v
def __idiv__(self, v):
"""Divides this Vector3 by a scalar.
If we try to divide anything other than a scalar, it throws the InvalidOperationException
Arguments:
v {number} -- Scalar to divide: all components of the vector are divided by this number
Returns:
Vector3 - Division of the Vector3
"""
return self / v
def __neg__(self):
"""Negates this Vector3, component-wise. Equivelent to multiplying by (-1)
Returns:
Vector3 - Negated Vector3
"""
return Vector3(-self.x, -self.y, -self.z)
def magnitude(self):
"""Returns the magnitude of the Vector3.
Returns:
Number - Magnitude of the vector
"""
return math.sqrt(self.dot(self))
def magnitude_squared(self):
"""Returns the squared magnitude of the Vector3.
Returns:
Number - Magnitude of the vector
"""
return self.dot(self)
def dot(self, v):
"""Computes the dot product of this Vector3 with another.
If we try to do this operation with anything other than a Vector3, it throws
the InvalidOperationException.
Arguments:
v {Vector3} -- Vector3 to do the dot product with
Returns:
Number - Scalar value corresponding to the dot product of both vectors
"""
if isinstance(v, Vector3):
return self.x * v.x + self.y * v.y + self.z * v.z
else:
raise InvalidOperationException("dot", type(self), type(v))
def cross(self, v):
"""Computes the cross product of this Vector3 with another.
If we try to do this operation with anything other than a Vector3, it throws
the InvalidOperationException.
Arguments:
v {Vector3} -- Vector3 to do the cross product with
Returns:
Vector3 - Cross product of both vectors
"""
if isinstance(v, Vector3):
return Vector3(self.y * v.z - self.z * v.y,
self.z * v.x - self.x * v.z,
self.x * v.y - self.y * v.x)
else:
raise InvalidOperationException("dot", type(self), type(v))
def normalize(self):
"""Normalizes this vector"""
d = 1.0 / self.magnitude()
self.x *= d
self.y *= d
self.z *= d
def normalized(self):
"""Returns the normalized version of this Vector3
Returns:
Vector3 - Normalized vector
"""
d = 1.0 / self.magnitude()
return Vector3(self.x * d, self.y * d, self.z * d)
def x0z(self):
"""Returns this vector, but with the y component zeroed.
Returns:
Vector3 - (x,0,z)
"""
return Vector3(self.x, 0, self.z)
def to_np3(self):
"""Converts a Vector3 to a 3-component numpy array
Returns:
np.array - [x,y,z]
"""
return np.array([self.x, self.y, self.z])
def to_np4(self, w=1):
"""Converts a Vector3 to a 4-component numpy array, with the given w as the 4th component.
Arguments:
w {number} - Value of the w component on the np.array.
Returns:
np.array - [x,y,z,w]
"""
return np.array([self.x, self.y, self.z, w])
@staticmethod
def from_np(np_array):
"""Converts a np.array to a Vector3. No validation is done on the array to confirm it
has 3 components.
Arguments:
np_array {np.array} - np.array with 3-components (rows or columns)
Returns:
Vector3 - A Vector3
"""
return Vector3(np_array[0], np_array[1], np_array[2])
@staticmethod
def distance(v1, v2):
"""Returns the distance between two positions/vectors
Arguments:
v1 {Vector3} - First vector
v2 {Vector3} - Second vector
Returns:
number - Distance between the two positions/vectors
"""
return (v1 - v2).magnitude()
def dot_product(v1, v2):
"""Returns the dot product between two vectors
Arguments:
v1 {Vector3} - First vector
v2 {Vector3} - Second vector
Returns:
number - Dot product between the vectors
"""
return v1.dot(v2)
def cross_product(v1, v2):
"""Returns the cross product between two vectors
Arguments:
v1 {Vector3} - First vector
v2 {Vector3} - Second vector
Returns:
Vector3 - Cross product between the vectors
"""
return v1.cross(v2)
Functions
def cross_product(v1, v2)
-
Returns the cross product between two vectors
Arguments
v1 {Vector3} - First vector
v2 {Vector3} - Second vector
Returns
Vector3 - Cross product between the vectors
Expand source code
def cross_product(v1, v2): """Returns the cross product between two vectors Arguments: v1 {Vector3} - First vector v2 {Vector3} - Second vector Returns: Vector3 - Cross product between the vectors """ return v1.cross(v2)
def dot_product(v1, v2)
-
Returns the dot product between two vectors
Arguments
v1 {Vector3} - First vector
v2 {Vector3} - Second vector
Returns
number - Dot product between the vectors
Expand source code
def dot_product(v1, v2): """Returns the dot product between two vectors Arguments: v1 {Vector3} - First vector v2 {Vector3} - Second vector Returns: number - Dot product between the vectors """ return v1.dot(v2)
Classes
class InvalidOperationException (op, type1, type2)
-
Exception thrown when there's an invalid operation with vectors
Expand source code
class InvalidOperationException(Exception): """Exception thrown when there's an invalid operation with vectors""" def __init__(self, op, type1, type2): super().__init__(self) self.op = op self.type1 = type1 self.type2 = type2 def __str__(self): """Returns a readable version of the exception""" return f"Invalid operation ({self.op}) between {self.type1} and {self.type2}!"
Ancestors
- builtins.Exception
- builtins.BaseException
class Vector3 (x=0, y=0, z=0)
-
3d vector class. It stores XYZ values as floats.
Arguments
x {number} – X component,defaults to 0
y {number} – Y component, defaults to 0
z {number} – Z component, defaults to 0
Expand source code
class Vector3: """3d vector class. It stores XYZ values as floats.""" def __init__(self, x=0, y=0, z=0): """ Arguments: x {number} -- X component,defaults to 0 y {number} -- Y component, defaults to 0 z {number} -- Z component, defaults to 0 """ self.x = x """{number} - X component""" self.y = y """{number} - Y component""" self.z = z """{number} - Z component""" def __str__(self): """Converts the 3d vector to a displayable string Returns: String - Vector in text format (x,y,z)""" return "(" + str(self.x) + "," + str(self.y) + "," + str(self.z) + ")" def __add__(self, v): """Adds this Vector3 to another. If we try to add anything other than a Vector3 to it, it throws the InvalidOperationException. Arguments: v {Vector3} -- Vector to add Returns: Vector3 - Sum of this Vector3 and the given one """ if isinstance(v, Vector3): return Vector3(self.x + v.x, self.y + v.y, self.z + v.z) else: raise InvalidOperationException("add", type(self), type(v)) def __sub__(self, v): """Subtracts a Vector3 from this one. If we try to subtract anything other than a Vector3, it throws the InvalidOperationException. Arguments: v {Vector3} -- Vector to subtract Returns: Vector3 - Subraction of the given vector from this one """ if isinstance(v, Vector3): return Vector3(self.x - v.x, self.y - v.y, self.z - v.z) else: raise InvalidOperationException("sub", type(self), type(v)) def __mul__(self, v): """Multiplies this Vector3 by a scalar. If we try to multiply anything other than a scalar, it throws the InvalidOperationException. Arguments: v {number} -- Scalar to multiply: all components of the vector are multiplied by this number Returns: Vector3 - Multiplication of the Vector3 """ if isinstance(v, (int, float)): return Vector3(self.x * v, self.y * v, self.z * v) else: raise InvalidOperationException("mult", type(self), type(v)) def __rmul__(self, v): """Multiplies this Vector3 by a scalar. If we try to multiply anything other than a scalar, it throws the InvalidOperationException Arguments: v {number} -- Scalar to multiply: all components of the vector are multiplied by this number Returns: Vector3 - Multiplication of the Vector3 """ if isinstance(v, (int, float)): return Vector3(self.x * v, self.y * v, self.z * v) else: raise InvalidOperationException("mult", type(self), type(v)) def __truediv__(self, v): """Divides this Vector3 by a scalar. If we try to divide anything other than a scalar, it throws the InvalidOperationException Arguments: v {number} -- Scalar to divide: all components of the vector are divided by this number Returns: Vector3 - Division of the Vector3 """ if isinstance(v, (int, float)): return Vector3(self.x / v, self.y / v, self.z / v) else: raise InvalidOperationException("mult", type(self), type(v)) def __eq__(self, v): """Checks if this Vector3 is equal to the given one, with a tolerance of 0.0001. Exception InvalidOperationException is thrown if we compare something other than a Vector3. Arguments: v {Vector3} -- Vector to compare Returns: Bool - True if the vectors are the same, false otherwise """ if isinstance(v, Vector3): return ((self - v).magnitude()) < 0.0001 else: raise InvalidOperationException("eq", type(self), type(v)) def __ne__(self, v): """Checks if this Vector3 is different to the given one, with a tolerance of 0.0001. Exception InvalidOperationException is thrown if we compare something other than a Vector3. Arguments: v {Vector3} -- Vector to compare Returns: Bool - True if the vectors are different, false otherwise """ if isinstance(v, Vector3): return ((self - v).magnitude()) > 0.0001 else: raise InvalidOperationException("neq", type(self), type(v)) def __isub__(self, v): """Subtracts a Vector3 from this one. If we try to subtract anything other than a Vector3, it throws the InvalidOperationException. Arguments: v {Vector3} -- Vector to subtract Returns: Vector3 - Subraction of the given vector from this one """ return self - v def __iadd__(self, v): """Adds this Vector3 to another. If we try to add anything other than a Vector3 to it, it throws the InvalidOperationException. Arguments: v {Vector3} -- Vector to add Returns: Vector3 - Sum of this Vector3 and the given one """ return self + v def __imul__(self, v): """Multiplies this Vector3 by a scalar. If we try to multiply anything other than a scalar, it throws the InvalidOperationException. Arguments: v {number} -- Scalar to multiply: all components of the vector are multiplied by this number. Returns: Vector3 - Multiplication of the Vector3 """ return self * v def __idiv__(self, v): """Divides this Vector3 by a scalar. If we try to divide anything other than a scalar, it throws the InvalidOperationException Arguments: v {number} -- Scalar to divide: all components of the vector are divided by this number Returns: Vector3 - Division of the Vector3 """ return self / v def __neg__(self): """Negates this Vector3, component-wise. Equivelent to multiplying by (-1) Returns: Vector3 - Negated Vector3 """ return Vector3(-self.x, -self.y, -self.z) def magnitude(self): """Returns the magnitude of the Vector3. Returns: Number - Magnitude of the vector """ return math.sqrt(self.dot(self)) def magnitude_squared(self): """Returns the squared magnitude of the Vector3. Returns: Number - Magnitude of the vector """ return self.dot(self) def dot(self, v): """Computes the dot product of this Vector3 with another. If we try to do this operation with anything other than a Vector3, it throws the InvalidOperationException. Arguments: v {Vector3} -- Vector3 to do the dot product with Returns: Number - Scalar value corresponding to the dot product of both vectors """ if isinstance(v, Vector3): return self.x * v.x + self.y * v.y + self.z * v.z else: raise InvalidOperationException("dot", type(self), type(v)) def cross(self, v): """Computes the cross product of this Vector3 with another. If we try to do this operation with anything other than a Vector3, it throws the InvalidOperationException. Arguments: v {Vector3} -- Vector3 to do the cross product with Returns: Vector3 - Cross product of both vectors """ if isinstance(v, Vector3): return Vector3(self.y * v.z - self.z * v.y, self.z * v.x - self.x * v.z, self.x * v.y - self.y * v.x) else: raise InvalidOperationException("dot", type(self), type(v)) def normalize(self): """Normalizes this vector""" d = 1.0 / self.magnitude() self.x *= d self.y *= d self.z *= d def normalized(self): """Returns the normalized version of this Vector3 Returns: Vector3 - Normalized vector """ d = 1.0 / self.magnitude() return Vector3(self.x * d, self.y * d, self.z * d) def x0z(self): """Returns this vector, but with the y component zeroed. Returns: Vector3 - (x,0,z) """ return Vector3(self.x, 0, self.z) def to_np3(self): """Converts a Vector3 to a 3-component numpy array Returns: np.array - [x,y,z] """ return np.array([self.x, self.y, self.z]) def to_np4(self, w=1): """Converts a Vector3 to a 4-component numpy array, with the given w as the 4th component. Arguments: w {number} - Value of the w component on the np.array. Returns: np.array - [x,y,z,w] """ return np.array([self.x, self.y, self.z, w]) @staticmethod def from_np(np_array): """Converts a np.array to a Vector3. No validation is done on the array to confirm it has 3 components. Arguments: np_array {np.array} - np.array with 3-components (rows or columns) Returns: Vector3 - A Vector3 """ return Vector3(np_array[0], np_array[1], np_array[2]) @staticmethod def distance(v1, v2): """Returns the distance between two positions/vectors Arguments: v1 {Vector3} - First vector v2 {Vector3} - Second vector Returns: number - Distance between the two positions/vectors """ return (v1 - v2).magnitude()
Static methods
def distance(v1, v2)
-
Returns the distance between two positions/vectors
Arguments
v1 {Vector3} - First vector
v2 {Vector3} - Second vector
Returns
number - Distance between the two positions/vectors
Expand source code
@staticmethod def distance(v1, v2): """Returns the distance between two positions/vectors Arguments: v1 {Vector3} - First vector v2 {Vector3} - Second vector Returns: number - Distance between the two positions/vectors """ return (v1 - v2).magnitude()
def from_np(np_array)
-
Converts a np.array to a Vector3. No validation is done on the array to confirm it has 3 components.
Arguments
np_array {np.array} - np.array with 3-components (rows or columns)
Returns
Vector3 - A Vector3
Expand source code
@staticmethod def from_np(np_array): """Converts a np.array to a Vector3. No validation is done on the array to confirm it has 3 components. Arguments: np_array {np.array} - np.array with 3-components (rows or columns) Returns: Vector3 - A Vector3 """ return Vector3(np_array[0], np_array[1], np_array[2])
Instance variables
var x
-
{number} - X component
var y
-
{number} - Y component
var z
-
{number} - Z component
Methods
def cross(self, v)
-
Computes the cross product of this Vector3 with another. If we try to do this operation with anything other than a Vector3, it throws the InvalidOperationException.
Arguments
v {Vector3} – Vector3 to do the cross product with
Returns
Vector3 - Cross product of both vectors
Expand source code
def cross(self, v): """Computes the cross product of this Vector3 with another. If we try to do this operation with anything other than a Vector3, it throws the InvalidOperationException. Arguments: v {Vector3} -- Vector3 to do the cross product with Returns: Vector3 - Cross product of both vectors """ if isinstance(v, Vector3): return Vector3(self.y * v.z - self.z * v.y, self.z * v.x - self.x * v.z, self.x * v.y - self.y * v.x) else: raise InvalidOperationException("dot", type(self), type(v))
def dot(self, v)
-
Computes the dot product of this Vector3 with another. If we try to do this operation with anything other than a Vector3, it throws the InvalidOperationException.
Arguments
v {Vector3} – Vector3 to do the dot product with
Returns
Number - Scalar value corresponding to the dot product of both vectors
Expand source code
def dot(self, v): """Computes the dot product of this Vector3 with another. If we try to do this operation with anything other than a Vector3, it throws the InvalidOperationException. Arguments: v {Vector3} -- Vector3 to do the dot product with Returns: Number - Scalar value corresponding to the dot product of both vectors """ if isinstance(v, Vector3): return self.x * v.x + self.y * v.y + self.z * v.z else: raise InvalidOperationException("dot", type(self), type(v))
def magnitude(self)
-
Returns the magnitude of the Vector3.
Returns
Number - Magnitude of the vector
Expand source code
def magnitude(self): """Returns the magnitude of the Vector3. Returns: Number - Magnitude of the vector """ return math.sqrt(self.dot(self))
def magnitude_squared(self)
-
Returns the squared magnitude of the Vector3.
Returns
Number - Magnitude of the vector
Expand source code
def magnitude_squared(self): """Returns the squared magnitude of the Vector3. Returns: Number - Magnitude of the vector """ return self.dot(self)
def normalize(self)
-
Normalizes this vector
Expand source code
def normalize(self): """Normalizes this vector""" d = 1.0 / self.magnitude() self.x *= d self.y *= d self.z *= d
def normalized(self)
-
Returns the normalized version of this Vector3
Returns
Vector3 - Normalized vector
Expand source code
def normalized(self): """Returns the normalized version of this Vector3 Returns: Vector3 - Normalized vector """ d = 1.0 / self.magnitude() return Vector3(self.x * d, self.y * d, self.z * d)
def to_np3(self)
-
Converts a Vector3 to a 3-component numpy array
Returns
np.array - [x,y,z]
Expand source code
def to_np3(self): """Converts a Vector3 to a 3-component numpy array Returns: np.array - [x,y,z] """ return np.array([self.x, self.y, self.z])
def to_np4(self, w=1)
-
Converts a Vector3 to a 4-component numpy array, with the given w as the 4th component.
Arguments
w {number} - Value of the w component on the np.array.
Returns
np.array - [x,y,z,w]
Expand source code
def to_np4(self, w=1): """Converts a Vector3 to a 4-component numpy array, with the given w as the 4th component. Arguments: w {number} - Value of the w component on the np.array. Returns: np.array - [x,y,z,w] """ return np.array([self.x, self.y, self.z, w])
def x0z(self)
-
Returns this vector, but with the y component zeroed.
Returns
Vector3 - (x,0,z)
Expand source code
def x0z(self): """Returns this vector, but with the y component zeroed. Returns: Vector3 - (x,0,z) """ return Vector3(self.x, 0, self.z)