Intersection de cercle avec l'algorithme de ligne de balayage

15

Malheureusement, je ne suis toujours pas aussi fort pour comprendre l' algorithme de ligne de balayage . Tous les articles et manuels sur le sujet sont déjà lus, mais la compréhension est encore loin. Juste pour que ce soit plus clair, j'essaie de résoudre autant d'exercices que possible. Mais, des tâches vraiment intéressantes et importantes sont toujours un défi pour moi.

L'exercice suivant, je l'ai trouvé dans les notes de cours de Line Segment Intersection par le tout puissant Jeff Erickson.

Exercice 2. Décrire et analyser un algorithme sweepline pour déterminer, étant donné cercles dans le plan, si deux se croisent, en temps . Chaque cercle est spécifié par son centre et son rayon, donc l'entrée se compose de trois tableaux et . Veillez à implémenter correctement les primitives de bas niveau.O ( n log n ) X [ 1 .. n ] , Y [ 1 .. n ] R [ 1 .. n ]nO(nJournaln)X[1..n],Oui[1..n]R[1..n]

Essayons de faciliter une chose complexe. Que savons-nous de l'intersection des cercles? Quel analogue peut être trouvé avec l'intersection des lignes. Deux lignes peuvent se croiser si elles sont adjacentes, quelle propriété deux cercles devraient-ils avoir pour se croiser? Soit la distance entre le centre des cercles, et centres des cercles. Considérez quelques cas:r 0 r 1r0r1

  • Cas 1: Si alors il n'y a pas de solutions, les cercles sont séparés.>r0+r1

  • Cas 2: Sialors il n'y a pas de solutions car un cercle est contenu dans l'autre.<|r0-r1|

  • Cas 3: si et alors les cercles coïncident et il existe un nombre infini de solutions.r 0 = r 1=0r0=r1

Ainsi, il semble que les conditions d'intersection soient prêtes, bien sûr, il peut s'agir de mauvaises conditions. Veuillez corriger si c'est le cas.

Algorithme. Maintenant, nous devons trouver quelque chose en commun entre deux cercles qui se croisent. Avec l'intersection analogique-ligne, nous devons avoir une condition d'insertion et une condition de suppression dans la file d'attente d'événements. Disons que le point d'événement est la coordonnée x du premier et du dernier point que la ligne de balayage verticale touche. Sur le premier point, nous insérons le cercle au statut et vérifions l'intersection (3 cas de vérification sont mentionnés ci-dessus) avec les cercles les plus proches, sur le dernier point, nous supprimons le cercle du statut .

Il semble que ce soit suffisant pour l'algorithme de ligne de balayage. S'il y a quelque chose qui ne va pas, ou peut-être qu'il y a quelque chose qui devrait être fait différemment, n'hésitez pas à partager vos pensées avec nous.

Addendum :

J'insère un cercle lorsque la ligne de balayage verticale touche le cercle pour la première fois et je supprime un cercle de l'état lorsque la ligne de balayage le touche pour la dernière fois. La vérification de l'intersection doit être effectuée pour le cercle précédent le plus proche. Si nous avons ajouté un cercle au statut et qu'il y avait déjà un autre cercle que nous avons ajouté auparavant et qu'il était toujours là, donc le cercle perméable n'était pas "fermé", donc il pourrait y avoir une intersection.

com
la source
4
omnipotent [citation nécessaire]
JeffE
@com qu'entendez-vous par "cercle précédent le plus proche"?
Joe
1
Je suppose que statusmaintient les cercles qui coupent actuellement la ligne de balayage? Supposons que vous ayez actuellement 100 cercles status, que vous traitez un événement d'insertion et insérez le 101e cercle. Combien de cercles comparez-vous pour vérifier l'intersection? Comment choisissez-vous les cercles à comparer?
Joe
@Joe, c'est exactement ce dont j'ai besoin, comme dans l'algorithme de ligne de balayage classique, où "l'intersection de deux lignes implique l'adjacence de ces deux lignes à un moment donné", j'ai besoin de trouver l'analogue similaire avec des cercles. La chose la plus simple que je viens avec est plus bas de coordonnées et le plus de coordonnées du cercle, si le cercle se croisent leur projection d'intervalles de la plus basse au plus haut devrait recouper à. Alors peut-être que maintenant je me rapproche de votre idée des demi-cercles. Au-dessus des demi-cercles contient le le plus élevé et en dessous contient le le plus bas . y y y y y yyyyyyy
com

Réponses:

5

Vous êtes définitivement sur la bonne voie. La grande question est: lorsque vous insérez un cercle, quels autres cercles vérifiez-vous pour l'intersection? Comment effectuez-vous cette vérification?

Dans le cas d'intersection de segments de ligne, les segments de ligne à n'importe quelle coordonnée x donnée sont totalement ordonnés. (Vous pouvez les répertorier de la coordonnée Y la plus basse à la plus élevée). Ainsi, vous pouvez conserver les segments de ligne dans une arborescence de recherche binaire et lorsque vous ajoutez un nouveau segment, il vous suffit de savoir où il appartient dans l'arborescence de recherche binaire et de vérifier ses voisins pour les événements d'intersection.

Dans le cas des cercles, il n'est pas immédiatement clair quels cercles vérifier. Si votre réponse est «tous», alors votre algorithme a besoin d'un peu de travail.

Pouvez-vous trouver un moyen de représenter les cercles afin qu'ils soient totalement ordonnés, comme le sont les segments de ligne?

Essayez de représenter les cercles en deux demi-cercles. Chaque événement d'insertion est en fait deux événements: insérer la moitié supérieure et insérer la moitié inférieure.

Joe
la source
Malheureusement, je n'ai pas l'idée des demi-cercles, peut-être que vous considérez le demi-cercle comme une unité minimale de cercle qui peut être intersectée (3 cas d'intersection: l'intersection est sur le demi-cercle supérieur, ou sur le bas, ou sur les deux). À la mendicité, tous les cercles sont classés par coordonnée x de leurs limites gauche et droite. Nous ne devons donc pas considérer x coordonné dans l' état , car tous les cercles viennent déjà dans l'ordre des coordonnées x. Par conséquent, il semble plus logique de considérer la coordonnée y du centre (du demi-cercle), ou toute combinaison de y et de rayons. Votre opinion?
com
@com Vous avez besoin du point central et du rayon pour déterminer si deux cercles se croisent, comme vous l'avez fait dans vos propres vérifications d'intersection. Seule la coordonnée y et le rayon seuls ne spécifient pas entièrement la limite du cercle. Il semble y avoir quelque chose de fondamental dans les algorithmes de ligne de balayage que vous ne comprenez pas, mais il m'est difficile de dire de quoi il s'agit.
Joe
0

Je pourrais penser à cette approche analogue au balayage Bentley Ottmann qui s'exécute en temps O ((n + k) logn).

Je pourrais réduire le problème de l'intersection de cercle en intersection de segment de ligne. Je considérerai le diamètre vertical parallèle à l'axe Y pour chacun des cercles. L'algorithme doit utiliser une ligne horizontale qui balaye l'avion de bas en haut.

Nous avons maintenant le point final supérieur, le point final inférieur pour chacun des cercles. De plus, nous devons modifier le prédicat Intersection pour dire que deux segments se croisent si et seulement si la ligne de balayage coupe les deux cercles en un point.

Comme le problème d'intersection de lignes peut être résolu en temps O ((n + k) logn), la même borne suit également pour l'intersection de cercle.

Je suis tout à fait convaincu que cela fonctionnerait, mais si vous pouvez signaler n'importe quel cas que cela ne traitera pas en général, faites-le moi savoir.

TheGT
la source