# Porting a 3D Brownian Motion to Python mode

We all know @GoToLoop is such a wonderful and generous mega-blast of a fellow at the forums, so I always look at his postings, then today I was looking at an example shown at LinkedList vs ArrayList and decided to port it to Python mode On Python we can use `deque` as a queue.

I hope I have got this right, enjoy!

``````"""
Brownian Motion (v3.00)
by Ammon.Owed (2013/Aug)
mod: GoToLoop
port to Python: Villares (2020)
Forum.Processing.org/two/discussion/2829/fifo-queue-problem-with-code#Item_1
OpenProcessing.org/sketch/878458
Bl.ocks.org/GoToLoop/145418d1dfb062c7c41a630bce5b8374
"""

from __future__ import division
from collections import deque

TITLE1, TITLE2 = "Brownian Motion     FPS: ", "     Size: "

HAS_MAX_LIMIT = False

DIM, LIMIT, DETAIL, DEPTH = 100, 03000, 1000, 2000
HUE = 1 << 10
HUE_M1 = HUE - 1
FPS, MIN_FPS, SMOOTH = 60, 40, 2
BOLD, AMP = 1.5, 10

points = deque(maxlen=LIMIT)
cam = PVector()
lp = PVector()

paused = False

def setup():
global canvasRatio, zNear, zFar, frame_rate

size(950, 600, P3D)

smooth(SMOOTH)
frameRate(FPS)

colorMode(HSB, HUE, 1, 1)
strokeWeight(BOLD)
noFill()

canvasRatio = float(width / height)

camZ = .5 * height / tan(PI * FPS / 360)
zNear = camZ / AMP
zFar = camZ * AMP

frame_rate = LIMIT << 1

def draw():
global cam, lp
# Local-cached & short-named variables:
fr = round(frame_rate)
len_p = len(points)
fc = frameCount

this.surface.setTitle(TITLE1 + str(fr) + TITLE2 + str(len_p))

# Recycled or new vector point:
if len_p != 0 and (not HAS_MAX_LIMIT and fr <= MIN_FPS
or HAS_MAX_LIMIT and len_p >= LIMIT):
np = points.popleft()
else:
np = PVector()

# Interpolated rotating camera aimed at latest added point (tail):
cam *= .99

camera(
cam.x + sin(.01 * fc) * DETAIL,
cam.y + cos(8e-3 * fc + 10) * DETAIL,
cam.z - DEPTH,
cam.x, cam.y, cam.z,
0, 1, 0
)

# perspective()
perspective(THIRD_PI, canvasRatio, zNear, zFar)

# Draw colored curved lines:
background(0)

beginShape()
for p in points:
fc += 1
stroke(fc & HUE_M1, 1, 1)
curveVertex(p.x, p.y, p.z)
endShape()

# Generate a new point at specified range:
np = PVector.random3D(np).mult(DIM)  # pick a new random direction.
# add that up from latest point.
# this is now the latest point too.
lp.set(np)
# add new point to queue's tail.
points.append(np)

def mousePressed():
global paused
if mouseButton == RIGHT:
points.clear()
elif not paused:
paused = True
noLoop()
else:
paused = False
loop()
``````
3 Likes

Now a very simplified approach:

``````"""
Inspired by
"""

from collections import deque

points = deque(maxlen=150)
paused = False
DIM = 25

def setup():
size(500, 500, P3D)
colorMode(HSB)
noFill()
points.append(PVector())  # starts with PVector(0, 0, 0)

def draw():
background(0)
translate(width / 2, height / 2)
rotateY(frameCount / 100.)

beginShape()
for i, p in enumerate(points):
stroke((frameCount + i) % 256, 255, 255)
curveVertex(p.x, p.y, p.z)
endShape()

if not paused:
v = points[-1]
n = v + PVector.random3D() * DIM
points.append(n)
for p in points:
p -= n / 30

def mousePressed():
global paused
if mouseButton == RIGHT:
points.clear()
points.append(PVector())
elif not paused:
paused = True
noLoop()
else:
paused = False
loop()
``````
1 Like