Computational Geometry Course outline Introduction Line intersections Polygon triangulation Geometric search Voronoï diagrams Delaunay Triangulations Binary Space Partition Trees 1 Computational Geometry Line intersections Line segments intersections Polygonal zones intersections Plane sweeping / DCEL 2 Computational Geometry Line intersections Classical problem in GIS Example : One has access to several independent maps : Forestry Wildlife etc... One wishes to know every homogeneous zones for every tuple of characteristics : e.g. deciduous forest & deers pine forest & deers pne forest & bears … and so forth. 3 Computational Geometry Line intersections Types of data that are contained in maps : Towns (as points or polygons) Rivers, highways (networks, graphs) Wooden areas, or of a given climate (polygones) One needs to combine 2 or more of these maps, therefore compute intersections Two maps with networks → points (bridges ?) Two maps with areas (zones) → new polygons Any combination... One common task (elementary task) is the intersection between two sets of line segments. 4 Computational Geometry Line intersections Line segments intersections 5 Computational Geometry Line intersections Intersection de segments Données en entrée : Deux ensembles de segments En sortie : Toutes les intersections entre ces deux ensembles On peut sans perte de généralité rassembler les deux ensembles et calculer les intersections à l'intérieur d'un seul ensemble. Il est possible de trouver des intersection au sein du même ensemble d'origine mais cela peut être filtré par la suite. 6 Computational Geometry Line intersections Algorithme 1 Force brute : prendre chaque paire de segments et vérifier si ils s'intersectent O(n²) !!! En un sens, c'est optimal si un grand nombre de segments s'intersectent (aussi en O(n²) ) Les algorithmes calculant ces intersections prennent 2 nécessairement un temps en n exemple : 2n segments n² intersections 7 Computational Geometry Line intersections En pratique, le nombre d'intersections n'est généralement pas en O(n²). L'algorithme n'est alors plus optimal On doit établir un algorithme plus efficace Idéalement O(f(n,I))) avec f(n,I) meilleur que O(n²) quand I est O(n) Ici, la complexité attendue est fonction des données d'entrée (nombre de segments n) mais aussi des données de sortie (ici le nombre d'intersections I ) On parle d'algorithme sensible aux données de sortie – ce n'était pas le cas pour certains algorithmes calculant l'enveloppe convexe. Comment ne pas tester toutes les paires de segments quand ce n'est pas nécessaire ? Utilisation de la géométrie... 8 Computational Geometry Line intersections Soit S ={s1, s2, s3, ... , s n } l'ensemble des segments. Ne testons les segments que si leur intervalle sur x (projection orthogonale sur l'axe x) est non disjoint y x 9 Computational Geometry Line intersections Pour détecter les paire de segments dont la projection sur x est non disjointe, utilisation d'une ligne imaginaire l balayant de gauche à droite le domaine Le statut de la ligne l est l'ensemble des segments qui l'intersectent l Point événement Il change au fur et à mesure du déplacement de la ligne À chaque événement ; le statut est mis à jour C'est le seul moment ou l'on « fait » quelque chose : ajouter un segment, faire quelques tests d'intersections, retirer un segment. Si un événement correspond à une extrémité à gauche, ajout de segment ; on teste l'intersection avec les segments déjà présents Si un point événement est une extrémité à droite, retirer le segment du statut. 10 Computational Geometry Line intersections On teste donc tous les segments présents dans le statut. Est-ce optimal ? Non ! Ici on teste un nombre quadratique de paires de segments ... 11 Computational Geometry Line intersections Ordonnons les segments dans le statut de bas en haut Cela permet de savoir si deux segments sont proches ou éloignés dans la direction verticale On ne teste que des segments adjacents dans cet ordre. Lorsque l'on ajoute un segment dans le statut, on ne le teste qu'avec celui « au dessous » et celui « au dessus » Si un événement est une intersection simple, il faut intervertir les segments concernés dans le classement... et les tester avec leurs nouveaux voisins Si un événement revient à retirer un segment du statut, on teste les deux segments qui deviennent voisins. Ainsi, chaque nouvelle adjacence dans le statut est testée pour intersection 12 Computational Geometry Line intersections Cet algorithme fonctionne-t-il ? Il faut vérifier que chaque point d'intersection p peut être calculé au moment ou l'on traite un événement. Revient à montrer que si et sj deviennent adjacents avant de traiter p l sji sk si p Ici, si et sj deviennent adjacents losque sk est retiré du statut. C'est la cas, car les deux segments sont adjacents dans le statut au moment ou est p est traité ; mais ne le sont pas au début (avant l'ajout d'un des segment si ou sj). Il existe donc un événement pour lequel ils deviennent adjacents. 13 Computational Geometry Line intersections En principe l'algorithme fonctionne, sans tenir compte des cas dégénérés. Intersections de 3 segments ou plus au même point Segments verticaux Segments confondus 14 Computational Geometry Line intersections « Invariant » de l'algorithme : tous les points d'intersection à gauche de la ligne ont été calculés correctement. 15 Computational Geometry Line intersections Structures de données La file des événements F Classée de façon lexicographique en fonction des coordonnées du point considéré → règle le cas des points situés sur une même coordonnée x (e.g. Segments verticaux) - structure identique à celle utilisée dans le cas du calcul de l'enveloppe convexe Détermine la nature de l'événement Point « gauche » d'un segment → ajout dans le statut Point « droit » d'un segment → retrait du statut Point d'intersection → échange de deux segments dans le statut Le statut T Classé en permanence selon l'ordre des segments le long de la ligne l Permet de rechercher rapidement les segments contigus à un événement donné (classement selon la coordonnée y par exemple) Difficulté : la clef (coordonnée y) varie lorsque l se déplace … 16 Computational Geometry Line intersections Les algorithmes : TrouveIntersections(S) Entrée : un ensemble de segments S dans le plan Sortie : un ensemble contenant les points d'intersection, avec pour chacun des points les segments qui le contiennent { Initialiser une file d'événements F vide. Insérer les points extrémités des segments de S dans F. Si le point est un point situé a gauche du segment, on y attache le segment. Initialiser une stucture Statut T vide. Tant que F est non vide { Trouver le prochain point p de F, et l'effacer de F. TraiteEvenement(p,T) } } 17 Computational Geometry Line intersections TraiteEvenement(p) doit être capable de traiter les cas dégénérés suivants : l s1 p s2 s6 s2 s1 s3 s4 s5 T={s5, s4, s3, s2, s1} → T={s5, s1, s2, s6} 18 Computational Geometry Line intersections TraiteEvenement(p) { Soit L(p) l'ensemble des segments dont le point « à gauche » est p (ils sont connus et stockés avec p) Trouver tous les segments dans T qui contiennent p ; ils sont adjacents dans T. Soit R(p) le sous ensemble de ces segments dont p est le point « droit » C(p) le sous ensemble des segments contenant p dans leur intérieur. Si Union(L(p),R(p),C(p)) contient plus d'un segment { p est une intersection, y attacher L(p),R(p),C(p) } Effacer les segments appartenant a Union(R(p),C(p)) de T Inserer les segments appartenant a Union(L(p),C(p)) dans T : l'ordre nouveau doit correspondre à l'ordre obtenu si l est juste à droite de p. Si il y a un segment vertical, il vient en dernier. Note : l'ordre parmi les segments de C(p) est renversé... Si Union(L(p),C(p)) est vide { Soit su et sd les voisins du dessus et du dessous de p dans T s6 l L(p) TrouverEvenement(su , sd , p) s1 } p s2 Sinon s 2 { C(p) Soit s' le segment le plus haut dans Union(L(p),C(p)) s1 Soit su le segment voisin (vers le haut) de s' dans T s3 s4 Si su existe TrouverEvenement(su , s', p) R(p) Soit s'' le segment le plus bas dans Union(L(p),C(p)) Soit sd le segment voisin (vers le bas) de s'' dans T s5 Si sd existe TrouverEvenement(s'' , sd , p) } } 19 Computational Geometry Line intersections TrouveEvenement(s1 , s2 , p) { Si s1 et s2 s'intersectent à droite de la ligne l, ou sur la ligne l mais au dessus de p Et que l'intersection n'est pas présente dans F Inserer l'intersection comme nouvel événement dans F. } 20 Computational Geometry Line intersections Analyse de l'algorithme L'algorithme trouve-t-il toutes les intersections ? Preuve par induction sur la priorité des événements On suppose que toutes les événements de plus haute priorité (avant p dans la file) sont correctement traitées. Soit p est une extrémité d'un des segments Il a été inséré dans F au début de l'algorithme et y figure donc, avec L(p), et les segments R(p) et C(p) sont dans T au moment ou cet événement est traité. Soit p est une intersection, il faut prouver que p a été introduit dans F à un moment ou à un autre. Ici , tous les segments impliqués ont p dans leur intérieur. Soit si et sj deux segments voisins dans T. La preuve précédente (slide 13) permet d'affirmer que ces segments deviennent voisins (et sont donc testés et p calculé) pour un certain événement q antérieur à p. (Cf page 27 du livre) 21 Computational Geometry Line intersections Performance en temps de l'algorithme On peut prouver que T=O((n+k) log n) avec k = taille de la sortie degré=4 On peut prouver un résultat plus fort : T=O((n+I) log n) avec I = nombre d'intersections → considérations sur les graphes plans e1 e2 File d'événements : O(n log n) Le traitement de chaque événement Insertions / délétions dans F : log n chaque Insertions / délétions dans T : log n chaque (au pire), mais il y en a m(p)=Card(Union(L( p ) , R( p ) , C( p ) ) ) Soit m la somme des m(p), globalement on a O(m log n) Or m=O(n+k), k étant la taille de la sortie (segments + intersections) Au final, on a donc une complexité de de O((n+k) log n) m est borné par la somme des degrés de chaque sommet Chaque arête contribue au degré de au plus deux sommets, donc m est borné par 2ne (nombre d'arêtes du graphe). nv (nombre de sommets) est au plus égal à 2n+I, Or, sur un graphe plan, ne= O(nv), CQFD. 22 Computational Geometry Line intersections Relation d'Euler … pour les graphes plans Chaque face du graphe plan est bornée par au moins 3 arêtes Une arête limite au plus deux faces distinctes Donc nf ≤ 2ne /3 Formule d'euler : nv – ne+nf = r avec r≥2 r dépend du genre topologique (nb de trous etc) On a donc ne=O(nv). 23 Computational Geometry Line intersections Performance en mémoire de l'algorithme T stocke au plus n segments , dans un arbre binaire → O(n) La file F stocke au pire n +I événements → O(n + I) Au final, M=O(n+I) Si I = O(n²) , c'est trop peu efficace. Si l'on veut traiter les intersection les unes après les autres (sans stockage), c'est catastrophique. Faire mieux est possible : Ne faire figurer dans F que les événements (intersections) dont les segments sont adjacents dans T. Donc, dès que deux segments ne sont plus adjacents, il faut supprimer l'événement correspondant dans F. Un événement est susceptible d'être supprimé/réinséré plusieurs fois avant d'être effectivement traité. Toutefois, cela n'arrive jamais plus de n fois en tout... donc globalement T=O((n+I) log n) La file F ne contient donc plus que O(n) élements. 24 Computational Geometry Line intersections En bref, Il est possible de calculer les intersections en un temps T=O((n+I) log n) et une place mémoire M=O(n) Cet algorithme date de 1979 (avec une modification ultérieure pour garder la mémoire en O(n)) J. L. Bentley and T. A. Ottmann , Algorithms for reporting and counting geometric intersections, IEEE Trans. Comput., C-28:643–647, 1979 Est-ce optimal ? Non... cas ou I=O(n²) : T=O(n² log n) , or on peut y arriver en O(n²) !!! La borne inférieure théorique est T=Ω(n log n +k) – et il existe un algorithme déterministe qui réalise cela (seulement) depuis 1995 I. J. Balaban. An optimal algorithm for finding segment intersections. In Proc. 11th Annu. ACM Sympos. Comput. Geom., pages 211–219, 1995. 25 Computational Geometry Line intersections Robustesse ? Tel quel ; algorithme non robuste à cause du calcul des intersections fait en précision finie... Il est possible que le calcul (imprécis) d'une intersection donne un point légèrement à gauche de l , mais que ce point n'ait pas été traité auparavant (n'a jamais figuré dans F.) Conséquence, l'intersection n'est pas reportée... l ε 2 kε 26 Computational Geometry Line intersections Solutions pour la robustesse Travailler avec des données en entrée sous forme d'entiers, et calculer les intersection exactes sous forme de nombres rationnels Lent / réducteur ! Augmenter la précision des calculs Une implémentation naïve (i.e. telle quelle) de l'algorithme de Bentley et Ottmann impose des calculs sur 5n bits pour un résultat exact sur n bits Boissonat & Preparata ont montré que l'on peut parvenir à faire les calculs sur 2n bits pour la même précision finale de n bits. Cf . Boissonat, J.-D.; Preparata, F. P. (2000), Robust plane sweep for intersecting segments, SIAM Journal on Computing 29 (5): 1401–1421 27 Computational Geometry Numerical errors Numerical errors Floating point calculations are (most of the time) inaccurate Analysis of the rounding done during operations in floating point : x⊖ y= x− y 1 1 , ∣ 1∣≤2 x⊕ y= x y 1 2 , ∣ 2∣≤2 x⊗ y= xy1 3 , ∣ 3∣≤ Mathematically equivalent calculations but expressed differently give distinct results An example with x 2 − y 2 = x y x− y 28 Computational Geometry Numerical errors Error made with the expression x y x− y x⊕ y⊗ x⊖ y = x− y 1 1 x y1 2 1 3 = x y x− y 1 1 2 3 1 2 2 3 1 3 1 2 3 ≈ 5 No catastrophic increase of the relative error Error made with the expression x 2− y2 = [ x 2 (1+ δ1 )− y 2 (1+ δ 2 )](1+ δ3 ) = (( x 2− y 2 )(1+ δ 1)+ (δ1−δ 2 ) y 2 )(1+ δ 3 ) 2 2 2 2 = (( x − y )(1+ δ1+ δ3+ (δ1−δ2 ) y + δ1 δ3 + (δ1 −δ 2 ) y δ 3 )) When x is close to y, the error can be of the order of magnitude of the calculated result... ( x⊗ x)⊖( y⊗ y) 29 Computational Geometry Numerical errors Some useful rules (not a comprehensive list !) Prefer x y x− y to x2− y2 Lagrange form more accurate than horner's scheme … E. g. sum of many terms Naive algorithm : N S =∑ X [ j ] j=1 S=0; for (j=1;j<=N;j++){ S=S+X[j] ; } return S ; involves an error ≈ N Kahan's summation algorithm S=X[1];C=0 for (j=2;j<=N;j++) { Y=X[j]-C; T=S+Y; C=(T-S)-Y; S=T } return S ; involves an error ≈2 30 Computational Geometry Numerical errors Example of catastrophic rounding ymax Computation of an integral : ∫ S= nx*ny samples 2 f ( x , y)dxdy with f (x , y)=x + y 2 Ω nx−1 ny−1 S≈ ∑ i=0 ∑ f x i , y j det J ymin j=0 dx= x max − x min / nx dy= y max − y min /ny x i = x min i dxdx / 2 y j = y min j dydy /2 det J =dx dy xmin y xmax x 31 Computational Geometry Numerical errors Computations made with the following parameters: xmin= ymin= 0.0 ; xmax= ymax= 1.0 ; nx = ny = 10, Sexact=2/3 1) Single precision floating point numbers 2) Double precision floating point numbers 3) Quad precision floating point numbers 4) Single precision floating points numbers with Kahan's summation algorithm bechet@yakusa:floating_error$ ./test 10 1) sum (float )=0.66500002145767211914 2) sum (double )=0.66500000000000025757 3) sum (ldouble)=0.66499999999999999997 4) sum (kahan )=0.66499999999999999997 Note : Program should be compiled without optimization ! 32 Computational Geometry Numerical errors bechet@yakusa:floating_error$ ./test 100 1) sum (float )=0.66664981842041015625 2) sum (double )=0.66665000000000051994 3) sum (ldouble)=0.66665000000000000093 4) sum (kahan )=0.66664993762969970703 bechet@yakusa:floating_error$ ./test 1000 1) sum (float )=0.66668075323104858398 2) sum (double )=0.66666649999999805232 3) sum (ldouble)=0.66666649999999999982 4) sum (kahan )=0.66666668653488159180 33 Computational Geometry Numerical errors bechet@yakusa:floating_error$ ./test 10000 1) sum (float )=0.36836880445480346680 2) sum (double )=0.66666666499985449690 3) sum (ldouble)=0.66666666499999997623 4) sum (kahan )=0.66666656732559204102 bechet@yakusa:floating_error$ ./test 100000 1) sum (float )=0.00390625000000000000 2) sum (double )=0.66666666665538221181 3) sum (ldouble)=0.66666666665000055245 4) sum (kahan )=0.66666662693023681641 Compensated summation algorithm coming from : William Kahan. Further remarks on reducing truncation errors. Comm. ACM, 8(1):40,1965. 34 Computational Geometry Numerical errors y=p(x)=(1-x)n for x=1.333 and 2<n<41 S. Graillat, Ph. Langlois, N. Louvet Compensated Horner Scheme Research Report RR2005-04, LP2A, University of Perpignan, France, july 2005 35 Computational Geometry Numerical errors Definition of the condition number of a numerical expression Ratio of the direct error to the inverse error ∣ y∣ K P , x=lim sup 0 x∈ D ∣ x∣ For a polynomial n inverse error δ x x +δ x under monomial form: ∑i=0 ∣ai∣∣x∣ K P , x= n i a x ∑ ∣ i=0 i ∣ i p x p̃ p y= p( x ) δy direct error ỹ = p ̃ ( x )= y +δ y = p( x +δ x ) 36 Computational Geometry Numerical errors There are various compensated algorithms to carry out calculations on floating point numbers. Ex. Kahan summation, Compensated Horner scheme ... In general, they allow to have similar results as when using internal floating point with a precision twice that of the input data, following by a final rounding. See references available on the course's website for the compensated Horner scheme. 37 Computational Geometry Line intersections Algorithme de balayage Paradigme utile dans un certain nombre de problèmes en CG Intersections de segments Diagrammes de Voronoï Triangulation de polygones M. I. Shamos and D. Hoey. Geometric intersection problems. In Proc. 17th Annu. IEEE Sympos. Found. Comput. Sci., pages 208–215, 1976. D. T. Lee and F. P. Preparata. Location of a point in a planar subdivision and its applications. SIAM J. Comput., 6:594–606, 1977. et référence précédente (J. L. Bentley and T. A. Ottmann) 38 Computational Geometry Line intersections Exercice : Tenter de trouver un algorithme incrémental pour l'intersection de segments ? 39 Computational Geometry Sweeping line paradigm Deux autres exercices Déterminer en T=O(nlogn) les segments (tous disjoints) visibles à partir d'un point. Non visible 40 Computational Geometry Sweeping line paradigm Relier un ensemble de n triangles disjoints Chaque segment relie deux triangles Les segments sont disjoints (pas d'intersection excepté aux extrémités) et ils sont disjoints des bords des triangles (connectés en exactement un point) Donner les événements, les cas qui apparaissent et les actions à mener, les structures de données, et l'invariant de l'algorithme. 41