Loading AI tools
structure de données géométrique basée sur la subdivision de carrée en quatre carrées plus petits De Wikipédia, l'encyclopédie libre
Un quadtree ou arbre quaternaire (arbre Q) est une structure de données de type arbre dans laquelle chaque nœud a quatre fils. Les quadtrees sont le plus souvent utilisés pour partitionner un espace bidimensionnel en le subdivisant récursivement en quatre nœuds.
Les quadtrees sont l'analogie bidimensionnelle des octrees. Le nom est formé à partir de quad et de tree (arbre, en anglais). Chaque nœud d'un quadtree subdivise l'espace qu'il représente en quatre sous-espaces.
Les quadtrees peuvent être classés selon le type de données qu'ils représentent, incluant régions, points, lignes et courbes. Voici quelques types communs de quadtrees :
Le quadtree «région» représente une partition de l'espace en deux dimensions en décomposant la région en quatre quadrants égaux, puis chaque quadrant en quatre sous-quadrants, et ainsi de suite, avec chaque «nœud terminal» comprenant des données correspondant à une sous-région spécifique. Chaque nœud de l'arbre a exactement : soit quatre enfants, soit aucun (cas d'un nœud terminal). Le quadtree «région» est un type d'arbre préfixe.
Un quadtree «région» ayant une profondeur n peut être utilisé pour représenter une image de 2n × 2n pixels, où la valeur de chaque pixel est 0 ou 1. Le nœud parent représente l'image tout entière. Si les pixels d'une région donnée ne sont pas tous à 0 ou tous à 1, celle-ci est subdivisée. Dans une telle représentation d'une image, chaque nœud terminal représente un bloc de pixels qui sont tous à 0 ou tous à 1.
Un quadtree «région» peut également être utilisé comme une représentation de résolution variable d'un champ de données. Par exemple, les températures d'une zone peuvent être stockées dans un quadtree, dans lequel chaque nœud terminal stocke la température moyenne de la sous-région qu'il représente.
Si un quadtree «région» est utilisé pour représenter un ensemble de points (par exemple, les latitudes et longitudes d'un groupe de villes), les régions sont subdivisées jusqu'à ce que chaque nœud terminal ne contienne plus qu'un point.
Le quadtree «point» est une adaptation d'un arbre binaire, utilisé pour représenter une donnée «point» à deux dimensions (par exemple, une coordonnée géographique). Il partage les caractéristiques de tous les quadtrees tout en étant un véritable arbre, puisque le centre d'une subdivision est toujours sur un point. La forme de l'arbre dépend de l'ordre dans lequel les données sont traitées. Une telle représentation est souvent très efficace en comparaison des données «points» ordonnées bidimensionnelles, opérant habituellement en un temps O(log n).
Le nœud d'un quadtree «point» est similaire à celui d'un arbre binaire, avec cette grosse différence : le premier possède quatre pointeurs (un pour chaque quadrant), tandis que le second n'en possède que deux («gauche» et «droite»). Une autre différence, une clé est habituellement décomposée en deux parties, se référant aux coordonnées x et y. Un nœud contient donc les informations suivantes :
Les quadtrees «bord» sont spécifiquement utilisés pour stocker des lignes, plutôt que des points. Les courbes sont approximées en subdivisant les cellules jusqu'à une très fine résolution. Ceci peut résulter en des arbres extrêmement déséquilibrés, annulant ainsi l'intérêt de l'indexation.
Le quadtree «carte polygonale» (ou CP-quadtree) est une variante d'un quadtree, utilisée pour stocker des collections de polygones potentiellement dégénérés (c'est-à-dire, ayant des sommets ou des bords isolés)[1]. Il existe trois classes principales de CP-quadtrees, variant en fonction de quelles informations ils stockent à l'intérieur de chaque «nœud noir». Les CP3-quadtrees peuvent stocker n'importe quelle quantité de «bords non-coupants» et au plus un point. Les CP2-quadtrees sont les mêmes que les CP3-quadtrees, excepté que tous les bords doivent partager le même point final. Pour finir, les CP1-quadtrees sont similaires aux CP2-quadtrees, mais les «nœuds noirs» peuvent contenir un point et ses bords ou juste un ensemble de bords partageant un point (mais vous ne pouvez pas avoir un point et un ensemble de bords qui ne contiennent pas ce point).
Le pseudo-code suivant montre une implémentation possible d'un quadtree gérant uniquement les points. Il existe d'autres approches valables.
Il est supposé que les structures suivantes sont utilisées.
// Objet de coordonnées simples pour représenter des points et des vecteurs struct XY { float x; float y; function __construct(float _x, float _y) {...} } // Zone de délimitation alignée sur l'axe, représentée par sa demi-dimension et son centre struct AABB { XY center; XY halfDimension; function __construct(XY center, XY halfDimension) {...} function containsPoint(XY p) {...} function intersectsAABB(AABB other) {...} }
Cette classe représente à la fois un quadtree et son nœud parent.
class QuadTree { // Constante arbitraire indiquant combien d'éléments peuvent être stockés dans ce nœud de quadtree constant int QT_NODE_CAPACITY = 4; // Zone de délimitation alignée sur l'axe (représentée par sa demi-dimension et son centre) // représentant les limites de ce quadtree AABB boundary; // Points de ce nœeud de quadtree Array of XY [size = QT_NODE_CAPACITY] points; // Enfants QuadTree* northWest; QuadTree* northEast; QuadTree* southWest; QuadTree* southEast; // Méthodes function __construct(AABB _boundary) {...} function insert(XY p) {...} function subdivide() {...} // créer quatre enfants permettant de diviser ce quadrant en quatre quadrants d'égales dimensions function queryRange(AABB range) {...} }
La méthode suivante permet d'insérer un point dans le quadrant approprié d'un quadtree, réalisant une partition si nécessaire.
class QuadTree { ... // Insérer un point dans le QuadTree function insert(XY p) { // Ignorer les objets qui n'appartiennent pas à ce quadtree if (!boundary.containsPoint(p)) return false; // l'objet ne doit pas être ajouté // S'il reste de la place dans ce quadtree, y ajouter l'objet if (points.size < QT_NODE_CAPACITY) { points.append(p); return true; } // Sinon, subdiviser le quadtree, puis ajouter le point au nœud qui l'acceptera if (northWest == null) subdivide(); if (northWest→insert(p)) return true; if (northEast→insert(p)) return true; if (southWest→insert(p)) return true; if (southEast→insert(p)) return true; // Sinon, le point ne peut être inséré, pour une raison inconnue (cela ne devrait jamais arriver) return false; } }
La méthode suivante permet de trouver tous les points à l'intérieur d'une «zone de recherche».
class QuadTree { ... // Trouver tous les points apparaissant à l'intérieur d'une «zone de recherche» function queryRange(AABB range) { // Préparer le tableau de résultats Array of XY pointsInRange; // Tout interrompre si la «zone de recherche» n'intersecte pas ce quadrant if (!boundary.intersectsAABB(range)) return pointsInRange; // liste vide // Vérifier les objets à ce niveau de quadrant for (int p := 0; p < points.size; p++) { if (range.containsPoint(points[p])) pointsInRange.append(points[p]); } // Terminer ici, s'il n'y a pas d'enfant if (northWest == null) return pointsInRange; // Sinon, relancer la recherche sur les 4 enfants et ajouter les points trouvés pointsInRange.appendArray(northWest→queryRange(range)); pointsInRange.appendArray(northEast→queryRange(range)); pointsInRange.appendArray(southWest→queryRange(range)); pointsInRange.appendArray(southEast→queryRange(range)); return pointsInRange; } }
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.