Estou criando um ambiente gerado aleatoriamente para um jogo que estou desenvolvendo. Estou usando OpenGL
e codificando Java
.
Estou tentando colocar aleatoriamente árvores no meu mundo (para criar uma floresta), mas não quero que os modelos se sobreponham (o que acontece quando duas árvores são colocadas muito próximas uma da outra). Aqui está uma imagem do que estou falando:
Posso fornecer mais código, se necessário, mas aqui estão os trechos essenciais. Estou armazenando meus objetos em um ArrayList
com List<Entity> entities = new ArrayList<Entity>();
. Estou adicionando a essa lista usando:
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);
}
em que cada um Entity
segue a seguinte sintaxe:
new Entity(modelName, positionVector(x, y, z), rotX, rotY, rotZ, scaleX, scaleY, scaleZ);
rotX
é a rotação ao longo do eixo x, e scaleX
é a escala na direção x, etc.
Você pode ver que eu estou colocando estas árvores aleatoriamente com random.nextFloat()
os x
e z
posições, e delimita o intervalo para as árvores aparecerá no local desejado. No entanto, eu gostaria de controlar de alguma forma essas posições, para que, se tentar colocar uma árvore muito perto de uma árvore anteriormente colocada, recalcule uma nova posição aleatória. Eu estava pensando que cada árvore Entity
poderia ter outro campo, como treeTrunkGirth
, e se uma árvore for colocada à distância entre a localização de outra árvore e ela treeTrunkGirth
, ela recalculará uma nova posição. Existe uma maneira de conseguir isso?
É um prazer adicionar mais trechos de código e detalhes conforme necessário.
treeTrunkGirth
vez de uma constante para determinar a distância mínima para colocar uma árvore, se ela precisar variar.Respostas:
Uma distribuição de amostragem Poisson-Disk permitirá que você selecione pontos aleatórios a uma distância mínima. Sua situação é semelhante a esta pergunta , mas como suas árvores não são pontos idealizados, você precisará alterar a verificação da distância da seguinte maneira: a distância entre uma nova árvore em potencial e uma árvore existente deve ser menor que a soma dos raios .
O algoritmo de Bridson pode resolver com eficiência o problema em O (n), mas pode ser um pouco complicado ajustá-lo para distâncias variáveis. Se seus parâmetros são baixos e / ou você está pré-computando seu terreno, uma solução de força bruta também pode atendê-lo. Aqui está um código de exemplo que força bruta o problema, verificando cada nova colocação potencial de árvore em relação a todas as árvores colocadas anteriormente:
Com os seguintes parâmetros:
Consegui colocar e renderizar aleatoriamente entre 400-450 árvores em menos de um segundo. Aqui está um exemplo:
fonte
tree.r + other tree.r
, 2, em vez de Math.sqrt, sqrt é geralmente mais lento do que powMath.pow(x,2)
não é necessariamente melhor / diferente do que usarx*x
como discutido aqui .