In [ ]:
# generate a list of Fibonacci series starting with 1
import itertools
import math
import numpy as np
def fib_function():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
def fib_list(n):
fib = fib_function()
return list(itertools.islice(fib,n+2))[2:]
In [ ]:
# return a range if the numbers are different
def ordered_range(a,b):
if (a == b):
return [a]
elif (a < b):
return range(a,b+1)
else:
return range(a,b-1,-1)
# replace None with previous value of coordinate
def replace_null(acc,p):
null_replacer = lambda (a,b): b if (a is None) else a
if not acc:
return [p]
else:
previous_point = acc[-1]
next_point = map(null_replacer, zip(p,previous_point))
return acc + [next_point]
# a point p has (x,y,z) coordinates
def line_coordinates(p1,p2):
x1,y1,z1 = p1[0],p1[1],p1[2]
x2,y2,z2 = p2[0],p2[1],p2[2]
points = reduce(replace_null,itertools.izip_longest(ordered_range(x1,x2),ordered_range(y1,y2),ordered_range(z1,z2)),[])
return points
In [ ]:
# generate the sequence [(1,0),(0,1),(-1,0),(0,-1),(1,0),...]
def next_mult((m,n)):
return (-1*n,m)
# return a new sequence = previous sequence + new segment
# and new start position for next segment new_start
def fib_segment((prev_sequence,(xm,zm)),segment_length):
start = prev_sequence[-1]
x1,y1,z1 = start[0],start[1],start[2]
x2,y2,z2 = x1 + (xm * segment_length), y1, z1 + (zm * segment_length)
new_segment = line_coordinates((x1,y1,z1),(x2,y2,z2))[1:]
new_sequence = prev_sequence + new_segment
return (new_sequence,next_mult((xm,zm)))
# fibonacci coordinates
# alternating x,z using next_mult
def fib_coords(start, n):
fib_series = fib_list(n)
fib_series.reverse()
fib_points = reduce(fib_segment,fib_series,([start],(1,0)))
return fib_points[0]
#logarithmic spiral functions
def log_spiral_xy(theta):
a = 1
b = 0.3
x = a*math.exp(b*theta)*math.cos(theta)
z = a*math.exp(b*theta)*math.sin(theta)
return (x,z)
def theta_to_xyz((x,y,z),t):
x1,z1 = log_spiral_xy(t)
return (x1,y,z1)
# log spiral coordinates
def log_sequence((x,y,z),n):
rads = np.arange(0,2*math.pi*n,0.1)
logseq = map(lambda t: tuple(map(lambda x, y: int(round(x + y)), (x,y,z), theta_to_xyz((x,y,z),t))) ,rads)
loglines = reduce(lambda acc,s: acc + line_coordinates(s[0],s[1]), zip(logseq,logseq[1:]),[])
return logseq
In [ ]:
# Minecraft initialization
# import sys
# sys.path.append('/Users/esumitra/workspaces/mc/mcpipy')
import mcpi.minecraft as minecraft
import mcpi.block as block
import time
mc = minecraft.Minecraft.create()
In [ ]:
# build in Minecraft
def build_fib(n,blockid):
pos = mc.player.getTilePos()
mc.postToChat("building in 5 seconds ...")
time.sleep(5)
x,y,z = pos.x,pos.y,pos.z
fclist = fib_coords((x,y,z),n)
for p in fclist:
mc.setBlock(p[0], p[1], p[2], blockid)
def build_log_spiral(n,blockid):
pos = mc.player.getTilePos()
mc.postToChat("building in 5 seconds ...")
time.sleep(5)
x,y,z = pos.x,pos.y,pos.z
fclist = log_sequence((x,y,z),n)
for p in fclist:
mc.setBlock(p[0], p[1], p[2], blockid)
In [ ]:
# build_fib(5, block.TNT.id)
# build_log_spiral(2, block.STONE.id)