返回

Poisson-Disc 算法详解:随机均匀采样和动画演示

前端

Poisson-Disc 算法原理

Poisson-Disc 算法的基本思想是通过迭代的方式来生成点集。算法首先在一个给定的区域内随机生成一个点,然后以该点为中心,以一定的半径画一个圆。在该圆内,算法继续随机生成点,但这些点与圆内的其他点以及圆心点的距离都必须大于或等于给定的半径。如果生成的点满足条件,则将其添加到点集中;否则,则将其丢弃。

算法不断重复上述过程,直到点集满足一定的分布准则。Poisson-Disc 算法生成的点集具有以下几个特点:

  • 随机性: 生成的点集是随机的,没有明显的规律。
  • 均匀性: 生成的点集在给定的区域内均匀分布,没有明显的聚集或稀疏区域。
  • 最短距离: 生成的点集中的任意两个点之间的距离都大于或等于给定的半径。

Poisson-Disc 算法实现

Poisson-Disc 算法的实现相对简单,可以使用多种编程语言实现。下面以 Python 为例,给出 Poisson-Disc 算法的实现代码:

import random
import math

def poisson_disc(width, height, radius, num_points):
    """
    生成一组 Poisson-Disc 点集。

    参数:
        width:区域宽度。
        height:区域高度。
        radius:点的最小距离。
        num_points:要生成的点的数量。

    返回:
        一个列表,包含了生成的点集。
    """

    # 初始化点集
    points = []

    # 随机生成第一个点
    x = random.uniform(0, width)
    y = random.uniform(0, height)
    points.append((x, y))

    # 迭代生成点集
    while len(points) < num_points:
        # 随机生成一个点
        x = random.uniform(0, width)
        y = random.uniform(0, height)

        # 检查该点是否满足条件
        valid = True
        for point in points:
            dx = x - point[0]
            dy = y - point[1]
            distance = math.sqrt(dx**2 + dy** 2)
            if distance < radius:
                valid = False
                break

        # 如果满足条件,则将其添加到点集中
        if valid:
            points.append((x, y))

    # 返回点集
    return points

Poisson-Disc 算法动画演示

为了更好地理解 Poisson-Disc 算法的原理和实现过程,可以制作一个动画演示。动画演示可以直观地展示算法是如何迭代生成点集的,以及生成的点集具有什么样的分布特征。

以下是一个使用 Python 和 matplotlib 库制作的 Poisson-Disc 算法动画演示:

import random
import math
import matplotlib.pyplot as plt

def poisson_disc(width, height, radius, num_points):
    """
    生成一组 Poisson-Disc 点集。

    参数:
        width:区域宽度。
        height:区域高度。
        radius:点的最小距离。
        num_points:要生成的点的数量。

    返回:
        一个列表,包含了生成的点集。
    """

    # 初始化点集
    points = []

    # 随机生成第一个点
    x = random.uniform(0, width)
    y = random.uniform(0, height)
    points.append((x, y))

    # 迭代生成点集
    while len(points) < num_points:
        # 随机生成一个点
        x = random.uniform(0, width)
        y = random.uniform(0, height)

        # 检查该点是否满足条件
        valid = True
        for point in points:
            dx = x - point[0]
            dy = y - point[1]
            distance = math.sqrt(dx**2 + dy** 2)
            if distance < radius:
                valid = False
                break

        # 如果满足条件,则将其添加到点集中
        if valid:
            points.append((x, y))

        # 绘制点集
        plt.scatter(x, y, color='blue', marker='o')

        # 暂停一下,以便用户可以看到动画效果
        plt.pause(0.01)

    # 返回点集
    return points

# 设置区域大小和点的数量
width = 500
height = 500
num_points = 1000

# 生成点集
points = poisson_disc(width, height, 10, num_points)

# 显示点集
plt.show()

运行该代码,可以看到 Poisson-Disc 算法是如何迭代生成点集的,以及生成的点集具有什么样的分布特征。