我有一个宽度和高度的平面(屏幕)(显示器分辨率,不是方形)。而且我想在那个平面上分配点(彼此相距相同)的点。
例如:
这有什么算法吗?
感谢您的时间!
编辑:彼此之间以及与平面边界相同的距离
EDIT2:我为我在飞机上模拟行为的对象组计算质心。
答案 0 :(得分:4)
取决于您想要的精度:
您可以通过Poisson磁盘采样获得随机正确的答案。具体地,泊松盘采样是随机采样,使得没有点比指定半径更近。这样的事物可以有效地(线性时间)以高维度实现 - 例如, :来自Robert Bridson的c ++代码:http://www.cs.ubc.ca/~rbridson/download/curlnoise.tar.gz实现他的论文http://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf
您可以真正优化积分的位置。这导致劳埃德算法和类似的优化程序:计算初始点集的Voronoi图,并将这些点移动到其Voronoi单元的质心。这也可以非常有效地完成,并且可以通过使用牛顿方法而不是Lloyd迭代来加速。 最终,如果您的域是正方形,您应该获得六边形网格(最小化上面的函数)。
如果您只需要近似结果,我建议第一种方法应该更快。
答案 1 :(得分:2)
如果你有很多分数,结果将看起来像一个六边形网格:
http://people.sc.fsu.edu/~jburkardt/m_src/hex_grid/hex_grid.html
否则会变得更复杂。一种非常好用(但可能是矫枉过正)的算法是进行物理模拟,其中点是彼此排斥的粒子。例如,查看在球体上执行相同操作的this video。
答案 2 :(得分:1)
编辑:不适用于物理排斥模拟。
将平面划分为矩形更容易处理。对于具有均匀边长的矩形,您不能准确地在中心有一个点。然而,等距的财产将它们很好地分散在屏幕上。
PHP中的简单程序来说明这一点:
<?php
$x_min = 1; $x_max = 1366;
$y_min = 1; $y_max = 768;
$x_div_count = 5;
$y_div_count = 5;
$x_div_len = (integer)round(($x_min + $x_max) / $x_div_count);
$y_div_len = (integer)round(($y_min + $y_max) / $y_div_count);
$x_mid_offset = (integer)round($x_div_len /2);
$y_mid_offset = (integer)round($y_div_len /2);
$x_offset = $x_mid_offset;
for ($idx =0; $idx < $x_div_count; $idx ++) {
$y_offset = $y_mid_offset;
for ($jdx =0; $jdx < $y_div_count; $jdx ++) {
$points_dist[] = array ('x' => $x_offset, 'y' => $y_offset);
$y_offset += $y_div_len;
}
$x_offset += $x_div_len;
}
var_dump(get_defined_vars());
?>
PS:如果你可以处理子像素渲染,那么使用浮点值。这些点往往是模糊但整体效果不错。
答案 3 :(得分:0)
首先,感谢大家的建议,这些建议帮助我更好地定义了我的问题并找到了解决问题的最佳方案。
现在我正在使用 Centroidal Voronoi tessellation ,根据维基百科:“在几何学中,质心Voronoi曲面细分(CVT)是一种特殊类型的Voronoi曲面细分或Voronoi图.Voronoi曲面细分当每个Voronoi单元的生成点也是它的平均值(质心)时,它被称为质心。它可以被视为与发生器的最佳分布相对应的最佳分区。“
它非常快,我正在使用的D3js库中实现了javascript。