Test fiable pour l'intersection de deux courbes de Bézier


9

Comment savoir de manière fiable si deux courbes de Bézier planes se coupent? Par «de manière fiable», je veux dire que le test ne répondra «oui» que lorsque les courbes se coupent et «non» uniquement lorsqu'elles ne se coupent pas. Je n'ai pas besoin de savoir à quels paramètres l'intersection a été trouvée. Je voudrais également utiliser des nombres à virgule flottante dans l'implémentation.

J'ai trouvé plusieurs réponses sur StackOverflow qui utilisent les boîtes de délimitation des courbes pour le test: ce n'est pas ce que je recherche car un tel test peut signaler une intersection même si les courbes ne se croisent pas.

La chose la plus proche que j'ai trouvée jusqu'à présent est le " coin de délimitation " de Sederberg et Meyers mais il "seulement" fait la distinction entre au plus une et deux ou plusieurs intersections, alors que je veux savoir s'il y a au plus zéro et une ou plusieurs intersections.


Je ne suis pas sûr qu'il existe en tant que tel, déterminer wetehr ou theres une possibilité de 0-1 ou 2 ou plus est assez trivial mais la formulation ne rend pas vraiment facile de s'assurer que son 0 ou 1 sans réellement vérifier.
joojaa

Quelles sont les exigences d'exécution? Une solution qui devrait être en mesure de produire des résultats assez précis serait d'approximer les deux courbes par un grand nombre de courts segments droits, puis de les croiser par paire. Mais cela coûte beaucoup de temps et de mémoire.
Dragonseel

@Dragonseel Eh bien, je serais heureux de toute solution, vraiment, mais puisque vous avez demandé à O (1), ce serait bien. Mais l'approximation des courbes avec des segments de ligne entraîne les mêmes problèmes que le test de chevauchement des boîtes englobantes ...
Ecir Hana

Problème intéressant. Je ne pense pas qu'il y ait de réponse facile, mais j'aimerais me tromper. Avez-vous un lien pour le papier Sederberg et Meyers?
Daniel M Gessel

@DanielMGessel Oui, voir la modification ci-dessus.
Ecir Hana

Réponses:


6

Une autre façon de formuler le problème est de définir une fonction qui donne la distance entre les points sur les deux courbes, en fonction des paramètres des courbes. Essayez ensuite de trouver le minimum global de cette fonction. Si les courbes se coupent, le minimum sera nul; sinon le minimum sera une distance positive.

Pour être explicite, étant donné une paire de courbes 2D définies par , définissez la distance au carré commec1,c2:[0,1]R2

f(u,v):[0,1]2R0|c2(v)c1(u)|2

f


[0,1]2R2

1
[0,1]R2

1
xyxciy

@Nathan: J'y avais pensé mais, après avoir passé beaucoup de temps à écrire du code pour trouver des minima dans les formats de compression de texture, tout cela semblait un peu hideux.
Simon F

5

[Avertissement: je pense que ce qui suit devrait fonctionner, mais je ne l'ai pas codé moi-même]

Je ne pouvais pas penser à une méthode «triviale» pour produire une réponse oui / non, mais ce qui suit serait une approche raisonnable pour une solution pratique à la question.

Supposons que nos courbes soient A (s) et B (t) avec les points de contrôle { A0, A1..An } et { B0, .. Bm } respectivement.

Il me semble que, étant donné une paire de Béziers 2D pour laquelle nous souhaitons déterminer si oui ou non se croisent, il y a six cas à considérer:

  1. Cas où l'on peut déterminer "trivialement" qu'elles ne se croisent pas .

  2. Cas où elles se croisent un nombre fini de fois et où nous pouvons «facilement» déterminer qu'elles se coupent définitivement au moins une fois (mais peu nous importe où ces intersections se produisent)

  3. L'un des Béziers est dégénéré, c'est-à-dire un point (qui se produira si tous les points de contrôle sont identiques). Nous pouvons supposer que nous avons déjà traité le cas où les deux sont des points.

  4. Une ou plusieurs des courbes sont fermées, par exemple. A0 == An. Pour vous simplifier la vie, nous allons subdiviser ces courbes et recommencer.

  5. Il existe un nombre infini de points d'intersection car chacun est un sous-ensemble d'un Bézier "parent" et ils se chevauchent.

  6. Nous ne sommes pas certains des cas ci-dessus et avons besoin d'une enquête plus approfondie

Pour le moment, nous ignorerons 3 et 4, mais nous y reviendrons plus tard.

Cas 1

Comme vous l'indiquez dans votre question, si les cases de délimitation respectives des points de contrôle de A et B ) ne se coupent pas, les courbes ne peuvent pas se croiser. Évidemment, c'est un test de rejet rapide, mais il est trop conservateur. Comme vous le savez probablement, avec une courbe de Bézier, la coque convexe de ses points de contrôle forme une limite (plus serrée) sur la courbe. On peut ainsi utiliser la technique de l'axe de séparation pour décider si les coques de A et B ne se croisent pas. (par exemple, comme indiqué dans Wikipedia :)

entrez la description de l'image ici

Cas 2

Si le test du cas 1 échoue, vous pouvez alors vérifier l'existence "triviale" d'une intersection. Maintenant, il existe probablement de meilleures façons de le faire, mais l'approche suivante, relativement bon marché, m'est venue à l'esprit:

Considérez simplement la courbe A:

Limites de la "ligne épaisse" d'un Bézier

A0AnA0An¯A0An¯

Si nous faisons de même avec la courbe B, nous obtenons le cas (possible) suivant: entrez la description de l'image ici

A0AnB0Bm

Cas 6

A1,A2,B1,B2

(A1,B1),(A2,B1)...(A2,B2)

Cas 3 et 5

C'est là que ça devient un peu plus fastidieux.

Si le «cas 3» dépasse le test du «cas 1», il me semble que vous devez résoudre une intersection réelle. Étant donné qu'il existe un processus simple pour mapper les N points de contrôle d'un Bézier, A (s), aux N-1 points du Bézier, A '(s), représentant alors sa première dérivée (à condition de prendre soin de la des situations relativement rares, dites «dégénérées» où la dérivée 1 fait zéro), alors l'itération de Newton (sur une dimension) pourrait être utilisée pour trouver des solutions potentielles.
Notez également que, puisque les points de contrôle de A '(s) sont liés aux valeurs dérivées, il existe un potentiel d'élimination précoce de certains cas.

Le cas 5 semble relativement improbable, donc peut-être seulement si après quelques récursions il n'y a pas de preuve concluante, on pourrait essayer chaque point final de A contre la courbe B et vice versa. Cela ne donnerait qu'une preuve d'intersection - pas une preuve de non-intersection.


Oui, mais je suis personnellement plus intéressé par le cas où le cas où le Bm et / ou le B0 sont tous deux dans le volume des limites max et min de A mais ne le percent pas, alors vous devez subdiviser et dans le pire des cas calculer l'intersection point. Il serait préférable d'utiliser la zone de délimitation minimale, également appelée approximation des lignes épaisses.
joojaa

Étant donné que, à chaque subdivision binaire, la différence entre la courbe et le segment reliant les points d'extrémité diminue d'un facteur raisonnable (et, du haut de ma tête, je pense que cela aurait pu être 4x pour les quadratiques), les limites vont sûrement aller pour converger vers un ruban "fin" assez rapidement.
Simon F

Oui, mais le pire des cas est que l'autre bézier commence à l'autre.
joojaa

Vous voulez dire, par exemple, An == B0 . Définissez-vous cela comme une intersection ou non?
Simon F

Pas plus comme B0 est quelque part sur la courbe. Ou même une traversée minimale
joojaa
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.