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 ]
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 1
Cas 1: Si alors il n'y a pas de solutions, les cercles sont séparés.
Cas 2: Sialors il n'y a pas de solutions car un cercle est contenu dans l'autre.
Cas 3: si et alors les cercles coïncident et il existe un nombre infini de solutions.r 0 = r 1
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.
status
maintient les cercles qui coupent actuellement la ligne de balayage? Supposons que vous ayez actuellement 100 cerclesstatus
, 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?Réponses:
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?
la source
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.
la source