Skip to content

Instantly share code, notes, and snippets.

@mr-linch
Created June 15, 2014 14:07
Show Gist options
  • Save mr-linch/def346a4c69a069d96cd to your computer and use it in GitHub Desktop.
Save mr-linch/def346a4c69a069d96cd to your computer and use it in GitHub Desktop.
Minimal implementations of vector mathematics for game development on the python
import math
import collections
"""Minimal implementations of vector mathematics for game development on the python.
Usage:
import vector
current_position = (5, 2)
destination = (8, 4)
direction = vector.sub(destination, current_position)
distance = vector.length(direction)
"""
def add(a, b):
"""Add arguments, element-wise"""
if isinstance(a, collections.Iterable) and isinstance(b, collections.Iterable):
if len(a) != len(b):
raise ValueError('operands must be the same size')
return [i + j for i, j in zip(a, b)]
return [i + b for i in a]
def sub(a, b):
"""Substract arguments, element-wise"""
if isinstance(a, collections.Iterable) and isinstance(b, collections.Iterable):
if len(a) != len(b):
raise ValueError('operands must be the same size')
return [i - j for i, j in zip(a, b)]
return [i - b for i in a]
def mul(a, b):
"""Multiply arguments, element-wise"""
if isinstance(a, collections.Iterable) and isinstance(b, collections.Iterable):
if len(a) != len(b):
raise ValueError('operands must be the same size')
return [i * j for i, j in zip(a, b)]
return [i * b for i in a]
def div(a, b):
"""Divide arguments element-wise"""
if isinstance(a, collections.Iterable) and isinstance(b, collections.Iterable):
if len(a) != len(b):
raise ValueError('operands must be the same size')
return [i / j for i, j in zip(a, b)]
return [i / b for i in a]
def dot(a, b):
"""Dot product of 2 vector"""
if len(a) != len(b):
raise ValueError('operands must be the same size')
return sum(i * j for i, j in zip(a, b))
def distance_sqr(a, b):
"""Squared distance between a and b"""
return sum((i - j) * (i - j) for i, j in zip(a, b))
def distance(a, b):
"""Distance between a and b"""
return math.sqrt(distance_sqr(a, b))
def negative(a):
"""Numerical negative, element-wise"""
return [-i for i in a]
def length_sqr(a):
"""Squared lenght of vector"""
return sum(x * x for x in a)
def length(a):
"""Length of vector"""
return math.sqrt(length_sqr(a))
def normalized(a):
"""Return new normalized vector"""
l = length(a)
return [x / l for x in a]
def normalize(a):
"""Normalize vector a"""
l = length(a)
for index, number in enumerate(a):
a[index] = number / l
return a
def angle_radians_2d(a):
"""The angle in radians of this vector relative to the x-axis"""
return math.atan2(a[1], a[0])
def angle_2d(a):
"""The angle in degrees of this vector relative to the x-axis"""
return math.degrees(angle_radians_2d(a))
def rotate_radians_2d(a, angle):
"""Rotates the Vector2 by the given angle (radians), counter-clockwise assuming the y-axis points up"""
cos = math.cos(angle)
sin = math.sin(angle)
x, y = a
return x * cos - y * sin, x * sin + y * cos
def rotate_2d(a, angle):
"""Rotates the Vector2 by the given angle (degrees), counter-clockwise assuming the y-axis points up"""
return rotate_radians_2d(a, math.radians(angle))
def to_integer(a):
"""Convert type to int, element-wise"""
return map(int, a)
def to_float(a):
"""Convert type to float, element-wise"""
return map(float, a)
def is_zero(a):
"""Check if vector is zero"""
for x in a:
if bool(x):
return False
return True
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment