-
Notifications
You must be signed in to change notification settings - Fork 0
/
LinAlgOps.py
79 lines (63 loc) · 2.5 KB
/
LinAlgOps.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import numpy
def calc_normal(v0, v1):
normal = numpy.cross(v1,v0)
return normalize(normal)
def normalize(vector):
norm = numpy.linalg.norm(vector)
return (vector[0]/norm,vector[1]/norm,vector[2]/norm)
def get_vector(v0, v1):
x = v1[0] - v0[0]
y = v1[1] - v0[1]
z = v1[2] - v0[2]
return numpy.array([x,y,z])
def calc_face_normals(heights, convert):
'''dict of face normals with vertex : array of face normals it's a part of'''
#vertex : normal
face_normals = {}
#points on face (tuple, clockwise starting with the upper left vertex) : normal
face = {}
for x in range(0, len(heights)-1):
for z in range(0, len(heights[x])-1):
p3 = (convert.convert_for_triangle('x', (x+1)), heights[x+1][z], convert.convert_for_triangle('z', z))
p2 = (convert.convert_for_triangle('x', x), heights[x][z+1], convert.convert_for_triangle('z', (z+1)))
p0 = (convert.convert_for_triangle('x', x), heights[x][z], convert.convert_for_triangle('z', z))
p1 = (convert.convert_for_triangle('x', (x+1)), heights[x+1][z+1], convert.convert_for_triangle('z', (z+1)))
v0 = get_vector(p0, p1)
v1 = get_vector(p0, p2)
v2 = get_vector(p0, p3)
f0 = calc_normal(v0, v1)
f1 = calc_normal(v2, v0)
if not p0 in face_normals:
face_normals[p0] = [f0, f1]
else:
face_normals[p0].append(f0)
face_normals[p0].append(f1)
if not p1 in face_normals:
face_normals[p1] = [f0, f1]
else:
face_normals[p1].append(f0)
face_normals[p1].append(f1)
if not p2 in face_normals:
face_normals[p2] = [f0]
else:
face_normals[p0].append(f0)
if not p3 in face_normals:
face_normals[p3] = [f1]
else:
face_normals[p3].append(f1)
face[(p0, p1, p2)] = f0
face[(p0, p3, p1)] = f1
for point in face_normals.iterkeys():
face_normals[point] = calc_vert_normals(face_normals[point])
return (face, face_normals)
def calc_vert_normals(normals):
avg = [0,0,0]
for face in normals:
avg[0] += face[0]
avg[1] += face[1]
avg[2] += face[2]
leng = len(normals)
avg[0] /= leng
avg[1] /= leng
avg[2] /= leng
return normalize(numpy.array([avg[0],avg[1],avg[2]]))