Voici quelque chose qui se trouve sur le dessus de ma tête sonne comme il pourrait le travail:
-
Créer un dictionnaire avec un double de la clé, et une liste de rectangle+valeurs booléennes, comme ceci:
Dictionnaire< Double, Liste< KeyValuePair< Rectangle, Boolean>>> rectangles;
Pour chaque rectangle dans votre ensemble, trouver le correspondant de la liste de l'x0 et x1 valeurs, et ajouter le rectangle à cette liste, avec une valeur booléenne true pour x0, et false pour x1. De cette façon, vous avez maintenant une liste complète de toutes les coordonnées x de chaque rectangle, soit entre le (vrai) ou des feuilles (faux) dans la direction x
Saisir toutes les clés de ce dictionnaire (toutes les différentes coordonnées x), de les trier et de les parcourir en boucle dans l'ordre, assurez-vous que vous pouvez obtenir à l'état actuel de la valeur x, et le prochain comme bien (vous en avez besoin à la fois). Cela vous donne des bandes individuelles de rectangles
- Maintenir un ensemble de rectangles, vous êtes actuellement à la recherche à, qui débute vide. Pour chaque valeur x vous parcourez au point 3, si le rectangle est inscrit avec une valeur true, l'ajouter à l'ensemble, sinon le supprimer.
- Pour une bande de trier les rectangles par leur abscisse
- Boucle à travers les rectangles dans la bande de gaza, le comptage de chevauchement des distances (pas clair pour moi encore comment le faire efficacement)
- Calculer la largeur de bande de fois la hauteur de chevauchement des distances pour obtenir des zones
Exemple, 5 rectangles, dessiner sur le dessus les uns des autres, de a à e:
aaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbb
aaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbb
aaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbb
aaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbb
aaaaaaaadddddddddddddddddddddddddddddbbbbbb
aaaaaaaadddddddddddddddddddddddddddddbbbbbb
ddddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddd
ddddddddddddddeeeeeeeeeeeeeeeeee
ddddddddddddddeeeeeeeeeeeeeeeeee
ddddddddddddddeeeeeeeeeeeeeeeeee
ccccccccddddddddddddddeeeeeeeeeeeeeeeeee
ccccccccddddddddddddddeeeeeeeeeeeeeeeeee
cccccccccccc eeeeeeeeeeeeeeeeee
cccccccccccc eeeeeeeeeeeeeeeeee
cccccccccccc
cccccccccccc
Voici la liste des coordonnées x:
v v v v v v v v v
|aaaaaaa|aa|aaaa | bbbbbbbbbb|bb|bbb
|aaaaaaa|aa|aaaa | bbbbbbbbbb|bb|bbb
|aaaaaaa|aa|aaaa | bbbbbbbbbb|bb|bbb
|aaaaaaa|aa|aaaa | bbbbbbbbbb|bb|bbb
|aaaaaaaddd|dddddddddd|ddddddddddddddbb|bbb
|aaaaaaaddd|dddddddddd|ddddddddddddddbb|bbb
| ddd|dddddddddd|dddddddddddddd |
| ddd|dddddddddd|dddddddddddddd |
| ddd|ddddddddddeeeeeeeeeeeeeeeeee
| ddd|ddddddddddeeeeeeeeeeeeeeeeee
| ddd|ddddddddddeeeeeeeeeeeeeeeeee
ccccccccddd|ddddddddddeeeeeeeeeeeeeeeeee
ccccccccddd|ddddddddddeeeeeeeeeeeeeeeeee
cccccccccccc eeeeeeeeeeeeeeeeee
cccccccccccc eeeeeeeeeeeeeeeeee
cccccccccccc
cccccccccccc
La liste serait (où chaque v est simplement une coordonnée de départ à 0 et allant jusqu'à):
0: +a, +c
1: +d
2: -c
3: -a
4: +e
5: +b
6: -d
7: -e
8: -b
Chaque bande serait donc (rectangles classées de haut en bas):
0-1: a, c
1-2: a, d, c
2-3: a, d
3-4: d
4-5: d, e
5-6: b, d, e
6-7: b, e
7-8: b
pour chaque tranche, le chevauchement serait:
0-1: none
1-2: a/d, d/c
2-3: a/d
3-4: none
4-5: d/e
5-6: b/d, d/e
6-7: none
7-8: none
J'imagine qu'une variation de la tri + enter/leave algorithme pour le haut-en bas à vérifier serait faisable ainsi:
- trier les rectangles nous sommes en train d'analyser dans la bande de gaza, du haut vers le bas, pour les rectangles avec le même haut-de coordonner, de les trier en bas de coordonnées ainsi
- parcourir les coordonnées y, et quand vous entrez dans un rectangle, l'ajouter à l'ensemble, lorsque vous quittez un rectangle, le retirer de l'ensemble
- chaque fois que le jeu a plus d'un rectangle, vous avez chevauchement (et si vous veillez à ajouter/supprimer tous les rectangles qui ont le même haut/bas de coordonnées que vous êtes en train de regarder, qui se chevauchent les rectangles ne serait pas un problème
Pour le 1-2 bande ci-dessus, vous itérer comme ceci:
0. empty set, zero sum
1. enter a, add a to set (1 rectangle in set)
2. enter d, add d to set (>1 rectangles in set = overlap, store this y-coordinate)
3. leave a, remove a from set (now back from >1 rectangles in set, add to sum: y - stored_y
4. enter c, add c to set (>1 rectangles in set = overlap, store this y-coordinate)
5. leave d, remove d from set (now back from >1 rectangles in set, add to sum: y - stored_y)
6. multiply sum with width of strip to get overlapping areas
Vous ne devez conserver une réelle définie ici non plus, juste le nombre de rectangles, vous êtes à l'intérieur, chaque fois que cela est de 1 à 2, stockez-le dans y, et chaque fois qu'il passe de 2 à 1, calculer le courant y stockée y, et la somme de cette différence.
Espérons que cela était compréhensible, et comme je l'ai dit, c'est hors de ma tête, pas encore testé en aucune façon.