Created
June 15, 2014 14:07
-
-
Save mr-linch/def346a4c69a069d96cd to your computer and use it in GitHub Desktop.
Minimal implementations of vector mathematics for game development on the python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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