Изучение методов выборки дисков Пуассона в Python: подробное руководство

Выборка по диску Пуассона – это популярный метод, используемый для создания равномерного и визуально приятного распределения точек. В этой статье мы углубимся в различные методы реализации дискретизации пуассоновского диска в Python. Мы предоставим примеры кода для демонстрации каждого метода, а также обсудим их преимущества и варианты использования. Давайте начнем!

  1. Базовая реализация с использованием алгоритма Бридсона.
    Алгоритм Бридсона — широко используемый метод генерации выборок диска Пуассона. Это гарантирует, что сгенерированные точки находятся на минимальном расстоянии друг от друга, что приводит к хорошо распределенному распределению.
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()
  1. Использование 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)
  1. Улучшение производительности с помощью cKDTree Scipy:
    Если вам нужно эффективно запрашивать соседей или выполнять другие пространственные операции над сгенерированными выборками, вы можете использовать структуру данных Scipy cKDTree. Вот пример того, как построить cKDTree из сгенерированных образцов:
def build_kdtree(points):
    kdtree = cKDTree(points)
    return kdtree
# Usage:
kdtree = build_kdtree(samples)

Дисковая выборка Пуассона — ценный метод создания хорошо распределенных распределений точек в различных приложениях. В этой статье мы рассмотрели различные методы реализации сэмплирования диска Пуассона в Python. Мы рассмотрели базовую реализацию с использованием алгоритма Бридсона, визуализацию с помощью Matplotlib и повышение производительности с помощью cKDTree от Scipy. Включив эти методы в свои проекты, вы сможете добиться эффективного и визуально приятного распределения точек.