Tout d'abord, je pense que cela vaut la peine de considérer ce que sont vos besoins réels.Je pense que ce n'est pas seulement "stocker les points actifs et aucun des autres d'une manière aussi efficace que possible", mais aussi "stocker des points adjacents dans des emplacements mémoire proches afin d'avoir un bon comportement de mise en cache". "stocker les points d'une manière pour laquelle les recherches peuvent être effectuées efficacement".
Cela dit, voici ce que je suggère. Divisez la région 3D complète en blocs cubiques, tous de la même taille. Pour chaque bloc, stockez tous les points du bloc dans des tableaux denses, y compris un tableau isTissue booléen pour savoir si chaque point est dans la région tissulaire ou non. Allouer seulement les blocs qui ont des points en eux. Faire un tableau (dense) de pointeurs vers des blocs, avec des pointeurs NULL pour les blocs non alloués. Ainsi, pour trouver le point en (i, j), vous devez d'abord calculer ii = i/bloc, jj = j/blocksize, puis chercher dans la table pointeur à bloc en (ii, jj) trouvez le bloc qui contient votre point. Si ce pointeur est NULL, votre point n'est pas dans le tissu. Si elle est non nulle, vous regardez (i mod blocksize, j mod blocksize) dans ce bloc, et il y a votre point (i, j). Vous pouvez vérifier son indicateur isTissue pour voir s'il s'agit d'un point "présent" ou non. Vous voudrez choisir la taille de bloc comme un équilibre entre la minimisation du nombre de fois que vous faites des calculs de points adjacents qui traversent les limites de blocs, et la minimisation du nombre de points qui sont dans les blocs mais pas dans la région de tissu. Je suppose qu'au minimum, vous voulez qu'une ligne du bloc soit longue. Probablement l'optimum est plutôt plus grand que cela, même si cela dépendra au moins un peu de votre géométrie. Pour parcourir tous les points d'une boîte 3D, vous effectuez simplement des recherches pour chaque point, ou (plus efficacement) déterminez les blocs qui touchent la boîte et parcourez les régions dans les blocs qui se trouvent dans votre boîte. case, en ignorant celles où isTissue est false. Si vous faites beaucoup de désallocation et de réallocation de blocs, vous voulez probablement "libérer" les blocs en les déposant dans un pool "inutilisé", puis en extrayant des blocs de ce pool plutôt que de les réaffecter . Cela a aussi l'avantage que tous ces points auront déjà tous leurs points sur "non présents" (parce que c'est pour cela que vous avez libéré le bloc), donc vous n'avez pas besoin de les initialiser.
Le lecteur expérimenté reconnaîtra probablement les similitudes entre ceci et les façons de disposer des données pour les calculs parallèles; Si vous avez une très grande simulation, vous pouvez facilement répartir les blocs sur plusieurs nœuds, et vous n'avez besoin que d'une communication entre nœuds pour les calculs de blocs croisés. Pour ce genre d'application, vous pouvez trouver utile de faire des niveaux imbriqués de blocs, où vous avez des méta-blocs (pour la communication entre nœuds) contenant des blocs plus petits (pour la géométrie).
Je suis simplement curieux ... Allez-vous utiliser les données de géométrie du tissu pour effectuer un rendu? –
Je ne suis pas tout à fait clair ce que votre géométrie est ici. Vous mentionnez que chaque point a des voisins orthogonaux, ce qui implique une grille de points régulière, mais ensuite vous faites référence à des données éparses. Ai-je raison de comprendre que votre ensemble de points est essentiellement un sous-ensemble (connecté) des points sur une grille régulière? –