Starting from an array of [0, 0, 0] points, we run a number of iterations that transform each point with one of four functions, with given probabilities (equal by default).
import numpy as np
N = 30000
x = np.zeros(N)
y = np.zeros(N)
z = np.zeros(N)
x1 = np.empty_like(x)
y1 = np.empty_like(y)
z1 = np.empty_like(z)
# Sierpinski triangle iterative functions
def f1(x,y,z,x1,y1,z1,c):
x1[c] = 1.0/2.0*x[c]
y1[c] = 1.0/2.0*y[c]
z1[c] = 1.0/2.0*z[c]
def f2(x,y,z,x1,y1,z1,c):
x1[c] = 1.0/2.0*x[c] + 1/2.0
y1[c] = 1.0/2.0*y[c]
z1[c] = 1.0/2.0*z[c]
def f3(x,y,z,x1,y1,z1,c):
x1[c] = 1.0/2.0*x[c] + 1/4.
y1[c] = 1.0/2.0*y[c] + np.sqrt(3)/4
z1[c] = 1.0/2.0*z[c]
def f4(x,y,z,x1,y1,z1,c):
x1[c] = 1.0/2.0*x[c] + 1/4.
y1[c] = 1.0/2.0*y[c] + 1./4
z1[c] = 1.0/2.0*z[c] + np.sqrt(3)/4
functions = [f1, f2, f3, f4]
probabilities = [1/4.]*4
assert(len(functions) == len(probabilities))
X,Y,Z = x,y,z
for i in range(20):
# pick indices for each function to be applied
r = np.random.choice(len(probabilities), size=N, p=probabilities)
for i, f in enumerate(functions):
f(x, y, z, x1, y1, z1, r==i)
x,x1 = x1,x
y,y1 = y1,y
z,z1 = z1,z
if i > 0:
X, Y, Z = np.hstack([X,x]), np.hstack([Y,y]), np.hstack([Z,z])
# how much memory are we using, how many points there are
print(3*X.nbytes//1024**2,"MB",X.shape[0])
Now we turn separate coordinate array into triplets.
Using numpy
for what could also be written as list(zip(X, Y, Z))
.
positions = np.vstack([X, Y, Z]).T.copy()
import k3d
plot = k3d.plot()
point_plot = k3d.points(positions.astype(np.float32), color=0xff0000, point_size=0.003, shader='3d')
plot += point_plot
plot.display()
Zoom in a little:
plot.camera = [-0.59265772150826,
1.0966590944867525,
0.15381683182413644,
0.35173312413637553,
0.35752558265043016,
0.3151305910837551,
-0.5602813338387698,
-0.7160643522547137,
-0.41633720753942915]