Soit S la zone de la scène. Soit A la zone du plus petit rectangle que nous voulons dessiner. Soit N = S/A
Une approche déterministe possible:
Lorsque vous dessinez un rectangle sur une scène vide, ce divise la scène en au plus 4 régions qui peuvent correspondre à votre prochain rectangle. Lorsque vous dessinez votre prochain rectangle, une ou deux régions sont divisées en au plus 4 sous-régions (chacune) pouvant contenir un rectangle, etc. Vous ne créerez jamais plus de N régions, où S est la zone de votre scène, et A est la zone de votre plus petit rectangle. Conserver une liste de régions (non triées), chacune représentée par ses quatre points d'angle, et chacune étiquetée avec sa surface, et utiliser la zone pondérée par zone reservoir sampling avec une taille de réservoir de 1 pour sélectionner une région avec probabilité proportionnelle à sa superficie dans au plus un passage dans la liste. Placez ensuite un rectangle à un emplacement aléatoire dans cette région. (Sélectionnez un point aléatoire dans la partie inférieure gauche de la région qui vous permet de dessiner un rectangle avec ce point comme son coin inférieur gauche sans toucher le mur supérieur ou droit.)
Si vous ne partez pas d'une étape vide, alors construisez simplement votre liste de régions disponibles dans O (N) (en retravaillant tous les rectangles existants sur une scène vierge dans n'importe quel ordre, par exemple) avant de rechercher votre premier point pour dessiner un nouveau rectangle.
Remarque: Vous pouvez modifier la taille de votre réservoir à k pour sélectionner les k rectangles suivants en une seule étape.
Note 2: Vous pouvez également stocker les régions disponibles dans un arbre avec chaque poids de bord égal à la somme des zones des régions dans le sous-arbre sur la zone de la scène. Ensuite, pour sélectionner une région dans O (logN), nous sélectionnons récursivement la racine avec la zone de probabilité de la région racine/S, ou chaque sous-arbre avec le poids du bord de probabilité/S. La mise à jour des poids sera gênante.
Durée: O (N)
Espace: O (N)
Une approche aléatoire possible:
Sélectionnez un point au hasard sur la scène. Si vous pouvez dessiner un ou plusieurs rectangles qui contiennent le point (pas seulement celui qui a le point dans son coin inférieur gauche), puis renvoyez un rectangle positionné aléatoirement qui contient le point. Il est possible de positionner le rectangle sans biais avec quelques subtilités, mais je vous le laisserai. Au pire, il y a un espace exactement assez grand pour notre rectangle et le reste de la scène est rempli. Donc, cette approche réussit avec une probabilité> 1/N, ou échoue avec la probabilité < 1-1/N. Répétez N fois. Nous échouons maintenant avec la probabilité < (1-1/N)^N < 1/e. Par échec, nous voulons dire qu'il y a un espace pour notre rectangle, mais nous ne l'avons pas trouvé. Par réussir, nous voulons dire que nous avons trouvé un espace s'il en existait un.Pour obtenir une probabilité raisonnable de succès, nous répétons Nlog (N) fois pour la probabilité 1/N d'échec, ou N² fois pour la probabilité 1/e^N d'échec. Résumé: Essayez des points aléatoires jusqu'à ce que nous trouvions un espace, en nous arrêtant après NlogN (ou N²) essais, auquel cas nous pouvons être sûrs qu'il n'y a pas d'espace.
Durée: O (NlogN) pour une forte probabilité de succès,
O (N²) pour très haute probabilité de succès
Espace: O (1)
Je n'ai pas de Karma pour commenter la réponse que vous avez sélectionnée, mais la version déterministe que vous avez choisie comme bonne réponse ne fonctionne pas car elle ne vous permet pas de placer des rectangles qui couvrent plusieurs régions. Vous devez d'abord appliquer la transformation mentionnée ci-dessus. –
Et le truc que j'ai mentionné dépend de la taille du nouveau rectangle que vous ajoutez, donc ce n'est pas comme si vous pouviez maintenir une structure de données hiérarchique qui l'incorpore déjà. Sa réponse est cassée. Relisez la mine. –