Je crée un environnement généré aléatoirement pour un jeu que je développe. J'utilise OpenGL
et je code Java
.
J'essaie de placer au hasard des arbres dans mon monde (pour créer une forêt), mais je ne veux pas que les modèles se chevauchent (ce qui se produit lorsque deux arbres sont placés trop près l'un de l'autre). Voici une photo de ce dont je parle:
Je peux fournir plus de code si nécessaire, mais voici les extraits essentiels. Je stocke mes objets dans un ArrayList
avec List<Entity> entities = new ArrayList<Entity>();
. J'ajoute ensuite à cette liste en utilisant:
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);
}
où chacun Entity
suit la syntaxe suivante:
new Entity(modelName, positionVector(x, y, z), rotX, rotY, rotZ, scaleX, scaleY, scaleZ);
rotX
est la rotation le long de l'axe x, et scaleX
est l'échelle dans la direction x, etc.
Vous pouvez voir que je suis placer ces arbres au hasard avec random.nextFloat()
les x
et z
positions, et délimitant la plage de sorte que les arbres apparaissent à l'endroit désiré. Cependant, je voudrais en quelque sorte contrôler ces positions, de sorte que s'il essaie de placer un arbre trop près d'un arbre précédemment placé, il recalculera une nouvelle position aléatoire. Je pensais que chaque arbre Entity
pourrait avoir un autre champ, tel que treeTrunkGirth
, et si un arbre est placé à la distance entre l'emplacement d'un autre arbre et le sien treeTrunkGirth
, il recalculera une nouvelle position. Existe-t-il un moyen d'y parvenir?
Je suis heureux d'ajouter plus d'extraits de code et de détails si nécessaire.
treeTrunkGirth
au lieu d'une constante pour déterminer la distance minimale pour placer un arbre s'ils doivent varier.Réponses:
Une distribution d' échantillonnage Poisson-Disk vous permettra de sélectionner des points aléatoires à une distance minimale. Votre situation est similaire à cette question , mais comme vos arbres ne sont pas des points idéalisés, vous devrez modifier la vérification de la distance comme suit: la distance entre un nouvel arbre potentiel et un arbre existant doit être inférieure à la somme de leurs rayons .
L'algorithme de Bridson peut résoudre efficacement le problème dans O (n), mais il peut être un peu fastidieux de le régler pour des distances variables. Si vos paramètres sont faibles et / ou si vous précalculez votre terrain, une solution de force brute peut également vous être utile. Voici un exemple de code qui force le problème en vérifiant chaque nouveau placement d'arbre potentiel par rapport à tous les arbres placés précédemment:
Avec les paramètres suivants:
J'ai pu placer et rendre au hasard entre 400 et 450 arbres en moins d'une seconde. Voici un exemple:
la source
tree.r + other tree.r
, 2, au lieu de math.sqrt, sqrt est généralement plus lent que powMath.pow(x,2)
n'est pas nécessairement meilleure / différente que l'utilisationx*x
comme indiqué ici .