Last active
October 15, 2015 04:59
-
-
Save Aeon/9897f7ed59ef13e2bb2c to your computer and use it in GitHub Desktop.
Revisions
-
Aeon revised this gist
Oct 15, 2015 . 2 changed files with 109 additions and 22 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,84 @@ # translation to python for grasshopper # original: https://gist.github.com/mbostock/22fd67be72552774736d # import pdb import numpy def poissonDiscSampler(width, height, radius): k = 30 # maximum number of samples before rejection radius2 = radius * radius R = 3 * radius2 cellSize = radius * numpy.sqrt(0.5) gridWidth = int(numpy.ceil(width / cellSize)) gridHeight = int(numpy.ceil(height / cellSize)) grid = numpy.zeros((gridWidth * gridHeight, 2)) queue = [] queueSize = 0 sampleSize = 0 def poisson(): if not sampleSize: return sample(numpy.random.random() * width, numpy.random.random() * height) # Pick a random existing sample and remove it from the queue. while queueSize: i = numpy.floor(numpy.random.random() * queueSize) s = queue[i] # Make a new candidate between [radius, 2 * radius] from the existing sample. for j in range(0, k): a = 2 * numpy.pi * numpy.random.random() r = numpy.sqrt(numpy.random.random() * R + radius2) x = s[0] + r * numpy.cos(a) y = s[1] + r * numpy.sin(a) # Reject candidates that are outside the allowed extent, # or closer than 2 * radius to any existing sample. if 0 <= x and x < width and 0 <= y and y < height and far(x, y): return sample(x, y) queue[i] = queue[--queueSize] queue.length = queueSize def far(x, y): i = numpy.floor(x / cellSize) j = numpy.floor(y / cellSize) i0 = numpy.max(i - 2, 0) j0 = numpy.max(j - 2, 0) i1 = numpy.min(i + 3, gridWidth) j1 = numpy.min(j + 3, gridHeight) for j in range(j0, j1): o = j * gridWidth for i in range(i0, i1): s = grid[o + i]; if s: dx = s[0] - x dy = s[1] - y if dx * dx + dy * dy < radius2: return False return True def sample(x, y): s = [x, y] queue.append(s) # pdb.set_trace() grid[gridWidth * int(numpy.floor(y / cellSize)) + int(numpy.floor(x / cellSize))] = s ++sampleSize ++queueSize return s return poisson # execute the sampling sample = poissonDiscSampler(width, height, cellSize) samples = [] s = sample() while True: s = sample() print s if s and len(samples) < maxPoints: samples.append(s) else: break print samples This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,33 +2,38 @@ # original: https://gist.github.com/mbostock/22fd67be72552774736d # import pdb #import numpy import time import math import random random.seed(time.time()) def poissonDiscSampler(width, height, radius): k = 30 # maximum number of samples before rejection radius2 = radius * radius R = 3 * radius2 cellSize = radius * 0.70710678118654757 # numpy.sqrt(0.5) gridWidth = int(math.ceil(width / cellSize)) gridHeight = int(math.ceil(height / cellSize)) grid = [[None, None]] * (gridWidth * gridHeight) queue = [] queueSize = 0 sampleSize = 0 def poisson(): if not sampleSize: return sample(random.random() * width, random.random() * height) # Pick a random existing sample and remove it from the queue. while queueSize: i = math.floor(random.random() * queueSize) s = queue[i] # Make a new candidate between [radius, 2 * radius] from the existing sample. for j in range(0, k): a = 2 * math.pi * random.random() r = math.sqrt(random.random() * R + radius2) x = s[0] + r * math.cos(a) y = s[1] + r * math.sin(a) # Reject candidates that are outside the allowed extent, # or closer than 2 * radius to any existing sample. if 0 <= x and x < width and 0 <= y and y < height and far(x, y): @@ -37,12 +42,12 @@ def poisson(): queue.length = queueSize def far(x, y): i = math.floor(x / cellSize) j = math.floor(y / cellSize) i0 = max(i - 2, 0) j0 = max(j - 2, 0) i1 = min(i + 3, gridWidth) j1 = min(j + 3, gridHeight) for j in range(j0, j1): o = j * gridWidth for i in range(i0, i1): @@ -60,7 +65,7 @@ def sample(x, y): # pdb.set_trace() grid[gridWidth * int(math.floor(y / cellSize)) + int(math.floor(x / cellSize))] = s ++sampleSize ++queueSize return s @@ -69,16 +74,14 @@ def sample(x, y): # execute the sampling sample = poissonDiscSampler(width, height, cellSize) samples = [] while True: s = sample() print s if s and len(samples) < maxPoints: samples.append(s) else: break -
Aeon revised this gist
Oct 15, 2015 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -9,8 +9,8 @@ def poissonDiscSampler(width, height, radius): radius2 = radius * radius R = 3 * radius2 cellSize = radius * numpy.sqrt(0.5) gridWidth = int(numpy.ceil(width / cellSize)) gridHeight = int(numpy.ceil(height / cellSize)) grid = numpy.zeros((gridWidth * gridHeight, 2)) queue = [] queueSize = 0 @@ -60,7 +60,7 @@ def sample(x, y): # pdb.set_trace() grid[gridWidth * int(numpy.floor(y / cellSize)) + int(numpy.floor(x / cellSize))] = s ++sampleSize ++queueSize return s -
Aeon created this gist
Oct 14, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,84 @@ # translation to python for grasshopper # original: https://gist.github.com/mbostock/22fd67be72552774736d # import pdb import numpy def poissonDiscSampler(width, height, radius): k = 30 # maximum number of samples before rejection radius2 = radius * radius R = 3 * radius2 cellSize = radius * numpy.sqrt(0.5) gridWidth = numpy.ceil(width / cellSize) gridHeight = numpy.ceil(height / cellSize) grid = numpy.zeros((gridWidth * gridHeight, 2)) queue = [] queueSize = 0 sampleSize = 0 def poisson(): if not sampleSize: return sample(numpy.random.random() * width, numpy.random.random() * height) # Pick a random existing sample and remove it from the queue. while queueSize: i = numpy.floor(numpy.random.random() * queueSize) s = queue[i] # Make a new candidate between [radius, 2 * radius] from the existing sample. for j in range(0, k): a = 2 * numpy.pi * numpy.random.random() r = numpy.sqrt(numpy.random.random() * R + radius2) x = s[0] + r * numpy.cos(a) y = s[1] + r * numpy.sin(a) # Reject candidates that are outside the allowed extent, # or closer than 2 * radius to any existing sample. if 0 <= x and x < width and 0 <= y and y < height and far(x, y): return sample(x, y) queue[i] = queue[--queueSize] queue.length = queueSize def far(x, y): i = numpy.floor(x / cellSize) j = numpy.floor(y / cellSize) i0 = numpy.max(i - 2, 0) j0 = numpy.max(j - 2, 0) i1 = numpy.min(i + 3, gridWidth) j1 = numpy.min(j + 3, gridHeight) for j in range(j0, j1): o = j * gridWidth for i in range(i0, i1): s = grid[o + i]; if s: dx = s[0] - x dy = s[1] - y if dx * dx + dy * dy < radius2: return False return True def sample(x, y): s = [x, y] queue.append(s) # pdb.set_trace() grid[gridWidth * numpy.floor(y / cellSize) + numpy.floor(x / cellSize)] = s ++sampleSize ++queueSize return s return poisson # execute the sampling sample = poissonDiscSampler(48, 48, 5.45) samples = [] s = sample() while True: s = sample() print s if s: samples.append(s) else: break print samples