Convexe
qui réalise le
calcul incrémental de l'enveloppe convexe.
Les sommets de l'enveloppes sont dans le champ cvx sous forme
d'une liste bouclée de points.
Cette structure de donnée délicate à manipulér est ici indiquée.
En effet, une telle liste ressemble fortement aux dessins des
enveloppes : des points reliés par des flèches.
class Convexe { PointList cvx ; // Liste des sommets. Attention, c'est une liste bouclée // Travail sur l'enveloppe convexe. // Renvoie un entier r // - r < 0 -> q est à droite du vecteur p1 p2 // - r > 0 -> q est à gauche du vecteur p1 p2 // - r == 0 -> q p1 p2 alignés static private int det(PointList q, PointList p1, PointList p2) { int r = (q.y - p1.y) * (p2.x - p1.x) - (q.x - p1.x) * (p2.y - p1.y) ; return r ; } // Fabrication d'un triangle comme liste bouclée de trois points static private PointList triangle (PointList p1, PointList p2, PointList p3) { PointList r3 = new PointList(p3.x, p3.y, null) ; PointList r2 = new PointList(p2.x, p2.y, r3) ; PointList r1 = new PointList(p1.x, p1.y, r2) ; r3.next = r1 ; return r1 ; } // Étendre l'enveloppe convexe (liste bouclée cvx) // Le point ajouté est le premier de l'argument p // etendre renvoie un booléen, qui indique un changement de l'enveloppe. boolean etendre(PointList p) { if (cvx == null) { PointList p1 = p ; if (p1.next == null) return false ; PointList p2 = p1.next ; if (p2.next == null) return false ; PointList p3 = p2.next ; if (det(p1, p2, p3) < 0) { cvx = triangle(p1,p2,p3) ; } else { cvx = triangle(p1,p3,p2) ; } return true ; } else { PointList first = null , last = null ; PointList q ; int prev = NONE ; int edge ; // Recherche des transitions entre ombre et lumière q = cvx ; do { if (det(p, q, q.next) >= 0) { edge = LIGHT ; if (prev == SHADOW) first = q ; } else { edge = SHADOW ; if (prev == LIGHT) last = q ; } prev = edge ; q = q.next ; } while (q != cvx) ; // Examen de l'arc issu du premier point if (det(p, q, q.next) >= 0) { if (prev == SHADOW) first = q ; } else { if (prev == LIGHT) last = q ; } // Le point ajouté est à l'intérieur if (last == null) return false ; // Suppression des sommets éclairés, et ajout du nouveau point cvx = new PointList(p.x, p.y, last) ; first.next = cvx ; return true ; } } } |