Skip to content

Instantly share code, notes, and snippets.

@Krewn
Created September 29, 2022 21:44
Show Gist options
  • Save Krewn/02750cc7502985f7170505afd804de65 to your computer and use it in GitHub Desktop.
Save Krewn/02750cc7502985f7170505afd804de65 to your computer and use it in GitHub Desktop.
Implementation of semi random motion in 2 dimensions.
import pygame
import math
import time
import drunk
import random
width=1000
height=1000
padding = 10
screenColor=(0,0,0)
lineColor=(255,255,255)
screen=pygame.display.set_mode((width+padding,height+padding))
start=time.time()
drunkards = [drunk.drunkard((500,500),420),
drunk.drunkard((500,500),420,jerk=5),
drunk.drunkard((500,500),210,jerk=10),
drunk.drunkard((500,500),210,jerk=10,contained=False)]
for k in range(100):
drunkards.append(drunk.drunkard((500,500),420+160*(random.random()-1),jerk = random.choice([1,2,3,4,5,6,7]),contained=random.choice([True,False])))
points = [ drunkard.nextPosition() for drunkard in drunkards ]
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.KEYDOWN:
pass
#if event.key == pygame.K_LEFT:
if event.type == pygame.KEYUP:
pass
#if event.key == pygame.K_LEFT:
screen.fill(screenColor)
nextPoints = [ drunkard.nextPosition() for drunkard in drunkards ]
for a,b in zip(points,nextPoints):
pygame.draw.line(screen, (255,255,255), a,b)
points = nextPoints
pygame.display.flip()
time.sleep(0.05)
filename = input("FileName:")
pygame.image.save(screen, filename+".PNG")
import os
def fairCoin():
return os.urandom(1)[0] >= 128
def dist(a,b):
return sum((i-j)**2 for i,j in zip(a,b))**0.5
def mag(a):
return dist(a,(0,0))
def dot(a,b):
return sum([i*j for i,j in zip(a,b)])
def cos(a,b):
return dot(a,b)/(mag(a)*mag(b))
def proj(a,b):
return mag(a)*cos(a,b)
def scaleTo(s,a):
m = mag(a)
return [s*k/m for k in a]
class drunkard:
def __init__(self,origin,radius,jerk=1,contained = True):
self.vmax = int(radius/10)
self.origin = origin
self.position = list(origin)
self.radius = radius
self.jerk=jerk
self.velocity = [0,0]
self.edgeHits = 0
self.contained = contained
def spotCoin(self,idx):
radiusPortion = (self.position[idx]-self.origin[idx])/self.radius
return 1 if os.urandom(1)[0]>=128+128*radiusPortion else -1
def speedCoin(self,idx):
if mag(self.velocity) == 0:
return fairCoin()
vmaxPortion = dist(self.velocity,(0,0))/self.vmax
dimPortion = proj(scaleTo(vmaxPortion,self.velocity),(0,1) if idx else(1,0))
return 1 if os.urandom(1)[0]>=128+128*dimPortion else -1
def updateVelocity(self):
self.velocity[0] += self.speedCoin(0)*self.jerk
self.velocity[1] += self.speedCoin(1)*self.jerk
self.velocity[0] += self.spotCoin(0)*self.jerk
self.velocity[1] += self.spotCoin(1)*self.jerk
if mag(self.velocity) > self.vmax:
self.velocity[0] = int(self.velocity[0]*self.vmax/mag(self.velocity))
self.velocity[1] = int(self.velocity[1]*self.vmax/mag(self.velocity))
def nextPosition(self):
self.updateVelocity()
newPosition = [start+delta for start,delta in zip(self.position,self.velocity)]
if dist(newPosition,self.origin) > self.radius:
if self.contained:
self.velocity = [0,0]
self.edgeHits += 1
print("Boundry Collisions: "+str(self.edgeHits)+" ",end="\r")
self.position = newPosition
return self.position
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment