Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python3
- import math
- class IcoSphereCreator:
- class MeshGeometry3D:
- positions = []
- TriangleIndices = []
- class TriangleIndices:
- def __init__(self, v1, v2, v3):
- self.v1 = v1
- self.v2 = v2
- self.v3 = v3
- class Point3D:
- def __init__(self, X, Y, Z):
- self.X = X
- self.Y = Y
- self.Z = Z
- geometry = MeshGeometry3D()
- index = -1
- middlePointIndexCache = {}
- def addVertex(self, p):
- length = math.sqrt(p.X * p.X + p.Y * p.Y + p.Z * p.Z)
- self.geometry.positions.append(self.Point3D(p.X/length, p.Y/length, p.Z/length))
- self.index += 1
- return self.index
- def getMiddlePoint(self, p1, p2):
- firstIsSmaller = p1 < p2
- smallerIndex = p1 if firstIsSmaller else p2
- greaterIndex = p2 if firstIsSmaller else p1
- key = (smallerIndex << 32) + greaterIndex;
- if key in self.middlePointIndexCache:
- return self.middlePointIndexCache[key]
- point1 = self.geometry.positions[p1]
- point2 = self.geometry.positions[p2]
- middle = self.Point3D(
- (point1.X + point2.X) / 2.0,
- (point1.Y + point2.Y) / 2.0,
- (point1.Z + point2.Z) / 2.0
- )
- i = self.addVertex(middle)
- self.middlePointIndexCache[key] = i
- return i
- def create(self, recursionLevel):
- # create 12 vertices of a icosahedron
- t = (1.0 + math.sqrt(5.0)) / 2.0
- self.addVertex(self.Point3D(-1, t, 0))
- self.addVertex(self.Point3D( 1, t, 0))
- self.addVertex(self.Point3D(-1, -t, 0))
- self.addVertex(self.Point3D( 1, -t, 0))
- self.addVertex(self.Point3D( 0, -1, t))
- self.addVertex(self.Point3D( 0, 1, t))
- self.addVertex(self.Point3D( 0, -1, -t))
- self.addVertex(self.Point3D( 0, 1, -t))
- self.addVertex(self.Point3D( t, 0, -1))
- self.addVertex(self.Point3D( t, 0, 1))
- self.addVertex(self.Point3D(-t, 0, -1))
- self.addVertex(self.Point3D(-t, 0, 1))
- # create 20 triangles of the icosahedron
- faces = []
- # 5 faces around point 0
- faces.append(self.TriangleIndices(0, 11, 5))
- faces.append(self.TriangleIndices(0, 5, 1))
- faces.append(self.TriangleIndices(0, 1, 7))
- faces.append(self.TriangleIndices(0, 7, 10))
- faces.append(self.TriangleIndices(0, 10, 11))
- # 5 adjacent faces
- faces.append(self.TriangleIndices(1, 5, 9))
- faces.append(self.TriangleIndices(5, 11, 4))
- faces.append(self.TriangleIndices(11, 10, 2))
- faces.append(self.TriangleIndices(10, 7, 6))
- faces.append(self.TriangleIndices(7, 1, 8))
- # 5 faces around point 3
- faces.append(self.TriangleIndices(3, 9, 4))
- faces.append(self.TriangleIndices(3, 4, 2))
- faces.append(self.TriangleIndices(3, 2, 6))
- faces.append(self.TriangleIndices(3, 6, 8))
- faces.append(self.TriangleIndices(3, 8, 9))
- # 5 adjacent faces
- faces.append(self.TriangleIndices(4, 9, 5))
- faces.append(self.TriangleIndices(2, 4, 11))
- faces.append(self.TriangleIndices(6, 2, 10))
- faces.append(self.TriangleIndices(8, 6, 7))
- faces.append(self.TriangleIndices(9, 8, 1))
- for i in range(0, recursionLevel):
- faces2 = []
- for tri in faces:
- # replace triangle by 4 triangles
- a = self.getMiddlePoint(tri.v1, tri.v2)
- b = self.getMiddlePoint(tri.v2, tri.v3)
- c = self.getMiddlePoint(tri.v3, tri.v1)
- faces2.append(self.TriangleIndices(tri.v1, a, c))
- faces2.append(self.TriangleIndices(tri.v2, b, a))
- faces2.append(self.TriangleIndices(tri.v3, c, b))
- faces2.append(self.TriangleIndices(a, b, c))
- faces = faces2
- for tri in faces:
- self.geometry.TriangleIndices.append(tri.v1)
- self.geometry.TriangleIndices.append(tri.v2)
- self.geometry.TriangleIndices.append(tri.v3)
- return self.geometry
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement