返回

在不规则区域内随机布点

在不规则区域内随机布点是指在给定的不规则形状区域内,以随机的方式均匀地分布点。这个过程通常用于模拟自然系统、创建地理信息系统(GIS)中的样本数据或进行计算机图形学中的建模。

计算过程

  • 首先计算最大边界盒
  • 在最大边界盒内生成随机点
  • 检查随机生成的点是否在多边形内部
  • 计算点到中心点的距离,并根据正态分布转换为概率
  • 根据概率随机舍弃点

export function generateRandomPointsInPolygon(polygon, numPoints, center) {
  numPoints = Math.min(numPoints, 300) //设置渲染上限
  const [centerX, centerY] = center || []

  // 计算最大边界盒
  let minX = Number.MAX_VALUE;
  let minY = Number.MAX_VALUE;
  let maxX = Number.MIN_VALUE;
  let maxY = Number.MIN_VALUE;
  for (const point of polygon) {
    minX = Math.min(minX, point[0]);
    minY = Math.min(minY, point[1]);
    maxX = Math.max(maxX, point[0]);
    maxY = Math.max(maxY, point[1]);
  }

  const points = [];
  while (points.length < numPoints) {
    // 在最大边界盒内生成随机点
    const x = Math.random() * (maxX - minX) + minX;
    const y = Math.random() * (maxY - minY) + minY;

    // 检查是否在多边形内部
    if (isPointInPolygon([x, y], polygon)) {
      // 计算点到中心点的距离,并转换为概率
      const distance = Math.sqrt((centerX - x) ** 2 + (centerY - y) ** 2);
      const probability = normalDistribution(distance, numPoints <= 20 ? 1 : 6);

      // 根据概率决定保留或删除点
      if (Math.random() < probability) {
        points.push([x, y]);
      }
    }
  }

  return points;
}

function isPointInPolygon(point, polygon) {
  const x = point[0];
  const y = point[1];
  let isInside = false;

  for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
    const xi = polygon[i][0];
    const yi = polygon[i][1];
    const xj = polygon[j][0];
    const yj = polygon[j][1];

    const intersect = ((yi > y) != (yj > y)) &&
        (x < ((xj - xi) * (y - yi)) / (yj - yi) + xi);

    if (intersect) {
      isInside = !isInside;
    }
  }

  return isInside;
}

// 正态分布
function normalDistribution(distance , stdDev = 5) {
  const mean = 0;  // 均值
  return 1 / (Math.sqrt(2 * Math.PI * stdDev)) * Math.exp(-0.5 * ((distance - mean) / stdDev) ** 2);
}

效果展示

截屏2023-11-0117.18.21