【发布时间】:2015-05-19 17:24:12
【问题描述】:
我正在尝试改进我的方法,即从中心点在网格表面上以相等的足迹布置数千个形状的位置(它具有更有机的外观)。网格表面意味着邻居之间的间距相等,但我不想通过选择随机的 x 和 y 坐标(或在这种情况下为 x 和 z,因为我在 3 维中工作)来创建类似拼凑的图案)。我现在拥有的东西可以工作,但是当我从 2,000 个对象开始向上移动时,速度非常慢。有没有更快的方法?就像我说的那样,我正在避免拼凑效果,以及均匀的圆形传播。现在的分布非常像城市和完美,但太慢了。
我一直在评论这个函数,希望它能彻底解释一切:
ArrayList buildingCoords; // stores the co-ordinates of occupied spaces
int w = 50 // Footprint dimensions. Width and depth.
PVector generateNewBuildingPosition(PVector coord) {
float sW = 30; // gap between shapes
// Starting at a coordinate of 0,0 if this is our 1st go
// (PVector coord initially feeds 0,0)
// or the last coordinate that was already taken
// (this loops with the last coordinate if it fails)
// we check one of the four spaces next to us with
// the roll of a dice (in a way...)
float randomX = random(0,15);
float randomZ = random(0,15);
if (randomX >= 10) {
randomX = w + sW;
} else if (randomX >= 5) {
randomX = (w + sW) * -1;
} else {
randomX = 0;
}
if (randomZ >= 10) {
randomZ = w + sW;
} else if (randomX >= 5) {
randomZ = (w + sW) * -1;
} else {
randomZ = 0;
}
// We've picked our direction.
// We have a PVector that acts as a marker for where we're
// placing. Adding or subtracting the movement of each
// attempt, one at a time, means the shapes spreads out
// more organically from the centre rather than trying
// to distribute each shape as a random patch.
PVector newDirection = new PVector(randomX, 0, randomZ);
coord.add(newDirection);
// Our marker moves to the new spot, we check if it exists.
// If it doesn't, we confirm it as this shape's anchor spot.
// If it does, we loop this function again, feeding it where our
// marker is.
if(buildingCoords.contains(coord)) {
generateNewBuildingPosition(coord);
} else {
// add this PVector to the arrayList
buildingCoords.add(coord);
}
// Return the coordinates that just succeeded.
return coord;
}
【问题讨论】:
-
抱歉,我错过了有一个外部变量。我现在已经将它包含在原始文件中,但它是每个形状的足迹的宽度和深度。
-
@Micheal Hobbs:这只是检查 ArrayList 是否包含某个对象的默认代码。列表越大,速度越慢。
-
有不同的方法可以做到这一点。如果您希望您的结构从中心向外扩展,您可以使用边界形状(边界框最简单),但实际上它归结为保留 non-taken 空间的列表,每次占用空间时都会更新。正如我所提到的,为了防止该列表在内存中爆炸,您可以动态增长它,这意味着您从一些空白空间开始,并在您占用空间时添加新空间(例如某个半径内的邻居)。
-
这里还有一个可能会有所帮助的想法:一种类似生活游戏的设置,根据网格位置的邻居数量来选择位置。零邻居不好,邻居太多也不好,我们总是试图在中间挑选一些东西。您可以跟踪至少有一个邻居的每个空位置(为那些有 1 个邻居、有 2 个邻居等的人保留一个单独的列表可能会更好),当您放置一个新元素时更新这个列表。跨度>
-
通过调整与
n邻居选择某物的概率权重,您可以调整生成的形状:如果您的“租户”非常隐居并且更喜欢一个邻居而不是其他所有事物,您将得到一个类似蕨类植物的结构,如果他们更喜欢更多的邻居,你更有可能得到一个斑点。您甚至可以在生成期间调整权重(当村庄较小时,房屋往往会挤在一起,并开始分散到一定大小以上)。
标签: java random processing