# # Code under the MIT license by Alexander Pruss # from mc import * import drawing from sys import argv import mcpi.settings as settings import ast RAINBOW = (WOOL_RED,WOOL_PINK,WOOL_ORANGE,WOOL_YELLOW,WOOL_GREEN,WOOL_BLUE,WOOL_LIGHT_BLUE,WOOL_PURPLE) TAN30 = sqrt(3.)/3 SQRT32 = sqrt(3./2) def parseBlock(s): try: return ast.literal_eval(s) except: return globals()[s.upper()] def distance(a,b): return sqrt((a[0]-b[0])**2+(a[1]-b[1])**2+(a[2]-b[2])**2) def tetrahedronBottom(height, apex): side = SQRT32*height return ( (apex[0]-0.5*TAN30*side,apex[1]-height,apex[2]-0.5*side), (apex[0]-0.5*TAN30*side,apex[1]-height,apex[2]+0.5*side), (apex[0]+TAN30*side,apex[1]-height,apex[2]) ) def drawTetrahedron(height, apex, block): bottom = tetrahedronBottom(height, apex) for i in range(int(round(height))+1): triangle = [] for point in bottom: a = float(i)/height triangle.append(((1-a)*apex[0]+a*point[0],apex[1]-i,(1-a)*apex[2]+a*point[2])) d.face(triangle,block) return triangle def average(a,b): return tuple(0.5*(a[i]+b[i]) for i in range(len(a))) def transform(tet): level, height, apex = tet[0],tet[1],tet[2] bottom = tetrahedronBottom(height,apex) yield (level,height/2.,apex) for p in bottom: yield (level+1,height/2.,average(apex,p)) def sierpinski(height, x,y,z, level): tetrahedra = [(0,height,(x,y,z))] for i in range(level): out = [] for tet in tetrahedra: out += transform(tet) tetrahedra = out return tetrahedra mc = Minecraft() d = drawing.Drawing(mc) pos = mc.player.getPos() height = 240 if not settings.isPE else 128 levels = 7 mc.player.setPos(tetrahedronBottom(height,(pos.x,pos.y+height,pos.z))[0]) tetrahedra = sierpinski(height,pos.x,pos.y+height,pos.z,levels) mc.postToChat("Drawing") if len(argv) >= 2 and '__' not in argv[1]: specifiedBlock = parseBlock(argv[1]) block = lambda level : specifiedBlock else: block = lambda level : RAINBOW[level % len(RAINBOW)] for tet in tetrahedra: drawTetrahedron(tet[1],tet[2],block(tet[0]))