在不规则区域内随机布点是指在给定的不规则形状区域内,以随机的方式均匀地分布点。这个过程通常用于模拟自然系统、创建地理信息系统(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);
}