From b092b13fc34c5d73f33447f16075bad80c752183 Mon Sep 17 00:00:00 2001 From: Joseph Masom Date: Fri, 9 Dec 2022 10:07:40 -0500 Subject: [PATCH 1/3] implement noisy sanding --- vRuffle.py | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/vRuffle.py b/vRuffle.py index a23648f..f96da75 100644 --- a/vRuffle.py +++ b/vRuffle.py @@ -4,6 +4,7 @@ import random import time import itertools +from perlin_noise import PerlinNoise ############### ### GLOBALS ### @@ -16,9 +17,11 @@ MIN_SAND = 0.1 MAX_SAND = 0.3 +SAND_RANGE = (MIN_SAND, MAX_SAND) MIN_COLOR = np.array([245, 225, 160]) MAX_COLOR = np.array([255, 255, 255]) +COLOR_RANGE = (MIN_COLOR, MAX_COLOR) MAX_VEL = 150 @@ -55,6 +58,25 @@ def transformRange(val, r1, r2): perc = np.linalg.norm(val - r1[0]) / np.linalg.norm(r1[1] - r1[0]) return r2[0] + perc * (r2[1] - r2[0]) +def generateNoise(baseOctaves, numComponents): + # baseOctave increases the zoom, numComponents increases the detail + noises, coeffs = [], [] + for i in range(numComponents): + coeff = 0.5**i + noises.append(PerlinNoise(octaves=baseOctaves / coeff)) + coeffs.append(coeff) + + def getNoise(pnt): + val = 0 + for i in range(numComponents): + noise, coeff = noises[i], coeffs[i] + val += coeff * noise(pnt) + return val + + absThresh = np.sqrt(0.5) * sum(coeffs) + + return getNoise, absThresh + class PlayingField: def __init__(self,left1,left2,left3,left4,right1,right2,right3,right4): self.left1 = left1 @@ -67,7 +89,7 @@ def __init__(self,left1,left2,left3,left4,right1,right2,right3,right4): self.right4 = right4 self.sandBoard = np.ones((tableWidth, tableHeight)) * MIN_SAND self.colorGradient = np.ones((tableWidth, tableHeight, 3)) * MIN_COLOR - choice = random.randint(0,2) + choice = 3#random.randint(0,3) # if choice == 0: # print("constant sanding") # self.fill_board(self.const_sand) @@ -80,14 +102,15 @@ def __init__(self,left1,left2,left3,left4,right1,right2,right3,right4): elif choice == 2: print("staggered sanding") self.fill_board(self.staggered) + elif choice == 3: + print("noisy sanding") + self.noisy_fill() def __setitem__(self, idx, val): self.sandBoard[idx] = val - self.colorGradient[idx] = transformRange( - self.sandBoard[idx], - (MIN_SAND, MAX_SAND), - (MIN_COLOR, MAX_COLOR) - ) + self.colorGradient[idx] = transformRange(self.sandBoard[idx], + SAND_RANGE, + COLOR_RANGE) def __getitem__(self, idx): return self.sandBoard[idx] @@ -155,6 +178,15 @@ def staggered(self, i, j): else: return random.uniform(third_qtl_sand, MAX_SAND) + def noisy_fill(self): + noise, absThresh = generateNoise(8, 3) + noiseRange = (-absThresh, absThresh) + for i in range(tableWidth): + for j in range(tableHeight): + pnt = [i/tableWidth, j/tableHeight] + noiseVal = noise(pnt) + self[i, j] = transformRange(noiseVal, noiseRange, SAND_RANGE) + class Puck: def __init__(self,num,pos,vel=np.array([0,0])): self.radius = 15 From 394db5baece37a4ff73af616b74659e3fba00625 Mon Sep 17 00:00:00 2001 From: Joseph Masom Date: Sat, 10 Dec 2022 13:32:41 -0500 Subject: [PATCH 2/3] set noise generation defaults and add variable decay rate --- vRuffle.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/vRuffle.py b/vRuffle.py index f96da75..2233fce 100644 --- a/vRuffle.py +++ b/vRuffle.py @@ -58,11 +58,12 @@ def transformRange(val, r1, r2): perc = np.linalg.norm(val - r1[0]) / np.linalg.norm(r1[1] - r1[0]) return r2[0] + perc * (r2[1] - r2[0]) -def generateNoise(baseOctaves, numComponents): +def generateNoise(baseOctaves, numComponents=1, decayRate=0.5): # baseOctave increases the zoom, numComponents increases the detail noises, coeffs = [], [] for i in range(numComponents): - coeff = 0.5**i + + coeff = decayRate**i noises.append(PerlinNoise(octaves=baseOctaves / coeff)) coeffs.append(coeff) @@ -179,7 +180,7 @@ def staggered(self, i, j): return random.uniform(third_qtl_sand, MAX_SAND) def noisy_fill(self): - noise, absThresh = generateNoise(8, 3) + noise, absThresh = generateNoise(8, numComponents=3) noiseRange = (-absThresh, absThresh) for i in range(tableWidth): for j in range(tableHeight): From a58f561031efb850daa8bc5718c8e994cb0e83c6 Mon Sep 17 00:00:00 2001 From: Joseph Masom Date: Mon, 12 Dec 2022 12:11:17 -0500 Subject: [PATCH 3/3] clean up initial board filling flow --- vRuffle.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/vRuffle.py b/vRuffle.py index 2233fce..ba2d1be 100644 --- a/vRuffle.py +++ b/vRuffle.py @@ -55,10 +55,12 @@ def blur(a): return arraylist_sum def transformRange(val, r1, r2): - perc = np.linalg.norm(val - r1[0]) / np.linalg.norm(r1[1] - r1[0]) + normalize = np.vectorize(np.linalg.norm) + perc = normalize(val - r1[0]) / normalize(r1[1] - r1[0]) + if len(np.shape(r2[0])) > 0: perc = np.expand_dims(perc, axis=-1) return r2[0] + perc * (r2[1] - r2[0]) -def generateNoise(baseOctaves, numComponents=1, decayRate=0.5): +def generateNoise(baseOctaves, numComponents, decayRate): # baseOctave increases the zoom, numComponents increases the detail noises, coeffs = [], [] for i in range(numComponents): @@ -96,16 +98,17 @@ def __init__(self,left1,left2,left3,left4,right1,right2,right3,right4): # self.fill_board(self.const_sand) if choice == 0: print('slow mid sanding') - self.fill_board(self.slow_mid) + filler = self.slow_mid elif choice == 1: print("slow outer sanding") - self.fill_board(self.slow_outer) + filler = self.slow_outer elif choice == 2: print("staggered sanding") - self.fill_board(self.staggered) + filler = self.staggered elif choice == 3: print("noisy sanding") - self.noisy_fill() + filler = self.build_noisy_filler(24, numComponents=3, decayRate=0.7) + self.fill_board(filler) def __setitem__(self, idx, val): self.sandBoard[idx] = val @@ -179,14 +182,14 @@ def staggered(self, i, j): else: return random.uniform(third_qtl_sand, MAX_SAND) - def noisy_fill(self): - noise, absThresh = generateNoise(8, numComponents=3) + def build_noisy_filler(self, octaves, numComponents=1, decayRate=0.5): + noise, absThresh = generateNoise(octaves, numComponents, decayRate) noiseRange = (-absThresh, absThresh) - for i in range(tableWidth): - for j in range(tableHeight): - pnt = [i/tableWidth, j/tableHeight] - noiseVal = noise(pnt) - self[i, j] = transformRange(noiseVal, noiseRange, SAND_RANGE) + windowSize = max(tableWidth, tableHeight) + def noisy_filler(i, j): + noiseVal = noise([i/windowSize, j/windowSize]) + return transformRange(noiseVal, noiseRange, SAND_RANGE) + return noisy_filler class Puck: def __init__(self,num,pos,vel=np.array([0,0])):