blender/intern/python/modules/util/vectools.py
2002-10-12 11:37:38 +00:00

143 lines
3.1 KiB
Python

"""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