diff options
-rw-r--r-- | intern/python/modules/util/README.txt | 13 | ||||
-rw-r--r-- | intern/python/modules/util/__init__.py | 2 | ||||
-rw-r--r-- | intern/python/modules/util/quat.py | 109 | ||||
-rw-r--r-- | intern/python/modules/util/tree.py | 215 | ||||
-rw-r--r-- | intern/python/modules/util/vect.py | 480 | ||||
-rw-r--r-- | intern/python/modules/util/vectools.py | 142 |
6 files changed, 0 insertions, 961 deletions
diff --git a/intern/python/modules/util/README.txt b/intern/python/modules/util/README.txt deleted file mode 100644 index 60321531bd7..00000000000 --- a/intern/python/modules/util/README.txt +++ /dev/null @@ -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) diff --git a/intern/python/modules/util/__init__.py b/intern/python/modules/util/__init__.py deleted file mode 100644 index ee6b0cef939..00000000000 --- a/intern/python/modules/util/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -__all__ = ["vect", "vectools", "area", "quat", "blvect", "tree"] - diff --git a/intern/python/modules/util/quat.py b/intern/python/modules/util/quat.py deleted file mode 100644 index d23b1c3f6d9..00000000000 --- a/intern/python/modules/util/quat.py +++ /dev/null @@ -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) diff --git a/intern/python/modules/util/tree.py b/intern/python/modules/util/tree.py deleted file mode 100644 index 313159239c6..00000000000 --- a/intern/python/modules/util/tree.py +++ /dev/null @@ -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() diff --git a/intern/python/modules/util/vect.py b/intern/python/modules/util/vect.py deleted file mode 100644 index 3724079519b..00000000000 --- a/intern/python/modules/util/vect.py +++ /dev/null @@ -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() - diff --git a/intern/python/modules/util/vectools.py b/intern/python/modules/util/vectools.py deleted file mode 100644 index 860cd568875..00000000000 --- a/intern/python/modules/util/vectools.py +++ /dev/null @@ -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 - - - - |