Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import scipy.constants as spc
- import math
- import json
- # Compute u - v
- def vecDiff(u, v):
- if type(u) is not list and type(v) is not list and len(u) != len(v):
- raise TypeError("Arguements must be lists of the same size.")
- return list( \
- map( \
- lambda m, n : m - n, \
- u, \
- v, \
- ) \
- )
- # Compute u . v
- def dotProd(u, v):
- if type(u) is not list and type(v) is not list and len(u) != len(v):
- raise TypeError("Arguements must be lists of the same size.")
- return sum( \
- map( \
- lambda m, n : m * n, \
- u, \
- v, \
- ) \
- )
- # Compute ||v||
- def eucNorm(v):
- return dotProd(v, v) ** 0.5
- # Compute v / ||v||
- def normalize(v):
- n = eucNorm(v)
- return list( \
- map( \
- lambda i : round(i / n, 10), \
- v \
- ) \
- )
- # Compute u x v
- def crossProd(u, v):
- # Remember: x:0, y:1, z:2
- return [\
- u[1] * v[2] - u[2] * v[1], \
- - (u[0] * v[2] - u[2] * v[0]), \
- u[0] * v[1] - u[1] * v[0] \
- ]
- # Get the vertex IDs neighboring a given vertex
- def getNeighbors(n):
- global edges
- pairsNFirst = edges[5*n:5*n+5]
- return tuple( \
- map( \
- lambda p : p[1], \
- pairsNFirst
- ) \
- )
- # Get the angle between two vectors
- def vecAngle(u, v):
- return math.degrees(
- math.acos(
- dotProd(u, v) / (eucNorm(u) * eucNorm(v))
- )
- )
- v = [spc.golden, 1, 0]
- vertices = []
- for j in range(4):
- for k in range(3):
- vertices.append(v.copy())
- t = v.pop()
- v.insert(0, t)
- v[(j + 2) % 2] *= -1
- vertices.sort(key = lambda v : v[1])
- for u in vertices:
- print(vertices.index(u), ':', u)
- edges = []
- for u in vertices:
- for w in vertices:
- if w != u:
- d = vecDiff(u, w)
- n = eucNorm(d)
- if round(n, 4) != 2.0000:
- continue
- edges.append((vertices.index(u), vertices.index(w)))
- edges.sort()
- for e in edges:
- i = edges.index(e)
- print( \
- i, ':', e, \
- end = '\n' if (i + 1) % 5 == 0 else '\t' \
- )
- triangles = []
- for n in range(12):
- neighborsN = getNeighbors(n)
- for m in neighborsN:
- neighborsM = getNeighbors(m)
- for k in neighborsM:
- if n in getNeighbors(k):
- t = tuple(sorted([n, m, k]))
- if t not in triangles:
- triangles.append(t)
- else:
- continue
- else:
- continue
- for t in triangles:
- print(triangles.index(t), ':', t)
- triangleData = {}
- neededCrossProdRedo = []
- for t in triangles:
- e1 = vecDiff(vertices[t[1]], vertices[t[0]])
- e2 = vecDiff(vertices[t[2]], vertices[t[0]])
- n = normalize(crossProd(e1, e2))
- if vecAngle(n, vertices[t[0]]) > 90.0:
- n = normalize(crossProd(e2, e1))
- neededCrossProdRedo.append(triangles.index(t))
- triangleData[triangles.index(t)] = { \
- "vertices" : t, \
- "normal": tuple(n) \
- }
- for k in neededCrossProdRedo:
- temp = list(triangleData[k]["vertices"])
- a = temp[2]
- temp[2] = temp[1]
- temp[1] = a
- triangleData[k]["vertices"] = tuple(temp)
- for n in triangleData.keys():
- print( \
- n, ':', \
- "vertices:", triangleData[n]["vertices"], \
- "; normal:", triangleData[n]["normal"] \
- )
- if input("Write a new .obj file? [Y/n]: ").upper() == 'Y':
- objFile = open("ccIcosahedron.obj", 'w')
- for v in vertices:
- objFile.write("v ")
- s = 0
- for c in v:
- objFile.write(str(c))
- if s < 2:
- objFile.write(' ')
- s += 1
- objFile.write('\n')
- objFile.write("vt 0.0 0.0\nvt 0.5 1.0\nvt 1.0 0.0\n")
- for k in range(20):
- objFile.write("vn ")
- s = 0
- for c in triangleData[k]["normal"]:
- objFile.write(str(c))
- if s < 2:
- objFile.write(' ')
- s += 1
- objFile.write('\n')
- for k in range(20):
- objFile.write("f ")
- s = 0
- for c in triangleData[k]["vertices"]:
- objFile.write(str(c + 1) + '/' + str(s + 1) + '/' + str(k + 1))
- if s < 2:
- objFile.write(' ')
- s += 1
- objFile.write('\n')
- objFile.close()
- print("File created!")
- jsonDumpFile = open("icosaGenDump.json", 'w')
- jsonDumpFile.write(json.dumps(vertices, indent = 4))
- jsonDumpFile.write('\n')
- jsonDumpFile.write(json.dumps(triangleData, indent = 4))
- jsonDumpFile.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement