PRBS visualisation in the style of turtle graphics

Having just watched two great Numberphile videos with Matt Henderson (1, 2), I was inspired to try visualising a PRBS in the style of turtle graphics. Below is my first quick experiment. The sequence used in this example is the 127-bit maximum length sequence from a 7-bit linear feedback shift register. Every 1 in the sequence makes the line steer left and every 0 makes the line steer right. I’m experimenting with longer PRBS sequences and other rules for steering the line based on the values.

#
# Visualise PRBS, turtle-graphics style - Written by Ted Burke 4-Feb-2022
#
# To convert individual PNG frames to a video animation:
#
#    ffmpeg -y -r 5 -f image2 -i %03d.png -vcodec libx264 -crf 25  -pix_fmt yuv420p test.mp4
#

import matplotlib.pyplot as plt
import numpy as np

# Generate PRBS
prbs = []
lfsr = np.ones(7, dtype=np.int8)
for i in range(2**7 - 1):
    prbs = prbs + [lfsr[0]]
    b = (lfsr[5] + lfsr[6]) % 2
    #lfsr = [b] + lfsr[:-1]
    lfsr = np.concatenate((np.array([b], dtype=np.int8), lfsr[:-1]))

for b in prbs:
    print(b, end=' ', flush=True)

# Create matplotlib figure
plt.figure(figsize=(4, 4), dpi=600)

# Generate 100 animation frames
for frame_index in range(100):
    # Print index for this frame and increment turning angle
    print(frame_index, end=' ', flush=True)
    theta = np.pi/(1.0 + frame_index*9.0/100) # each frame has slightly larger turning angle than the last
    
    # Generate series of complex points for this frame
    z = 0 + 0j;
    step = 0 + 1j;
    points = np.array([0 + 0j])
    for bit in prbs:
        # calculate next complex point and add it to the series for this frame
        step = step * np.exp(1j*(2*bit-1)*theta) # steer left for 1 or right for 0
        z += step
        points = np.append(points, z)
    
    # Rotate the entire series of points so that the final point is to the right of origin
    points = np.exp(-1j*np.angle(z)) * points
    
    # Clear the axes, then plot a line through the complex points in array a
    plt.cla()
    plt.xlim(-100, 100)
    plt.ylim(-100, 100)
    
    plt.plot(points.real, points.imag)
    
    # Save current frame to a numbered PNG file
    plt.savefig('{0:03d}.png'.format(frame_index))

Advertisement
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s