Я создаю случайно сгенерированную среду для игры, которую разрабатываю. Я использую OpenGL
и кодирую Java
.
Я пытаюсь случайным образом разместить деревья в моем мире (чтобы создать лес), но я не хочу, чтобы модели перекрывались (что происходит, когда два дерева расположены слишком близко друг к другу). Вот картина того, о чем я говорю:
Я могу предоставить больше кода, если это необходимо, но вот основные фрагменты. Я храню свои объекты в ArrayList
с List<Entity> entities = new ArrayList<Entity>();
. Затем я добавляю в этот список, используя:
Random random = new Random();
for (int i = 0; i < 500; i++) {
entities.add(new Entity(tree, new Vector3f(random.nextFloat() * 800 - 400,
0, random.nextFloat() * -600), 0, random.nextFloat() * 360, 0, 3, 3, 3);
}
где каждый Entity
придерживается следующего синтаксиса:
new Entity(modelName, positionVector(x, y, z), rotX, rotY, rotZ, scaleX, scaleY, scaleZ);
rotX
вращение вдоль оси x, scaleX
масштаб в направлении x и т. д.
Вы можете видеть , что я помещаю эти деревья в случайном порядке с random.nextFloat()
для x
и z
позиций, и ограничивающая диапазон так , деревья будут появляться в нужном месте. Однако я хотел бы как-то контролировать эти позиции, чтобы, если он попытается разместить дерево слишком близко к ранее размещенному дереву, он пересчитает новую случайную позицию. Я думал, что у каждого дерева Entity
может быть другое поле, например treeTrunkGirth
, и если дерево находится на расстоянии между местоположением другого дерева и оно treeTrunkGirth
, то оно пересчитает новую позицию. Есть ли способ сделать это?
Я рад добавить больше фрагментов кода и деталей по мере необходимости.
treeTrunkGirth
вместо константы, чтобы определить минимальное расстояние для размещения дерева, если они должны варьироваться.Ответы:
А Пуассона-диск Отбор проб распределение позволит выбрать случайные точки минимальное расстояние друг от друга. Ваша ситуация похожа на этот вопрос , но поскольку ваши деревья не являются идеализированными точками, вам нужно изменить проверку расстояния следующим образом: расстояние между потенциальным новым деревом и существующим деревом должно быть меньше суммы их радиусов ,
Алгоритм Бридсона может эффективно решить проблему в O (n), но его может быть немного сложно настроить для переменных расстояний. Если ваши параметры невелики и / или вы предварительно рассчитываете свою местность, то решение с использованием грубой силы также может вам пригодиться. Вот некоторый пример кода, который грубо заставляет проблему, проверяя каждое потенциальное новое размещение дерева против всех ранее размещенных деревьев:
Со следующими параметрами:
Я был в состоянии произвольно разместить и визуализировать между 400-450 деревьями менее чем за секунду. Вот пример:
источник
tree.r + other tree.r
, 2 вместо math.sqrt, sqrt обычно медленнее, чем powMath.pow(x,2)
не обязательно лучше / отличается от использования,x*x
как описано здесь .