forked from bartvdbraak/blender
A couple of files I left in the intern/python dir needed to be removed as
well. To remove the directories on your system, do a: cvs update -P
This commit is contained in:
parent
930fc9ee40
commit
ef9bfdcc75
@ -1,13 +0,0 @@
|
||||
3D utilities
|
||||
|
||||
(c) onk, 1998-2001
|
||||
|
||||
A few low level & math utilities for 2D/3D computations as:
|
||||
|
||||
- area.py: solving close packing problems in 2D
|
||||
|
||||
- vect.py: low level / OO like matrix and vector calculation module
|
||||
|
||||
- vectools.py: more vector tools for intersection calculation, etc.
|
||||
|
||||
- tree.py: binary trees (used by the BSPtree module)
|
@ -1,2 +0,0 @@
|
||||
__all__ = ["vect", "vectools", "area", "quat", "blvect", "tree"]
|
||||
|
@ -1,109 +0,0 @@
|
||||
"""Quaternion module
|
||||
|
||||
This module provides conversion routines between Matrices, Quaternions (rotations around
|
||||
an axis) and Eulers.
|
||||
|
||||
(c) 2000, onk@section5.de """
|
||||
|
||||
# NON PUBLIC XXX
|
||||
|
||||
from math import sin, cos, acos
|
||||
from util import vect
|
||||
reload(vect)
|
||||
|
||||
Vector = vect.Vector
|
||||
|
||||
Matrix = vect.Matrix
|
||||
|
||||
class Quat:
|
||||
"""Simple Quaternion class
|
||||
|
||||
Usually, you create a quaternion from a rotation axis (x, y, z) and a given
|
||||
angle 'theta', defining the right hand rotation:
|
||||
|
||||
q = fromRotAxis((x, y, z), theta)
|
||||
|
||||
This class supports multiplication, providing an efficient way to
|
||||
chain rotations"""
|
||||
|
||||
def __init__(self, w = 1.0, x = 0.0, y = 0.0, z = 0.0):
|
||||
self.v = (w, x, y, z)
|
||||
|
||||
def asRotAxis(self):
|
||||
"""returns rotation axis (x, y, z) and angle phi (right hand rotation)"""
|
||||
phi2 = acos(self.v[0])
|
||||
if phi2 == 0.0:
|
||||
return Vector(0.0, 0.0, 1.0), 0.0
|
||||
else:
|
||||
s = 1 / (sin(phi2))
|
||||
|
||||
v = Vector(s * self.v[1], s * self.v[2], s * self.v[3])
|
||||
return v, 2.0 * phi2
|
||||
|
||||
def __mul__(self, other):
|
||||
w1, x1, y1, z1 = self.v
|
||||
w2, x2, y2, z2 = other.v
|
||||
|
||||
w = w1*w2 - x1*x2 - y1*y2 - z1*z2
|
||||
x = w1*x2 + x1*w2 + y1*z2 - z1*y2
|
||||
y = w1*y2 - x1*z2 + y1*w2 + z1*x2
|
||||
z = w1*z2 + x1*y2 - y1*x2 + z1*w2
|
||||
return Quat(w, x, y, z)
|
||||
|
||||
def asMatrix(self):
|
||||
w, x, y, z = self.v
|
||||
|
||||
v1 = Vector(1.0 - 2.0 * (y*y + z*z), 2.0 * (x*y + w*z), 2.0 * (x*z - w*y))
|
||||
v2 = Vector(2.0 * (x*y - w*z), 1.0 - 2.0 * (x*x + z*z), 2.0 * (y*z + w*x))
|
||||
v3 = Vector(2.0 * (x*z + w*y), 2.0 * (y*z - w*x), 1.0 - 2.0 * (x*x + y*y))
|
||||
|
||||
return Matrix(v1, v2, v3)
|
||||
|
||||
# def asEuler1(self, transp = 0):
|
||||
# m = self.asMatrix()
|
||||
# if transp:
|
||||
# m = m.transposed()
|
||||
# return m.asEuler()
|
||||
|
||||
def asEuler(self, transp = 0):
|
||||
from math import atan, asin, atan2
|
||||
w, x, y, z = self.v
|
||||
x2 = x*x
|
||||
z2 = z*z
|
||||
tmp = x2 - z2
|
||||
r = (w*w + tmp - y*y )
|
||||
phi_z = atan2(2.0 * (x * y + w * z) , r)
|
||||
phi_y = asin(2.0 * (w * y - x * z))
|
||||
phi_x = atan2(2.0 * (w * x + y * z) , (r - 2.0*tmp))
|
||||
|
||||
return phi_x, phi_y, phi_z
|
||||
|
||||
def fromRotAxis(axis, phi):
|
||||
"""computes quaternion from (axis, phi)"""
|
||||
phi2 = 0.5 * phi
|
||||
s = sin(phi2)
|
||||
return Quat(cos(phi2), axis[0] * s, axis[1] * s, axis[2] * s)
|
||||
|
||||
#def fromEuler1(eul):
|
||||
#qx = fromRotAxis((1.0, 0.0, 0.0), eul[0])
|
||||
#qy = fromRotAxis((0.0, 1.0, 0.0), eul[1])
|
||||
#qz = fromRotAxis((0.0, 0.0, 1.0), eul[2])
|
||||
#return qz * qy * qx
|
||||
|
||||
def fromEuler(eul):
|
||||
from math import sin, cos
|
||||
e = eul[0] / 2.0
|
||||
cx = cos(e)
|
||||
sx = sin(e)
|
||||
e = eul[1] / 2.0
|
||||
cy = cos(e)
|
||||
sy = sin(e)
|
||||
e = eul[2] / 2.0
|
||||
cz = cos(e)
|
||||
sz = sin(e)
|
||||
|
||||
w = cx * cy * cz - sx * sy * sz
|
||||
x = sx * cy * cz - cx * sy * sz
|
||||
y = cx * sy * cz + sx * cy * sz
|
||||
z = cx * cy * sz + sx * sy * cz
|
||||
return Quat(w, x, y, z)
|
@ -1,215 +0,0 @@
|
||||
# Basisklasse fuer Baumstruktur
|
||||
# Object-orientiertes Programmieren Wi/97
|
||||
#
|
||||
# (c) Martin Strubel, Fakultaet fuer Physik, Universitaet Konstanz
|
||||
# (strubi@gandalf.physik.uni-konstanz.de)
|
||||
|
||||
# updated 08.2001
|
||||
|
||||
"""Simple binary tree module
|
||||
|
||||
This module demonstrates a binary tree class.
|
||||
|
||||
Example::
|
||||
|
||||
a = [5, 8, 8, 3, 7, 9]
|
||||
t1 = Tree()
|
||||
t1.fromList(a)
|
||||
|
||||
Operations on tree nodes are done by writing a simple operator class::
|
||||
|
||||
class myOp:
|
||||
def __init__(self):
|
||||
...
|
||||
def operate(self, node):
|
||||
do_something(node)
|
||||
|
||||
and calling the recursive application::
|
||||
|
||||
op = MyOp()
|
||||
t1.recurse(op)
|
||||
|
||||
Objects inserted into the tree can be of any kind, as long as they define a
|
||||
comparison operation.
|
||||
"""
|
||||
|
||||
def recurse(node, do):
|
||||
if node == None:
|
||||
return
|
||||
recurse(node.left, do)
|
||||
do(node)
|
||||
recurse(node.right, do)
|
||||
|
||||
class Nullnode:
|
||||
def __init__(self):
|
||||
self.left = None
|
||||
self.right = None
|
||||
self.depth = 0
|
||||
|
||||
def recurse(self, do):
|
||||
if self == Nil:
|
||||
return
|
||||
self.left.recurse(do)
|
||||
do(self)
|
||||
self.right.recurse(do)
|
||||
|
||||
Nil = Nullnode()
|
||||
|
||||
def nothing(x):
|
||||
return x
|
||||
|
||||
class Node(Nullnode):
|
||||
def __init__(self, data = None):
|
||||
self.left = Nil
|
||||
self.right = Nil
|
||||
self.data = data
|
||||
self.depth = 0
|
||||
|
||||
def __repr__(self):
|
||||
return "Node: %s" % self.data
|
||||
|
||||
def insert(self, node):
|
||||
if node.data < self.data:
|
||||
if self.left != Nil:
|
||||
return self.left.insert(node)
|
||||
else:
|
||||
node.depth = self.depth + 1
|
||||
self.left = node
|
||||
# print "inserted left"
|
||||
return self
|
||||
|
||||
elif node.data > self.data:
|
||||
if self.right != Nil:
|
||||
return self.right.insert(node)
|
||||
else:
|
||||
node.depth = self.depth + 1
|
||||
self.right = node
|
||||
# print "inserted right"
|
||||
return self
|
||||
else:
|
||||
return self.insert_equal(node)
|
||||
|
||||
def find(self, node, do = nothing):
|
||||
if node.data < self.data:
|
||||
if self.left != Nil:
|
||||
return self.left.find(node, do)
|
||||
else:
|
||||
return self
|
||||
elif node.data > self.data:
|
||||
if self.right != Nil:
|
||||
return self.right.find(node, do)
|
||||
else:
|
||||
return self
|
||||
else:
|
||||
return do(self)
|
||||
|
||||
def remove(self, node):
|
||||
newpar
|
||||
return self
|
||||
def insert_equal(self, node):
|
||||
#print "insert:",
|
||||
self.equal(node)
|
||||
return self
|
||||
def found_equal(self, node):
|
||||
self.equal(node)
|
||||
def equal(self, node):
|
||||
# handle special
|
||||
print "node (%s) is equal self (%s)" % (node, self)
|
||||
def copy(self):
|
||||
n = Node(self.data)
|
||||
return n
|
||||
|
||||
def recursecopy(self):
|
||||
n = Node()
|
||||
n.data = self.data
|
||||
n.flag = self.flag
|
||||
if self.left != Nil:
|
||||
n.left = self.left.recursecopy()
|
||||
if self.right != Nil:
|
||||
n.right = self.right.recursecopy()
|
||||
|
||||
return n
|
||||
|
||||
class NodeOp:
|
||||
def __init__(self):
|
||||
self.list = []
|
||||
def copy(self, node):
|
||||
self.list.append(node.data)
|
||||
|
||||
class Tree:
|
||||
def __init__(self, root = None):
|
||||
self.root = root
|
||||
self.n = 0
|
||||
def __radd__(self, other):
|
||||
print other
|
||||
t = self.copy()
|
||||
t.merge(other)
|
||||
return t
|
||||
def __repr__(self):
|
||||
return "Tree with %d elements" % self.n
|
||||
def insert(self, node):
|
||||
if self.root == None:
|
||||
self.root = node
|
||||
else:
|
||||
self.root.insert(node)
|
||||
self.n += 1
|
||||
def recurse(self, do):
|
||||
if self.root == None:
|
||||
return
|
||||
self.root.recurse(do)
|
||||
def find(self, node):
|
||||
return self.root.find(node)
|
||||
def remove(self, node):
|
||||
self.root.remove(node)
|
||||
def copy(self):
|
||||
"make true copy of self"
|
||||
t = newTree()
|
||||
c = NodeOp()
|
||||
self.recurse(c.copy)
|
||||
t.fromList(c.list)
|
||||
return t
|
||||
def asList(self):
|
||||
c = NodeOp()
|
||||
self.recurse(c.copy)
|
||||
return c.list
|
||||
def fromList(self, list):
|
||||
for item in list:
|
||||
n = Node(item)
|
||||
self.insert(n)
|
||||
def insertcopy(self, node):
|
||||
n = node.copy()
|
||||
self.insert(n)
|
||||
def merge(self, other):
|
||||
other.recurse(self.insertcopy)
|
||||
# EXAMPLE:
|
||||
|
||||
newTree = Tree
|
||||
|
||||
def printnode(x):
|
||||
print "Element: %s, depth: %s" % (x, x.depth)
|
||||
|
||||
def test():
|
||||
a = [5, 8, 8, 3, 7, 9]
|
||||
t1 = Tree()
|
||||
t1.fromList(a)
|
||||
|
||||
b = [12, 4, 56, 7, 34]
|
||||
t2 = Tree()
|
||||
t2.fromList(b)
|
||||
|
||||
print "tree1:"
|
||||
print t1.asList()
|
||||
print "tree2:"
|
||||
print t2.asList()
|
||||
print '-----'
|
||||
print "Trees can be added:"
|
||||
|
||||
|
||||
t3 = t1 + t2
|
||||
print t3.asList()
|
||||
print "..or alternatively merged:"
|
||||
t1.merge(t2)
|
||||
print t1.asList()
|
||||
|
||||
if __name__ == '__main__':
|
||||
test()
|
@ -1,480 +0,0 @@
|
||||
#------------------------------------------------------------------------------
|
||||
# simple 3D vector / matrix class
|
||||
#
|
||||
# (c) 9.1999, Martin Strubel // onk@section5.de
|
||||
# updated 4.2001
|
||||
#
|
||||
# This module consists of a rather low level command oriented
|
||||
# and a more OO oriented part for 3D vector/matrix manipulation
|
||||
#
|
||||
# For documentation, please look at the EXAMPLE code below - execute by:
|
||||
#
|
||||
# > python vect.py
|
||||
#
|
||||
#
|
||||
# permission to use in scientific and free programs granted
|
||||
# In doubt, please contact author.
|
||||
#
|
||||
# history:
|
||||
#
|
||||
# 1.5: Euler/Rotation matrix support moved here
|
||||
# 1.4: high level Vector/Matrix classes extended/improved
|
||||
#
|
||||
|
||||
"""Vector and matrix math module
|
||||
|
||||
Version 1.5
|
||||
by onk@section5.de
|
||||
|
||||
This is a lightweight 3D matrix and vector module, providing basic vector
|
||||
and matrix math plus a more object oriented layer.
|
||||
|
||||
For examples, look at vect.test()
|
||||
"""
|
||||
|
||||
VERSION = 1.5
|
||||
|
||||
TOLERANCE = 0.0000001
|
||||
|
||||
VectorType = 'Vector3'
|
||||
MatrixType = 'Matrix3'
|
||||
FloatType = type(1.0)
|
||||
|
||||
def dot(x, y):
|
||||
"(x,y) - Returns the dot product of vector 'x' and 'y'"
|
||||
return (x[0] * y[0] + x[1] * y[1] + x[2] * y[2])
|
||||
|
||||
def cross(x, y):
|
||||
"(x,y) - Returns the cross product of vector 'x' and 'y'"
|
||||
return (x[1] * y[2] - x[2] * y[1],
|
||||
x[2] * y[0] - x[0] * y[2],
|
||||
x[0] * y[1] - x[1] * y[0])
|
||||
|
||||
def matrix():
|
||||
"Returns Unity matrix"
|
||||
return ((1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0))
|
||||
|
||||
def matxvec(m, x):
|
||||
"y = matxvec(m,x) - Returns product of Matrix 'm' and vector 'x'"
|
||||
vx = m[0][0] * x[0] + m[1][0] * x[1] + m[2][0] * x[2]
|
||||
vy = m[0][1] * x[0] + m[1][1] * x[1] + m[2][1] * x[2]
|
||||
vz = m[0][2] * x[0] + m[1][2] * x[1] + m[2][2] * x[2]
|
||||
return (vx, vy, vz)
|
||||
|
||||
def matfromnormal(z, y = (0.0, 1.0, 0.0)):
|
||||
"""(z, y) - returns transformation matrix for local coordinate system
|
||||
where 'z' = local z, with optional *up* axis 'y'"""
|
||||
y = norm3(y)
|
||||
x = cross(y, z)
|
||||
y = cross(z, x)
|
||||
return (x, y, z)
|
||||
|
||||
def matxmat(m, n):
|
||||
"(m,n) - Returns matrix product of 'm' and 'n'"
|
||||
return (matxvec(m, n[0]), matxvec(m, n[1]), matxvec(m, n[2]))
|
||||
|
||||
def len(x):
|
||||
"(x) - Returns the length of vector 'x'"
|
||||
import math
|
||||
return math.sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2])
|
||||
|
||||
len3 = len # compatiblity reasons
|
||||
|
||||
def norm3(x):
|
||||
"(x) - Returns the vector 'x' normed to 1.0"
|
||||
import math
|
||||
r = math.sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2])
|
||||
return (x[0]/r, x[1]/r, x[2]/r)
|
||||
|
||||
def add3(x, y):
|
||||
"(x,y) - Returns vector ('x' + 'y')"
|
||||
return (x[0]+y[0], x[1]+y[1], x[2]+y[2])
|
||||
|
||||
def sub3(x, y):
|
||||
"(x,y) - Returns vector ('x' - 'y')"
|
||||
return ((x[0] - y[0]), (x[1] - y[1]), (x[2] - y[2]))
|
||||
|
||||
def dist3(x, y):
|
||||
"(x,y) - Returns euclidian distance from Point 'x' to 'y'"
|
||||
return len3(sub3(x, y))
|
||||
|
||||
def scale3(s, x):
|
||||
"(s,x) - Returns the vector 'x' scaled by 's'"
|
||||
return (s*x[0], s*x[1], s*x[2])
|
||||
|
||||
def scalemat(s,m):
|
||||
"(s,m) - Returns the Matrix 'm' scaled by 's'"
|
||||
return (scale3(s, m[0]), scale3(s, m[1]), scale3(s,m[2]))
|
||||
|
||||
def invmatdet(m):
|
||||
"""n, det = invmat(m) - Inverts matrix without determinant correction.
|
||||
Inverse matrix 'n' and Determinant 'det' are returned"""
|
||||
|
||||
# Matrix: (row vectors)
|
||||
# 00 10 20
|
||||
# 01 11 21
|
||||
# 02 12 22
|
||||
|
||||
wk = [0.0, 0.0, 0.0]
|
||||
|
||||
t = m[1][1] * m[2][2] - m[1][2] * m[2][1]
|
||||
wk[0] = t
|
||||
det = t * m[0][0]
|
||||
|
||||
t = m[2][1] * m[0][2] - m[0][1] * m[2][2]
|
||||
wk[1] = t
|
||||
det = det + t * m[1][0]
|
||||
|
||||
t = m[0][1] * m[1][2] - m[1][1] * m[0][2]
|
||||
wk[2] = t
|
||||
det = det + t * m[2][0]
|
||||
|
||||
v0 = (wk[0], wk[1], wk[2])
|
||||
|
||||
t = m[2][0] * m[1][2] - m[1][0] * m[2][2]
|
||||
wk[0] = t
|
||||
det = det + t * m[0][1]
|
||||
|
||||
t = m[0][0] * m[2][2] - m[0][2] * m[2][0]
|
||||
wk[1] = t
|
||||
det = det + t * m[1][1]
|
||||
|
||||
t = m[1][0] * m[0][2] - m[0][0] * m[1][2]
|
||||
wk[2] = t
|
||||
det = det + t * m[2][1]
|
||||
|
||||
v1 = (wk[0], wk[1], wk[2])
|
||||
|
||||
t = m[1][0] * m[2][1] - m[1][1] * m[2][0]
|
||||
wk[0] = t
|
||||
det = det + t * m[0][2]
|
||||
|
||||
t = m[2][0] * m[0][1] - m[0][0] * m[2][1]
|
||||
wk[1] = t
|
||||
det = det + t * m[1][2]
|
||||
|
||||
t = m[0][0] * m[1][1] - m[1][0] * m[0][1]
|
||||
wk[2] = t
|
||||
det = det + t * m[2][2]
|
||||
|
||||
v2 = (wk[0], wk[1], wk[2])
|
||||
# det = 3 * determinant
|
||||
return ((v0,v1,v2), det/3.0)
|
||||
|
||||
def invmat(m):
|
||||
"(m) - Inverts the 3x3 matrix 'm', result in 'n'"
|
||||
n, det = invmatdet(m)
|
||||
if det < 0.000001:
|
||||
raise ZeroDivisionError, "minor rank matrix"
|
||||
d = 1.0/det
|
||||
return (scale3(d, n[0]),
|
||||
scale3(d, n[1]),
|
||||
scale3(d, n[2]))
|
||||
|
||||
def transmat(m):
|
||||
# can be used to invert orthogonal rotation matrices
|
||||
"(m) - Returns transposed matrix of 'm'"
|
||||
return ((m[0][0], m[1][0], m[2][0]),
|
||||
(m[0][1], m[1][1], m[2][1]),
|
||||
(m[0][2], m[1][2], m[2][2]))
|
||||
|
||||
def coplanar(verts):
|
||||
"checks whether list of 4 vertices is coplanar"
|
||||
v1 = verts[0]
|
||||
v2 = verts[1]
|
||||
a = sub3(v2, v1)
|
||||
v1 = verts[1]
|
||||
v2 = verts[2]
|
||||
b = sub3(v2, v1)
|
||||
if dot(cross(a,b), sub3(verts[3] - verts[2])) < 0.0001:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
################################################################################
|
||||
# Matrix / Vector highlevel
|
||||
# (and slower)
|
||||
# TODO: include better type checks !
|
||||
|
||||
class Vector:
|
||||
"""Vector class
|
||||
|
||||
This vector class provides vector operations as addition, multiplication, etc.
|
||||
|
||||
Usage::
|
||||
|
||||
v = Vector(x, y, z)
|
||||
|
||||
where 'x', 'y', 'z' are float values, representing coordinates.
|
||||
Note: This datatype emulates a float triple."""
|
||||
|
||||
def __init__(self, x = 0.0, y = 0.0, z = 0.0):
|
||||
# don't change these to lists, very ugly referencing details...
|
||||
self.v = (x, y, z)
|
||||
# ... can lead to same data being shared by several matrices..
|
||||
# (unless you want this to happen)
|
||||
self.type = VectorType
|
||||
|
||||
def __neg__(self):
|
||||
return self.new(-self.v[0], -self.v[1], -self.v[2])
|
||||
|
||||
def __getitem__(self, i):
|
||||
"Tuple emulation"
|
||||
return self.v[i]
|
||||
|
||||
# def __setitem__(self, i, arg):
|
||||
# self.v[i] = arg
|
||||
|
||||
def new(self, *args):
|
||||
return Vector(args[0], args[1], args[2])
|
||||
|
||||
def __cmp__(self, v):
|
||||
"Comparison only supports '=='"
|
||||
if self[0] == v[0] and self[1] == v[1] and self[1] == v[1]:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def __add__(self, v):
|
||||
"Addition of 'Vector' objects"
|
||||
return self.new(self[0] + v[0],
|
||||
self[1] + v[1],
|
||||
self[2] + v[2])
|
||||
|
||||
def __sub__(self, v):
|
||||
"Subtraction of 'Vector' objects"
|
||||
return self.new(self[0] - v[0],
|
||||
self[1] - v[1],
|
||||
self[2] - v[2])
|
||||
|
||||
def __rmul__(self, s): # scaling by s
|
||||
return self.new(s * self[0], s * self[1], s * self[2])
|
||||
|
||||
def __mul__(self, t): # dot product
|
||||
"""Left multiplikation supports:
|
||||
|
||||
- scaling with a float value
|
||||
|
||||
- Multiplikation with *Matrix* object"""
|
||||
|
||||
if type(t) == FloatType:
|
||||
return self.__rmul__(t)
|
||||
elif t.type == MatrixType:
|
||||
return Matrix(self[0] * t[0], self[1] * t[1], self[2] * t[2])
|
||||
else:
|
||||
return dot(self, t)
|
||||
|
||||
def cross(self, v):
|
||||
"(Vector v) - returns the cross product of 'self' with 'v'"
|
||||
return self.new(self[1] * v[2] - self[2] * v[1],
|
||||
self[2] * v[0] - self[0] * v[2],
|
||||
self[0] * v[1] - self[1] * v[0])
|
||||
|
||||
def __repr__(self):
|
||||
return "(%.3f, %.3f, %.3f)" % (self.v[0], self.v[1], self.v[2])
|
||||
|
||||
class Matrix(Vector):
|
||||
"""Matrix class
|
||||
|
||||
This class is representing a vector of Vectors.
|
||||
|
||||
Usage::
|
||||
|
||||
M = Matrix(v1, v2, v3)
|
||||
|
||||
where 'v'n are Vector class instances.
|
||||
Note: This datatype emulates a 3x3 float array."""
|
||||
|
||||
def __init__(self, v1 = Vector(1.0, 0.0, 0.0),
|
||||
v2 = Vector(0.0, 1.0, 0.0),
|
||||
v3 = Vector(0.0, 0.0, 1.0)):
|
||||
self.v = [v1, v2, v3]
|
||||
self.type = MatrixType
|
||||
|
||||
def __setitem__(self, i, arg):
|
||||
self.v[i] = arg
|
||||
|
||||
def new(self, *args):
|
||||
return Matrix(args[0], args[1], args[2])
|
||||
|
||||
def __repr__(self):
|
||||
return "Matrix:\n %s\n %s\n %s\n" % (self.v[0], self.v[1], self.v[2])
|
||||
|
||||
def __mul__(self, m):
|
||||
"""Left multiplication supported with:
|
||||
|
||||
- Scalar (float)
|
||||
|
||||
- Matrix
|
||||
|
||||
- Vector: row_vector * matrix; same as self.transposed() * vector
|
||||
"""
|
||||
try:
|
||||
if type(m) == FloatType:
|
||||
return self.__rmul__(m)
|
||||
if m.type == MatrixType:
|
||||
M = matxmat(self, m)
|
||||
return self.new(Vector(M[0][0], M[0][1], M[0][2]),
|
||||
Vector(M[1][0], M[1][1], M[1][2]),
|
||||
Vector(M[2][0], M[2][1], M[2][2]))
|
||||
if m.type == VectorType:
|
||||
v = matxvec(self, m)
|
||||
return Vector(v[0], v[1], v[2])
|
||||
except:
|
||||
raise TypeError, "bad multiplicator type"
|
||||
|
||||
def inverse(self):
|
||||
"""returns the matrix inverse"""
|
||||
M = invmat(self)
|
||||
return self.new(Vector(M[0][0], M[0][1], M[0][2]),
|
||||
Vector(M[1][0], M[1][1], M[1][2]),
|
||||
Vector(M[2][0], M[2][1], M[2][2]))
|
||||
|
||||
def transposed(self):
|
||||
"returns the transposed matrix"
|
||||
M = self
|
||||
return self.new(Vector(M[0][0], M[1][0], M[2][0]),
|
||||
Vector(M[1][0], M[1][1], M[2][1]),
|
||||
Vector(M[2][0], M[1][2], M[2][2]))
|
||||
|
||||
def det(self):
|
||||
"""returns the determinant"""
|
||||
M, det = invmatdet(self)
|
||||
return det
|
||||
|
||||
def tr(self):
|
||||
"""returns trace (sum of diagonal elements) of matrix"""
|
||||
return self.v[0][0] + self.v[1][1] + self.v[2][2]
|
||||
|
||||
def __rmul__(self, m):
|
||||
"Right multiplication supported with scalar"
|
||||
if type(m) == FloatType:
|
||||
return self.new(m * self[0],
|
||||
m * self[1],
|
||||
m * self[2])
|
||||
else:
|
||||
raise TypeError, "bad multiplicator type"
|
||||
|
||||
def __div__(self, m):
|
||||
"""Division supported with:
|
||||
|
||||
- Scalar
|
||||
|
||||
- Matrix: a / b equivalent b.inverse * a
|
||||
"""
|
||||
if type(m) == FloatType:
|
||||
m = 1.0 /m
|
||||
return m * self
|
||||
elif m.type == MatrixType:
|
||||
return self.inverse() * m
|
||||
else:
|
||||
raise TypeError, "bad multiplicator type"
|
||||
|
||||
def __rdiv__(self, m):
|
||||
"Right division of matrix equivalent to multiplication with matrix.inverse()"
|
||||
return m * self.inverse()
|
||||
|
||||
def asEuler(self):
|
||||
"""returns Matrix 'self' as Eulers. Note that this not the only result, due to
|
||||
the nature of sin() and cos(). The Matrix MUST be a rotation matrix, i.e. orthogonal and
|
||||
normalized."""
|
||||
from math import cos, sin, acos, asin, atan2, atan
|
||||
mat = self.v
|
||||
sy = mat[0][2]
|
||||
# for numerical stability:
|
||||
if sy > 1.0:
|
||||
if sy > 1.0 + TOLERANCE:
|
||||
raise RuntimeError, "FATAL: bad matrix given"
|
||||
else:
|
||||
sy = 1.0
|
||||
phi_y = -asin(sy)
|
||||
|
||||
if abs(sy) > (1.0 - TOLERANCE):
|
||||
# phi_x can be arbitrarely chosen, we set it = 0.0
|
||||
phi_x = 0.0
|
||||
sz = mat[1][0]
|
||||
cz = mat[2][0]
|
||||
phi_z = atan(sz/cz)
|
||||
else:
|
||||
cy = cos(phi_y)
|
||||
cz = mat[0][0] / cy
|
||||
sz = mat[0][1] / cy
|
||||
phi_z = atan2(sz, cz)
|
||||
|
||||
sx = mat[1][2] / cy
|
||||
cx = mat[2][2] / cy
|
||||
phi_x = atan2(sx, cx)
|
||||
return phi_x, phi_y, phi_z
|
||||
|
||||
Ex = Vector(1.0, 0.0, 0.0)
|
||||
Ey = Vector(0.0, 1.0, 0.0)
|
||||
Ez = Vector(0.0, 0.0, 1.0)
|
||||
|
||||
One = Matrix(Ex, Ey, Ez)
|
||||
orig = (0.0, 0.0, 0.0)
|
||||
|
||||
def rotmatrix(phi_x, phi_y, phi_z, reverse = 0):
|
||||
"""Creates rotation matrix from euler angles. Rotations are applied in order
|
||||
X, then Y, then Z. If the reverse is desired, you have to transpose the matrix after."""
|
||||
from math import sin, cos
|
||||
s = sin(phi_z)
|
||||
c = cos(phi_z)
|
||||
matz = Matrix(Vector(c, s, 0.0), Vector(-s, c, 0.0), Ez)
|
||||
|
||||
s = sin(phi_y)
|
||||
c = cos(phi_y)
|
||||
maty = Matrix(Vector(c, 0.0, -s), Ey, Vector(s, 0.0, c))
|
||||
|
||||
s = sin(phi_x)
|
||||
c = cos(phi_x)
|
||||
matx = Matrix(Ex, Vector(0.0, c, s), Vector(0.0, -s, c))
|
||||
|
||||
return matz * maty * matx
|
||||
|
||||
|
||||
def test():
|
||||
"The module test"
|
||||
print "********************"
|
||||
print "VECTOR TEST"
|
||||
print "********************"
|
||||
|
||||
a = Vector(1.1, 0.0, 0.0)
|
||||
b = Vector(0.0, 2.0, 0.0)
|
||||
|
||||
print "vectors: a = %s, b = %s" % (a, b)
|
||||
print "dot:", a * a
|
||||
print "scalar:", 4.0 * a
|
||||
print "scalar:", a * 4.0
|
||||
print "cross:", a.cross(b)
|
||||
print "add:", a + b
|
||||
print "sub:", a - b
|
||||
print "sub:", b - a
|
||||
print
|
||||
print "********************"
|
||||
print "MATRIX TEST"
|
||||
print "********************"
|
||||
c = a.cross(b)
|
||||
m = Matrix(a, b, c)
|
||||
v = Vector(1.0, 2.0, 3.0)
|
||||
E = One
|
||||
print "Original", m
|
||||
print "det", m.det()
|
||||
print "add", m + m
|
||||
print "scalar", 0.5 * m
|
||||
print "sub", m - 0.5 * m
|
||||
print "vec mul", v * m
|
||||
print "mul vec", m * v
|
||||
n = m * m
|
||||
print "mul:", n
|
||||
print "matrix div (mul inverse):", n / m
|
||||
print "scal div (inverse):", 1.0 / m
|
||||
print "mat * inverse", m * m.inverse()
|
||||
print "mat * inverse (/-notation):", m * (1.0 / m)
|
||||
print "div scal", m / 2.0
|
||||
|
||||
# matrices with rang < dimension have det = 0.0
|
||||
m = Matrix(a, 2.0 * a, c)
|
||||
print "minor rang", m
|
||||
print "det:", m.det()
|
||||
|
||||
if __name__ == '__main__':
|
||||
test()
|
||||
|
@ -1,142 +0,0 @@
|
||||
"""Vector tools
|
||||
|
||||
Various vector tools, basing on vect.py"""
|
||||
|
||||
from vect import *
|
||||
|
||||
EPSILON = 0.0001
|
||||
|
||||
def vecarea(v, w):
|
||||
"Computes area of the span of vector 'v' and 'w' in 2D (not regarding z coordinate)"
|
||||
return v[0]*w[1] - v[1]*w[0]
|
||||
|
||||
def intersect(a1, b1, a2, b2):
|
||||
"""Computes 2D intersection of edges ('a1' -> 'b1') and ('a2' -> 'b2'),
|
||||
returning normalized intersection parameter 's' of edge (a1 -> b1).
|
||||
If 0.0 < 's' <= 1.0,
|
||||
the two edges intersect at the point::
|
||||
|
||||
v = a1 + s * (b1 - a1)
|
||||
"""
|
||||
v = (b1[0] - a1[0], b1[1] - a1[1])
|
||||
w = (b2[0] - a2[0], b2[1] - a2[1])
|
||||
d0 = (a2[0] - a1[0])
|
||||
d1 = (a2[1] - a1[1])
|
||||
|
||||
det = w[0]*v[1] - w[1]*v[0]
|
||||
if det == 0: return 0.0
|
||||
t = v[0]*d1 - v[1]*d0
|
||||
s = w[0]*d1 - w[1]*d0
|
||||
s /= det
|
||||
t /= det
|
||||
if s > 1.0 or s < 0.0: return 0.0
|
||||
if t > 1.0 or t < 0.0: return 0.0
|
||||
return s
|
||||
|
||||
def insidetri(a, b, c, x):
|
||||
"Returns 1 if 'x' is inside the 2D triangle ('a' -> 'b' -> 'c'), 0 otherwise"
|
||||
v1 = norm3(sub3(b, a))
|
||||
v2 = norm3(sub3(c, a))
|
||||
v3 = norm3(sub3(x, a))
|
||||
|
||||
a1 = (vecarea(v1, v2))
|
||||
a2 = (vecarea(v1, v3))
|
||||
lo = min(0.0, a1)
|
||||
hi = max(0.0, a1)
|
||||
|
||||
if a2 < lo or a2 > hi: return 0
|
||||
|
||||
v2 = norm3(sub3(b, c))
|
||||
v3 = norm3(sub3(b, x))
|
||||
|
||||
a1 = (vecarea(v1, v2))
|
||||
a2 = (vecarea(v1, v3))
|
||||
|
||||
lo = min(0.0, a1)
|
||||
hi = max(0.0, a1)
|
||||
|
||||
if a2 < lo or a2 > hi: return 0
|
||||
|
||||
return 1
|
||||
|
||||
def plane_fromface(v1, v2, v3):
|
||||
"Returns plane (normal, point) from 3 vertices 'v1', 'v2', 'v3'"
|
||||
v = sub3(v2, v1)
|
||||
w = sub3(v3, v1)
|
||||
n = norm3(cross(v, w))
|
||||
return n, v1
|
||||
|
||||
def inside_halfspace(vec, plane):
|
||||
"Returns 1 if point 'vec' inside halfspace defined by 'plane'"
|
||||
n, t = plane
|
||||
n = norm3(n)
|
||||
v = sub3(vec, t)
|
||||
if dot(n, v) < 0.0:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def half_space(vec, plane, tol = EPSILON):
|
||||
"""Determine whether point 'vec' is inside (return value -1), outside (+1)
|
||||
, or lying in the plane 'plane' (return 0) of a numerical thickness
|
||||
'tol' = 'EPSILON' (default)."""
|
||||
n, t = plane
|
||||
v = sub3(vec, t)
|
||||
fac = len3(n)
|
||||
|
||||
d = dot(n, v)
|
||||
if d < -fac * tol:
|
||||
return -1
|
||||
elif d > fac * tol:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def plane_edge_intersect(plane, edge):
|
||||
"""Returns normalized factor 's' of the intersection of 'edge' with 'plane'.
|
||||
The point of intersection on the plane is::
|
||||
|
||||
p = edge[0] + s * (edge[1] - edge[0])
|
||||
|
||||
"""
|
||||
n, t = plane # normal, translation
|
||||
mat = matfromnormal(n)
|
||||
mat = transmat(mat) # inverse
|
||||
v = matxvec(mat, sub3(edge[0], t)) #transformed edge points
|
||||
w = matxvec(mat, sub3(edge[1], t))
|
||||
w = sub3(w, v)
|
||||
if w[2] != 0.0:
|
||||
s = -v[2] / w[2]
|
||||
return s
|
||||
else:
|
||||
return None
|
||||
|
||||
def insidecube(v):
|
||||
"Returns 1 if point 'v' inside normalized cube, 0 otherwise"
|
||||
if v[0] > 1.0 or v[0] < 0.0:
|
||||
return 0
|
||||
if v[1] > 1.0 or v[1] < 0.0:
|
||||
return 0
|
||||
if v[2] > 1.0 or v[2] < 0.0:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
def flatproject(verts, up):
|
||||
"""Projects a 3D set (list of vertices) 'verts' into a 2D set according to
|
||||
an 'up'-vector"""
|
||||
z, t = plane_fromface(verts[0], verts[1], verts[2])
|
||||
y = norm3(up)
|
||||
x = cross(y, z)
|
||||
uvs = []
|
||||
for v in verts:
|
||||
w = (v[0] - t[0], v[1] - t[1], v[2] - t[2])
|
||||
# this is the transposed 2x2 matrix * the vertex vector
|
||||
uv = (dot(x, w), dot(y,w)) # do projection
|
||||
uvs.append(uv)
|
||||
return uvs
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user