# Prime Spiral

Being fascinated by prime numbers I wanted to create a prime number spiral generator myself. It just goes through the numbers from 0 to … and checks if they are prime. If they are prime, this rectangle in the spiral gets lit red, if it is not prime it gets lit dark gray. Because my algorithm for prime checking is very basic, I implemented a performance helper. That way the spiral’s creation will slow down after time (due to the numbers that need to be checked getting bigger and bigger). The really interesting thing is, that – although they may seem random – prime numbers often form lines if shown in such a spiral. To see the comparison I included an image of a randomly (50% to 50%) lit up board.

``````# Python 2.7.7 Code
# Pygame 1.9.1 (for Python 2.7.7)
# Jonathan Frech 28th of May, 2015``````

``````# importing needed modules
import pygame, sys, time, math, os, random

""" CLASSES """
# dummy class for global variables
class dummy():
pass

# entity class
class entity():
# init
def __init__(self, _pos, _number):
self.pos = _pos
self.number = _number

self.size = main.ENTITYSIZE
self.screenPos = [self.pos[0] * self.size[0], self.pos[1] * self.size[1]]

# calculate color based of number
if self.number == 0:
# color in begin
self.color = [255, 255, 255]
elif lit(self.number):
# color in lit numbers
self.color = [255, 0, 0]
else:
# color in checked but not lit numbers
self.color = [50, 50, 50]

# self.dead defines if entity is alive

# render the entity and set self.dead
# to True (for better performance)
def render(self, _surface):
pygame.draw.rect(_surface, self.color, [self.screenPos[0], self.screenPos[1], self.size[0], self.size[1]])

""" FUNCTIONS """
# checks if given number should be lit on
def lit(_num):
# prime check
if _num <= 1: 		return False 	for _ in range(2, _num): 		if _num % _ == 0: 			return False 	return True # adds in a new entity # (on next spiral position) def addNew(): 	# change main.POS 	if main.DIR == "up": 		main.POS[1] -= 1 	elif main.DIR == "down": 		main.POS[1] += 1 	elif main.DIR == "left": 		main.POS[0] -= 1 	elif main.DIR == "right": 		main.POS[0] += 1 	 	# change direction if needed 	main.CURRENT += 1 	if main.CURRENT > int(main.MAX):
main.CURRENT = 0
main.MAX += .5
if main.DIR == "up":
main.DIR = "left"
elif main.DIR == "down":
main.DIR = "right"
elif main.DIR == "left":
main.DIR = "down"
elif main.DIR == "right":
main.DIR = "up"

main.ENTITIES.append(entity(main.POS[:], main.NUM))

# main.NUM gets increased
main.NUM += 1

# gets the mouse position
def getMousePos():
p = pygame.mouse.get_pos()
return [p[0], p[1]]

# validates color integer
# extra feature: _min and _max implementation
def colorValid(_color, _min = 0, _max = 255):
newColor = math.fabs(_color)
n = _max - _min
if newColor > n:
if int(newColor / n) % 2 == 0:
newColor = newColor % n
else:
newColor = n - (newColor % n)

return int(newColor) + _min

# gets the position on a circle
# circle center                           : '_pos'
# angle from center to point on the circle: '_angle'
return [
]

# returns an integer version of given positon
def intpos(_pos):
return [int(_pos[0]), int(_pos[1])]

# basic vector functions
def vecConvert(p1, p2):
return [p2[0] - p1[0], p2[1] - p1[1]]
def vecLen(vec):
return math.sqrt( (vec[0]**2) + (vec[1]**2) )
def vecMultiply(vec, n):
return [vec[0] * n, vec[1] * n]
def vecGetPoint(vec, point):
return [point[0] + vec[0], point[1] + vec[1]]
return [vec1[0] + vec2[0], vec1[1] + vec2[1]]

# calculates distance between given positions
def posDistance(p1, p2):
return math.sqrt( (p2[0] - p1[0])**2 + (p2[1] - p1[1])**2 )

# quits the program
def quit():
sys.exit()

""" TICK; RENDER """
# tick function
def tick():
# handle events
for event in pygame.event.get():
# quit
if event.type == pygame.QUIT:
quit()

# keyup
if event.type == pygame.KEYUP:
# handle 'main.KEYSDOWN'
if event.key in main.KEYSDOWN:
main.KEYSDOWN.remove(event.key)

# keydown
if event.type == pygame.KEYDOWN:
# handle 'main.KEYSDOWN'
if event.key not in main.KEYSDOWN:
main.KEYSDOWN.append(event.key)

for _ in range(0, main.ENTITYAPPEARANCESPEED):
# permormance assurance
if len(main.ENTITIES) <	main.ENTITYAPPEARANCESPEED * 2: 			addNew() 	 	# remove already drawn (dead) entities 	for _ in main.ENTITIES: 		if _.dead: 			main.ENTITIES.remove(_) # render function def render(): 	# render entities 	for _ in main.ENTITIES: 		_.render(main.SURF) 	 	# blit and flip 	main.SCREEN.blit(main.SURF, [0, 0]) 	pygame.display.flip() """ INIT """ # initialize program def init(): 	main.WIDTH, main.HEIGHT = 1080, 720 	main.SIZE = [main.WIDTH, main.HEIGHT] 	main.CENTER = [main.WIDTH / 2., main.HEIGHT / 2.] 	 	main.SCREEN = pygame.display.set_mode(main.SIZE) 	 	 	main.SURF = pygame.Surface(main.SIZE) 	main.COLOR = [0, 0, 0] 	 	main.TICKS = 0 	main.KEYSDOWN = [] 	main.CAPTION = "Prime Spiral" 	 	# entity init 	main.ENTITIES = [] 	main.ENTITYSIZE = [2, 2] 	main.ENTITYAPPEARANCESPEED = 20 	 	main.DIR = "up" 	main.CURRENT = -1 	main.MAX = 0 	main.POS = intpos([main.CENTER[0] / main.ENTITYSIZE[0], main.CENTER[1] / main.ENTITYSIZE[1]]) 	main.NUM = 0 	 	# functions 	pygame.display.set_caption(main.CAPTION) 	main.SURF.fill(main.COLOR) """ RUN """ # run function (uses tick() and render()) def run(): 	ticksPerSecond = 60 	lastTime = time.time() * 1000000000 	nsPerTick =  1000000000.0 / float(ticksPerSecond) 	 	ticks = 0 	frames = 0 	 	lastTimer = time.time() * 1000 	delta = 0.0 	 	while True: 		now = time.time() * 1000000000 		delta += float(now - lastTime) / float(nsPerTick) 		lastTime = now 		shouldRender = False 				 		while delta >= 1:
ticks += 1
main.TICKS += 1
tick()
delta -= 1
shouldRender = True

if shouldRender:
frames += 1
render()

if time.time() * 1000 - lastTimer >= 1000:
lastTimer += 1000

# debug
#print("Frames: " + str(frames) + ", ticks: " + str(ticks))

frames = 0
ticks = 0

# main variable
main = dummy()
init()

# start program
run()``````