Comment puis-je ajouter et soustraire des polygones convexes?

12

J'ai deux polygones convexes 2D qui se chevauchent . Je recherche un algorithme pour les soustraire et les ajouter . Le résultat doit être un seul polygone concave ou (mieux encore) un ensemble de plus grands convexes formant le résultat concave (par exemple des triangles).

entrez la description de l'image ici

gauche: les polygones qui se chevauchent initialement. Au milieu: le polygone concave résultant après l'ajout. À droite: un ensemble de polygones convexes formant le résultat concave. Ici, il serait préférable d'avoir des polygones convexes plus grands qu'un triangle pour des raisons de performances. Une soustraction de la deux polygones qui se chevauchent mèneraient à la même image qu'à gauche mais avec la zone de chevauchement ne faisant pas partie du polygone résultant.)

Comment puis-je faire ceci?

Sebastian Barth
la source
Parlons-nous de 2D ici? parce qu'en 3D, la combinaison de polygones n'a pas vraiment de sens.
concept3d
Oui, sry, je parle de 2D! Bien que je ne vois pas pourquoi cela n'a pas moins de sens en 3D qu'en 2D.
Sebastian Barth
2
ajouter deux polygones en 3D, s'ils sont plats, cela n'a pas beaucoup de sens à moins qu'ils ne soient sur le même plan, s'ils ont du volume (solides) alors c'est une autre histoire.
concept3d
D'accord, je l'ai. Je ne pensais pas aux graphiques, mais aux objets de collision. Merci pour la clarification.
Sebastian Barth
De plus, recherchez tous les points qu'ils croisent et ajoutez les sommets à un ensemble. L'ensemble est important pour éviter les chevauchements. Ensuite, ajoutez simplement tous les autres sommets des deux autres formes dans l'ensemble. Cet ensemble contient tous les sommets de la forme additive.
Vaughan Hilts

Réponses:

9

TL; DR Vous devez implémenter des opérations booléennes à l'aide d'arbres BSP.

Eh bien, il semble que nous parlions ici de géométrie solide constructive . J'ai implémenté CSG à un niveau commercial, donc je sais une chose ou deux à ce sujet.

L'article classique sur CSG s'appelle Merging BSP Trees Yields Polyhedral Set Operations , pour être honnête, c'est trop à expliquer ici, mais en bref, l'algorithme traite des polygones qui se trouvent sur le même plan qu'un partitionnement d'espace binaire, construisant essentiellement un arbre BSP de chaque maillage polygonal. La deuxième étape consiste à fusionner ces arbres BSP; vous prenez simplement un arbre et l'insérez dans l'autre. L'algorithme continue ensuite d'expliquer comment traiter chaque nœud feuille pour diviser et soustraire les nœuds, les nœuds qui ne sont pas nécessaires dans la forme finale seront supprimés, d'autres recevront le parent approprié.

Mais attendez! Ce document parle essentiellement des maillages polygonaux et des plans 3D, NON?

L'algorithme peut être généralisé dans n'importe quelle dimension, donc dans votre cas 2D, il est facile d'utiliser des segments de ligne au lieu de plan comme partitions binaires. Ainsi, chaque polygone sera converti en un arbre BSP que les deux seront fusionnés. Enfin, vous traversez l'arbre résultant pour générer le polygone final,

Notez que cet algorithme et le CSG en général ne traitent pas directement le rendu et les faces de maillage et ne sont pas vraiment prêts, vous devez donc extraire les faces des arborescences BSP finales. Je trouve également que le lancer de rayons est une approche plus facile pour rendre le résultat CSG, vous n'avez besoin que des rayons pour traverser l'arbre au lieu d'extraire et de diviser les faces (rappelez-vous que nous ne traitons que des partitions binaires).

Concernant la robustesse numérique. Il est bon de noter qu'il existe deux types de calculs géométriques,

  • Ceux qui sont basés sur la construction, vous construisez une forme basée sur le résultat d'une opération précédente. Par exemple y = sqrt(x), puis utiliser ydans une nouvelle opération. C'est ce qu'on appelle la construction; le problème est que les erreurs numériques s'accumulent rapidement.
  • Alternativement, il existe des opérations qui utilisent des prédicats à la place, essentiellement au lieu d'utiliser la construction, vous demandez simplement si une condition est vraie / fausse et utilisez la même valeur dans une opération différente. Les tests classiques incluent incircle et le test d'orientation; cela est également suspect d'erreurs numériques, surtout si vous utilisez une précision simple ou double, mais donne généralement de bien meilleurs résultats. il existe d'autres solutions qui varient selon la vitesse et la précision. Voici l'un des articles récents qui évitent la construction en utilisant une géométrie plane pour donner des résultats précis. Je citerai également le document:

Le concept de représentation plane des maillages polygonaux a été décrit pour la première fois par Sugihara et Iri [SI89]. Ce type de représentation fournit un avantage important en ce qui concerne les tâches qui impliquent de changer la topologie des solides représentés par des maillages comme l'évaluation des expressions booléennes: aucune nouvelle information de géométrie primaire ne doit être construite pour obtenir le polyèdre résultant

entrez la description de l'image ici

Et enfin, je voudrais ajouter, si vous souhaitez démarrer votre implémentation CSG BSP, je recommanderais de commencer sur les FAQ BSP .

concept3d
la source
Cool, mais contre-intuitif, étant donné qu'un BSP d'un polygone ou d'un polyèdre convexe est une liste. Grand papier.
3Dave
@DavidLively oui, mais peut en faire un arbre équilibré en choisissant le plan racine comme étant différent des faces. En fait, cela fait partie du défi dont ils ne parlent pas
concept3d
Ah, ça a du sens. Une sorte de BSP hybride, alors.
3Dave
@DavidLively, le BSP n'est pas vraiment facile à rendre, bien que la question OP soit un cas simple, dans un cas plus complexe avec une géométrie de millions de polygones, une fois que vous avez terminé la construction de l'arbre, vous êtes loin d'être terminé.
concept3d
@ concept3d J'espère que ce ne sera pas trop ennuyeux car il s'agit d'une réponse vieille de 5 ans, mais il y a deux choses que je ne comprends pas vraiment: lorsque vous essayez de déterminer si un point se trouve à gauche ou à droite d'un avion / d'une ligne, ne serait-il pas plus facile de simplement faire pivoter le tout pour que le plan / la ligne corresponde à un plan / ligne trivial, puis de ne considérer que les coordonnées du point pivoté? Que diriez-vous d'utiliser l'algorithme Sutherland – Hodgman au lieu des arbres BSP? Cela ressemble assez à cette approche.
John P
1

En suivant votre exemple:

Choisissez un sommet de départ sur le polygone A, puis commencez à vérifier les arêtes qui se coupent dans le sens horaire (ou antihoraire). S'il n'y a pas d'intersection, ajoutez le sommet précédent à votre polygone résultant. S'il y a une intersection, ajoutez le point auquel ils se sont intersectés au polygone résultant, puis commencez à itérer sur le polygone B, dans le même ordre d'enroulement. Faites la même chose, en échangeant à nouveau vers le polygone A si une intersection se produit.

Une fois que vous avez accumulé tous les sommets du nouveau polygone, exécutez un algorithme de triangulation dessus. La méthode de coupure d'oreille est facile à mettre en œuvre, mais il existe des options plus rapides.

Important: assurez-vous que le sommet à partir duquel vous commencez n'est pas à l'intérieur de l'autre polygone (consultez cet article pour les points dans les tests de polygone).

Itérer sur chaque arête, pour vérifier une intersection serait un algorithme O (n ^ 2). Vous pouvez l'accélérer en trouvant d'abord les sommets qui se trouvent à l'intérieur de l'autre polygone, car les arêtes liées à ces sommets seront celles qui se coupent.

Faute
la source
0

Si vous voulez un polygone concave , choisissez simplement l'arête la plus proche entre les deux polygones d'entrée et ajoutez deux nouvelles arêtes:

entrez la description de l'image ici

La convexe devient un peu plus compliquée:

entrez la description de l'image ici

Une approche est itérative en ce qu'elle ajoute des sommets du deuxième polygone au premier, un à la fois, faisant évoluer le premier polygone dans un conteneur qui englobe tout.

Fondamentalement:

  • Itérer à travers les sommets du deuxième polygone.
  • Pour chaque sommet V, parcourez les arêtes du premier polygone:
  • Trouver une "plage" d'arêtes qui font toutes face au sommet
  • prendre la paire de sommets externes qui définissent cette plage et supprimer toutes les arêtes de la plage qui les relie
  • Dessinez deux nouveaux segments de ces sommets externes vers le nouveau sommet (à partir du deuxième polygone), en vous assurant que les nouvelles arêtes sont orientées dans la bonne direction.
  • Passez au sommet suivant du deuxième polygone

Voici un diagramme illustrant le processus pour le premier sommet:

entrez la description de l'image ici

Une méthode plus rapide consiste à trouver la liste des arêtes sur chaque polygone qui ne font pas face à l'autre polygone, supprimer tout le reste et connecter les extrémités des bandes de lignes restantes les unes aux autres.

Peut-être que quelqu'un d'autre peut sonner avec quelques conseils de soustraction.

3Dave
la source
Cela ne semble résoudre que la moitié du problème (ajout). Il pourrait également être utile de souligner le fonctionnement des algorithmes ou pourrait être optimisé si les polygones se chevauchent.
L'algorithme ignore implicitement les sommets qui sont "à l'intérieur" du polygone cible, ce qui compense également le problème où une arête du deuxième polygone croise le premier.
3Dave
Cela équivaut presque à la phase de fusion (point 4. de l' algorithme de fusion de la coque . Dans mon cas, ce n'est pas une bonne solution pour enfermer plus de surface après avoir combiné les polygones. La bonne solution serait de garder les deux polygones tels qu'ils sont car ils ne sont pas '' t se chevauchent, ni se touchent
Sebastian Barth
@luftgewehrindianer Ah - Oui, cela fait une grande différence. J'ai peut-être mal compris la question. Cherchez-vous à ajouter les polygones ensemble, sans vous soucier de savoir si le résultat est convexe ou concave? Ou générer un ensemble convexe basé sur l'intersection? (Ignorant la soustraction pour le moment.)
3Dave
@DavidLively Imaginez deux polygones convexes de la même couleur et sans trait de bordure. Quand ils se chevauchent, il ressemble à un nouveau polygone convexe ou concave. Il essaie de trouver une triangulation de la forme combinée. N'ajoutez pas de zone entre les deux polygones.
danijar