Выборка по диску Пуассона – это популярный метод, используемый для создания равномерного и визуально приятного распределения точек. В этой статье мы углубимся в различные методы реализации дискретизации пуассоновского диска в Python. Мы предоставим примеры кода для демонстрации каждого метода, а также обсудим их преимущества и варианты использования. Давайте начнем!
- Базовая реализация с использованием алгоритма Бридсона.
Алгоритм Бридсона — широко используемый метод генерации выборок диска Пуассона. Это гарантирует, что сгенерированные точки находятся на минимальном расстоянии друг от друга, что приводит к хорошо распределенному распределению.
import numpy as np
from scipy.spatial import cKDTree
def generate_poisson_disc_samples(width, height, radius, k=30, max_attempts=5):
cell_size = radius / np.sqrt(2)
grid_width = int(np.ceil(width / cell_size))
grid_height = int(np.ceil(height / cell_size))
grid = np.empty((grid_width, grid_height), dtype=np.int32)
points = []
active = []
def get_random_point():
return [np.random.uniform(0, width), np.random.uniform(0, height)]
def get_grid_coordinates(point):
return int(point[0] // cell_size), int(point[1] // cell_size)
def is_valid(point):
x, y = get_grid_coordinates(point)
x_min, y_min = max(0, x - 2), max(0, y - 2)
x_max, y_max = min(grid_width, x + 3), min(grid_height, y + 3)
for i in range(x_min, x_max):
for j in range(y_min, y_max):
if grid[i, j] != -1:
dx = point[0] - points[grid[i, j]][0]
dy = point[1] - points[grid[i, j]][1]
if dx * dx + dy * dy < radius * radius:
return False
return True
def add_point(point):
index = len(points)
points.append(point)
active.append(index)
x, y = get_grid_coordinates(point)
grid[x, y] = index
def generate_samples():
if len(points) == 0:
add_point(get_random_point())
while active:
index = np.random.choice(active)
current_point = points[index]
success = False
for _ in range(max_attempts):
angle = 2 * np.pi * np.random.random()
direction = [np.cos(angle), np.sin(angle)]
distance = radius + np.random.uniform(radius, 2 * radius)
new_point = [current_point[0] + direction[0] * distance,
current_point[1] + direction[1] * distance]
if (0 <= new_point[0] < width and 0 <= new_point[1] < height and
is_valid(new_point)):
add_point(new_point)
success = True
break
if not success:
active.remove(index)
return np.array(points)
return generate_samples()
- Использование matplotlib для визуализации:
Чтобы визуализировать сгенерированные образцы дисков Пуассона, вы можете использовать библиотеку Matplotlib. Вот пример построения точек:
import matplotlib.pyplot as plt
def plot_poisson_disc_samples(points):
plt.scatter(points[:, 0], points[:, 1], color='blue', s=5)
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Poisson Disc Sampling')
plt.show()
# Usage:
width = 500
height = 500
radius = 10
samples = generate_poisson_disc_samples(width, height, radius)
plot_poisson_disc_samples(samples)
- Улучшение производительности с помощью cKDTree Scipy:
Если вам нужно эффективно запрашивать соседей или выполнять другие пространственные операции над сгенерированными выборками, вы можете использовать структуру данных Scipy cKDTree. Вот пример того, как построить cKDTree из сгенерированных образцов:
def build_kdtree(points):
kdtree = cKDTree(points)
return kdtree
# Usage:
kdtree = build_kdtree(samples)
Дисковая выборка Пуассона — ценный метод создания хорошо распределенных распределений точек в различных приложениях. В этой статье мы рассмотрели различные методы реализации сэмплирования диска Пуассона в Python. Мы рассмотрели базовую реализацию с использованием алгоритма Бридсона, визуализацию с помощью Matplotlib и повышение производительности с помощью cKDTree от Scipy. Включив эти методы в свои проекты, вы сможете добиться эффективного и визуально приятного распределения точек.