Estoy creando un entorno generado aleatoriamente para un juego que estoy desarrollando. Estoy usando OpenGL
y codificando Java
.
Estoy tratando de colocar árboles al azar en mi mundo (para crear un bosque), pero no quiero que los modelos se superpongan (lo que sucede cuando dos árboles se colocan demasiado cerca el uno del otro). Aquí hay una foto de lo que estoy hablando:
Puedo proporcionar más código si es necesario, pero aquí están los fragmentos esenciales. Estoy almacenando mis objetos en un ArrayList
con List<Entity> entities = new ArrayList<Entity>();
. Luego estoy agregando a esa 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);
}
donde cada uno Entity
sigue la siguiente sintaxis:
new Entity(modelName, positionVector(x, y, z), rotX, rotY, rotZ, scaleX, scaleY, scaleZ);
rotX
es la rotación a lo largo del eje xy scaleX
es la escala en la dirección x, etc.
Se puede ver que estoy colocando estos árboles al azar con random.nextFloat()
los x
y las z
posiciones, y que limita la gama de modo que los árboles van a aparecer en la ubicación deseada. Sin embargo, me gustaría controlar de alguna manera estas posiciones, de modo que si intenta colocar un árbol demasiado cerca de un árbol colocado previamente, volverá a calcular una nueva posición aleatoria. Estaba pensando que cada árbol Entity
podría tener otro campo, como treeTrunkGirth
, y si un árbol se coloca en la distancia entre la ubicación de otro árbol y es treeTrunkGirth
, entonces volverá a calcular una nueva posición. ¿Hay alguna manera de lograr esto?
Me complace agregar más fragmentos de código y detalles según sea necesario.
treeTrunkGirth
lugar de una constante para determinar la distancia mínima para colocar un árbol si necesita variar.Respuestas:
Una distribución de muestreo de Poisson-Disk le permitirá seleccionar puntos aleatorios a una distancia mínima de distancia. Su situación es similar a esta pregunta , pero dado que sus árboles no son puntos idealizados, deberá cambiar la distancia comprobando de la siguiente manera: la distancia entre un árbol nuevo potencial y un árbol existente, debe ser menor que la suma de sus radios .
El algoritmo de Bridson puede resolver eficientemente el problema en O (n), pero puede ser un poco complicado ajustarlo para distancias variables. Si sus parámetros son bajos y / o está precalculando su terreno, una solución de fuerza bruta también puede servirle. Aquí hay un código de muestra que el bruto fuerza el problema al verificar cada posible colocación de nuevos árboles contra todos los árboles colocados anteriormente:
Con los siguientes parámetros:
Pude colocar aleatoriamente y renderizar entre 400-450 árboles en menos de un segundo. Aquí hay un ejemplo:
fuente
tree.r + other tree.r
, 2, en lugar de math.sqrt, sqrt suele ser más lento que powMath.pow(x,2)
no es necesariamente mejor / diferente que usarx*x
como se discutió aquí .