Last active
November 10, 2015 12:35
-
-
Save internetimagery/7a90fe5f2be5fb16aaac to your computer and use it in GitHub Desktop.
3D Stuff
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, collections | |
class Vector(tuple): | |
__slots__ = () | |
def __neg__(s): return s.__class__(-a for a in s) | |
def __pos__(s): return s.__class__(+a for a in s) | |
def __ne__(s, v): return False if s == v else True | |
magnitude = property(lambda s: math.sqrt(sum(s * s))) # |s| | |
def __nonzero__(s): return 1 != len(set(a for a in s if not a)) | |
def __add__(s, v): return s.__class__(a + b for a, b in zip(s, v)) | |
def __div__(s, v): return s.__class__(a / b for a, b in zip(s, v)) | |
def __mod__(s, v): return s.__class__(a % b for a, b in zip(s, v)) | |
def __mul__(s, v): return s.__class__(a * b for a, b in zip(s, v)) | |
def __sub__(s, v): return s.__class__(a - b for a, b in zip(s, v)) | |
def __pow__(s, v): return s.__class__(a ** b for a, b in zip(s, v)) | |
def __lt__(s, v): return False not in set(a < b for a, b in zip(s, v)) | |
def __gt__(s, v): return False not in set(a > b for a, b in zip(s, v)) | |
def __truediv__(s, v): return s.__class__(a / b for a, b in zip(s, v)) | |
def __eq__(s, v): return False not in set(a == b for a, b in zip(s, v)) | |
def __le__(s, v): return False not in set(a <= b for a, b in zip(s, v)) | |
def __ge__(s, v): return False not in set(a >= b for a, b in zip(s, v)) | |
def __floordiv__(s, v): return s.__class__(a // b for a, b in zip(s, v)) | |
def __new__(s, *args): return tuple.__new__(s, args[0] if len(args) == 1 else args) | |
def angle(s, v): return math.degrees(math.acos(s.dot(v) / (s.magnitude * v.magnitude))) | |
normalized = property(lambda s: s / ([s.magnitude]*len(s)) if s else s.__class__([0]*len(s))) | |
def mean(s, *v): | |
for v1 in v: s += v1 | |
return s.__class__(s / ([len(v)]*len(s))) | |
def cross(s, v): return s.__class__( | |
s[1] * v[2] - s[2] * v[1], | |
s[2] * v[0] - s[0] * v[2], | |
s[0] * v[1] - s[1] * v[0]) | |
def dot(s, v): return sum(s * v) | |
class Point(Vector): | |
__slots__ = () | |
def distance(s, v): return Vector(v - s).magnitude | |
class Matrix(collections.Sequence): | |
__slots__ = ("row", "col", "cols", "rows") | |
def __init__(s, row): | |
s.rows = row | |
s.row = range(len(row)) | |
s.col = range(len(row[0])) | |
# Store transpose | |
s.cols = tuple(tuple(s.rows[b][a] for b in s.row) for a in s.col) | |
def __repr__(s): return "\n".join([repr(a) for a in s.rows]) | |
def __len__(s): return (len(s.row), len(s.col)) | |
def __getitem__(s, k): | |
try: | |
return s.rows[k[0]][k[1]] | |
except TypeError: | |
raise TypeError, "You must supply both x and y coordinates." | |
def __mul__(s, m): return s.__class__(tuple(tuple(sum([a * b for a, b in zip(s.rows[r], m.cols[c])]) for c in m.col) for r in s.row)) | |
def __add__(s, m): return s.__class__(tuple(tuple(m[r,c] + s[r,c] for c in s.col) for r in s.row)) | |
def __div__(s, m): return s * -v | |
def __mod__(s, m): raise NotImplementedError | |
def __sub__(s, m): return s.__class__(tuple(tuple(m[r,c] - s[r,c] for c in s.col) for r in s.row)) | |
def __pow__(s, m): raise NotImplementedError | |
def __lt__(s, m): raise NotImplementedError | |
def __gt__(s, m): raise NotImplementedError | |
def __truediv__(s, m): raise NotImplementedError | |
def __eq__(s, m): return False not in set(s[r,c] == m[r,c] for r in s.row for c in s.col) | |
def __le__(s, m): raise NotImplementedError | |
def __ge__(s, m): raise NotImplementedError | |
def __floordiv__(s, m): raise NotImplementedError | |
def __nonzero__(s): return True if set(True for r in s.row for c in s.col if s[r,c]) else False | |
def __ne__(s, m): return s != m | |
def __neg__(s): return s.__class__(tuple(tuple(-s[r,c] for c in s.col) for r in s.row)) | |
def __pos__(s): return s.__class__(tuple(tuple(+s[r,c] for c in s.col) for r in s.row)) | |
def scalar(s, n): return s.__class__(tuple(tuple(n for c in s.col) for r in s.row)) | |
# def _inv(s): | |
# num = range(len(s.row)); num.reverse() | |
# if len(s.row) != len(s.col): raise ValueError, "Matrix must be a square." | |
# return s.__class__(tuple(tuple((r,c) for c in num) for r in num)) | |
# inverse = property(lambda s: s._inv()) | |
def identity(size): | |
num = range(size) | |
return Matrix(tuple(tuple(1 if a == b else 0 for b in num) for a in num)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment