Avertissement
Cette page est très technique. Elle a d’abord été écrite comme mémorisation personnelle. Elle peut éventuellement intéresser des lecteurs qui souhaiteraient traiter de cette question du régionnement par l’IA. En ce sens elle dégage quelques points importants à prendre en compte.
• Si on veut utiliser l’IA il faudrait peut-être d’abord calculer – mathématiquement – la frontière des parties 2H (rose) et 2H1E (verte), a priori une cubique. Une IA pourrait produire un code plus affiné que celui-ci, mais aussi choisir d’autres options – dont celle suggérée dans cette page, avec un exemple local
ou même faire tout à fait autrement. C’est un thème intéressant à traiter pour tester une IA, et probablement apprendre de cette IA.
L’autre point encore non étudié est cette constatation, largement validé dans toutes les illustrations, que l’intérieur proche du point d’inflexion est une région où il y a trois perpendiculaires hilbertiennes.

________________

Dans cette page, il s’agit de donner quelques éléments utilisés pour finaliser la figure du régionnement vis à vis de l’orthogonalité comme on l’a illustré dans cette page qu’il est conseillé d’avoir parcouru avant de lire cet article : il s’agit essentiellement d’une page d’illustrations, mais qui fait le tour des configurations à aborder.

On poursuit le travail commencé dans l’article présentant les détails sur 1H1E. Cette fois-ci on s’intéresse aux régions 1E – une seule perpendiculaire euclidienne – 1H – une seule perpendiculaire hilbertienne – et 0P – aucune perpendiculaire.

La démarche générale de la figure

Pour une position de la droite \((AB)\), les 6 régions à l’écran. Il en existe toujours 4 : 1E, 1H, 0P, 1H1E.

Les trois régions 2H (rose), 2H1E (verte) et 1H1E (jaune) ont déjà été construite dans les pages précédentes avant celle qui présente les trois dernières 1E, 1H, 0P. On va devoir être plus systématique que ce qui a été fait pour la partie 1H1E.

L’expression-programme au cœur de cette figure renvoie les trois listes de segments La1E, La1H et La0P. Chacune se construit, en général en plusieurs temps car elle peuvent comporter plusieurs parties.

Ainsi la région 1E peut comporter 4 parties, deux passant par les points \(Ph\) et \(Qb\), clairement non bornées, et éventuellement deux autres passant en général par les intersections \(PhQo\) et \(QbPo\) ou leurs correspondants hilbertiens quand un de ces deux points est dans l’ellipse.

De même la région 0P contient toujours deux parties, une passant par \(Ph\) et l’autre par \(Qb\). Seule la région 1H peut ne contenir qu’une seule partie, et c’est alors celle qui traverse l’ellipse en passant par les deux points \(Ph\) et \(Qb\), mais elle contient souvent une seconde partie, généralement autour des points \(PhQb\) – présent ou non à l’écran – et d’un des deux points \(PhQo\) ou \(QbPo\). La région 1H est systématiquement réduite à une seule partie quand l’un de ces deux derniers points est intérieur à l’ellipse.

Variable de redéploiement des listes

Comme déjà vu dans l’article technique consacré au régionnement 1H1E, pour ce qui est des arcs de cercles à l’intérieur de l’ellipse, on dispose de 24 listes préalablement construites (par macro), dont 8 utilisant les points intérieurs à l’ellipse \(Inter_{PhQo}\) et \(Inter_{QbPo}\) ayant d’ailleurs été renommées pour une meilleur lisibilité.

Les trois listes finales La1E, La1H et La0P, concrètement, doivent être des listes de points – même si on les interprète ensuite comme des listes de segments – mais les listes intermédiaires, celles des parties, peuvent être aussi des listes de liste de points, car utilisant soit les listes des arcs de cercles, soit encore les deux listes associées à 2H et 2H1E nommées respectivement expFrRose, et expFrVerte. Pour savoir s’il faut les aplatir ou non, on utilise un booléen de préfixe DL (pour Double Liste) qui vaut 0 si on a une liste de points et 1 si on a une liste de listes. Les principales variables liées à la construction des trois listes finales sont initialisées ainsi :

var Prep1Ep1=[];var Prep1Ep2=[];var Prep1Ep3=[];var Prep1Ep4=[];var Prep1Hp1=[];var Prep1Hp2=[];var Prep0Pp1=[];var Prep0Pp2=[];La1E=[];La1H=[];La0P=[];var DL1Ep1=0;var DL1Ep2=0;var DL1Ep3=0;var DL1Ep4=0;var DL1Hp1=0;var DL1Hp2=0;var DL0Pp1=0;var DL0Pp2=0;

Sur la méthode de construction de ces parties

Soit une configuration donnée pour la droite \((AB)\), on cherche à déterminer quelles sont les parties des différents types dans cette configuration.

On repère différents paramètres significatifs de la configuration, et en fonction de ces paramètres, on a choisi ici de construire les deux parties qui appartiennent à 1H par exemple (de la configuration illustrée précédemment).

Pour la partie passant par les points Ph et Qb
var DL1Hp1=1;var Prep1Hp1=[ListeQbQbo,[QboG,HG,PhoG,Ph],ListePhPh2,[PhQb,Qb]] 

Pour l'autre partie, dans un cadre un peu plus général
var DL1Hp2=0;var Prep1Hp2=[PhQb,((QbPoEcran)&&(QbPo[0]>Qb[0]))?QbPo:Qb2D,((QbPoEcran)&&(QbPo[0]>Qb[0]))?PhoD:Qb2D,((PhQoEcran)&&(PhQo[0]>Qb[0]))?QboD:Ph2D,((PhQoEcran)&&(PhQo[0]>Qb[0]))?PhQo:PhQb]

soit ici, compte tenu des booléens, on construit [PhQb,QbPo,PhoD,Ph2D,PhQb]

Avec une pratique régulière de la figure, on arrive à fortement paramétrer les parties ainsi construites, en fonction de différents paramètres. Mais il y a clairement de nombreux paramètres, en particulier pour gérer comme ci-dessus, la connexion avec les autres parties (ci dessus 0P et 1E) des parties 2H (rose) et 2H1E (verte). C’est parfois simple, comme dans cet exemple

La partie 0P (marron) issue de Ph s'écrit simplement : var Prep0Pp1=[expFrRose,ListePhoPh,ListePhPh2].
La partie 1E (mauve) issue de Ph s'écrit : var Prep1Ep1=[ListePhPho,expFrVerte,[(Tindex<11)?(Qb2D[1]<xMax)?BD:Qb2D:Qb2D,HD,Ph2G,Ph]].

mais parfois cela peut-être moins simple. Ces exemples de code illustrent que, dans cette figure, on a choisi de construire les parties de régionnement, à partir des listes déjà disponibles et des points de la figure, en fonction de la configuration.

Une autre approche pourrait être de repérer préalablement toutes les parties possibles du plan, les nommer, et ensuite simplement de les associer aux parties selon les configuration. On l’a fait deux fois dans notre programmation, dont une sous la forme suivante : une partie peut être de type 1H ou 1E. On commence par la construire dans différentes situations, puis à la fin on déclare que cette partie est une partie de 1H ou une partie de 1E.

var Vers1Hp2ou1Ep3=[];if ((QbPoEcran) && (QbPo[0]>Ph[0])) {var Vers1Hp2ou1Ep3=[PhQb,PhQo,QboD,PhoD,QbPo]} else {if ((PhQoEcran)&&(PhQo[0]>Qbo[0])) {var Vers1Hp2ou1Ep3=(PhQbEcran)?[PhQo,PhQb,Qb2D,HD,QboD,PhQo]:[PhQo,Ph2D,HD,QboD,PhQo]} else {if ((PhQbEcran)&&((PhQoEcran==0)&&(QbPoEcran==0))) {var Vers1Hp2ou1Ep3=[PhQb,Ph2D,BD,HD,Qb2D]}}};if (((PhQo[0]<PhQb[0])&&(PhQbEcran))||((PhQoEcran)&&(PhQbEcran==0))) {var DL1Ep3=0;var Prep1Ep3=Vers1Hp2ou1Ep3} else {var DL1Hp2=0;var Prep1Hp2=Vers1Hp2ou1Ep3};

Deux illustrations de la variable Vers1Hp2ou1Ep3
ci dessus partie Prep1Hp2 car \(PhQo[0]>PhQb[0]\) qu’on décrit généralement par \(PhQo>PhQb\)
ci dessous partie Prep1Ep3 car \(PhQo[0]<PhQb[0]\)

On aurait la même chose avec une pente positive, le point \(PhQo\) étant généralement remplacé par \(QbPo\), comme dans ces illustrations, avec les noms des points en bord d’écran

Autre exemple avec l’alternance de position entre \(QbPo\) et \(PhQb\)

Une autre approche de construction du régionnement serait d’utiliser plus systématiquement cette démarche. Mais il faudrait aussi faire de nombreux tests pour l’affichage final, plus complexes que ceux qui interviennent dans l’exemple présenté. L’option n’a pas été retenue, mais elle reste envisageable

Extrait complet du code pour le cas \(PhQo\) intérieur à l’ellipse

On donne cet exemple car il est simple, compact, sans difficulté. Le point \(PhQo\) peut être à l’intérieur de l’ellipse uniquement si la pente de la droite \((AB)\) est négative. Dans le code général, on traite d’abord la pente négative, et ensuite, pour ce qui nous intéresse ici, le cas où le booléen \(PhQoInHell\) est vrai (le point est à l’intérieur de l’ellipse).

Le code (illustré plus loin)

Pour rappel \(ChProdPh >0\) signifie – globalement, la définition exacte a été précisée dans la l’article technique sur 1H1E – que les extrémités \(Ph_2\) et \(Pho\) sont d’un même côté vis à vis de \(Ph\) (idem pour \(ChProdQb >0\) avec \(Qb, \, Qb_2, \, Qbo\)). Même si cette donnée est importante, elle ne suffit pas, bien entendu, à caractériser une situation même locale, en particulier il faut aussi savoir si ces deux points sont avant ou après \(Ph\), d’où le test \(Pho[0]>Ph[0]\).

// pente neg - PhQoInHell Pho>Ph ChProdPh>0
if (penteAB<0) {if (PhQoInHell) {if (Pho[0]>Ph[0]) {if (ChProdPh>0) {var DL1Hp1=1;var Prep1Hp1=[ListeQbInter1,ListeInter1Ph,(QbPoEcran)?[QbPo,Qb]:[PhoG,BG,Qb2G,Qb]];var DL0Pp1=1;var Prep0Pp1=[ListeQboInter1,ListeInter1Ph,ListePhPho,[PhoD,HD,QboD,Qbo]];var DL1Ep1=1;var Prep1Ep1=[ListePhPho,[PhoD,HG,BG,Ph2G]];};

// pente neg - PhQoInHell Pho>Ph - Indep du signe de ChProdPh car comme Pho>Ph il ne peut être neg

var DL1Ep4=1;var Prep1Ep4=[ListeQboInter1,ListeInter1Ph2,(PhQbEcran)?[PhQb,Qb2D,HD,QboD]:[Ph2D,HD,QboD]];var DL0Pp2=0;var Prep0Pp2=(QbPoEcran)?[PhoG,QbPo,Qb,QboG,BG]:[Qb2G,Qb,QboG,BG];var DL1Ep2=1;if (((PtReb==0)&&(p2H1Esup==0))&&((expFrVerte).length>0)) {var Prep1Ep2=[ListeQbQb2,expFrVerte,[Ph2D,HD,BD,BG,QboG]]} else {var Prep1Ep2=[ListeQbQb2,(PhQbEcran)?[PhQb,Ph2D,HD,BD,BG,QboG]:[Qb2D,HD,BD,BG,QboG]]};if (QbPoEcran) {var DL1Ep3=0;var Prep1Ep3=[Qb2G,QbPo,PhoG,BG]}}//

// PhQoInHell Pho<Ph ChProdPh>0

else {if (ChProdPh>0) {var DL1Ep1=1;var Prep1Ep1=[ListePhPho,[PhoG,BG,HG,(aPoP2<180)?Ph2G[1]>Ph2D[1])?Ph2G:Ph2D:Qb2D,((PhQbEcran)&(PhQb[1]>Ph[1]))?PhQb:Ph]];var DL1Ep2=1;var Prep1Ep2=[ListeQbQb2,[(Qb2G[1]Ph[0]))?[Qb,QboD,HD,PhoD,QbPo]:[Qb,QboD,Qb2D];if ((QbPoEcran)&&(QbPo[0]>Ph[0])) {var DL1Ep3=0;var Prep1Ep3=[QbPo,PhoD,HD,(aQoQ2<180)?(Qb2D[1]>Qb2G[1])?Qb2D:Qb2G:Ph2D,((PhQbEcran)&(PhQb[1]>Ph[1]))?PhQb:QbPo]};var DL1Ep4=1;var Prep1Ep4=[ListeQboInter1,ListeInter1Ph2,[(Ph2G[1]<Ph2D[1])?Ph2G:Ph2D,QboG]];var DL0Pp2=1;var Prep0Pp2=[ListeQboInter1,ListeInter1Ph,ListePhPho,[PhoG,BG,QboG]];var DL1Hp1=1;var Prep1Hp1=[ListeQbInter1,ListeInter1Ph,[QbPo,Qb]]}

// PhQoInHell   Pho<Ph  ChProdPh<0

else {var DL1Ep1=0;var Prep1Ep1=[Ph,PhoD,HG,Ph2G];var DL1Ep2=1;var Prep1Ep2=[ListeQb2Qb,[QboG,BG,BD,Ph2D,PhQb]];if (((expFrVerte).length>0)&&((p2H1Esup==1)&&(PtReb==0))) {var DL1Ep3=1;var Prep1Ep3=[ListeQboInter1,ListeInter1Ph2,expFrVerte,[Qb2D,HD,QboD,Qbo]]} else {var DL1Ep3=1;var Prep1Ep3=[ListeQboInter1,ListeInter1Ph2,[PhQb,Qb2D,HD,QboD,Qbo]]};var DL0Pp1=0;var Prep0Pp1=[Qb,QboG,BG,Qb2G];var DL0Pp2=1;var Prep0Pp2=[ListeQboInter1,ListeInter1Ph,[PhoD,HD,QboD]];var DL1Hp1=1;var Prep1Hp1=[ListeQbInter1,ListeInter1Ph,ListePhPho,[PhoG,BG,Qb2G]];}}}
// Fin PhQoInHell

Illustration des deux premières parties du code

Ci dessus : cas \(ChProdPh>0\) et \(Pho>Ph\) dans le sous cas \(QbPoEcran\) vrai :
il y a une partie Prep1Ep4 et on voit le pied \(He\) de la perpendiculaire euclidienne issue de \(I\)


Ci-dessous, même partie du code dans le sous cas \(QbPoEcran\) faux : la partie Prep1Hp1 s’agrandit
On note aussi une petite partie verte au dessus de
\(PhQb\), soit une partie 2H1E.

Ci-dessous, on place \(I\) dans la partie verte, on voit les deux pieds \(Hh_2\) (proche de \(Ph\)) et \(Hh_3\) des perpendiculaires hilbertiennes et le pied \(He\) de l’euclidienne.

Illustration de la quatrième partie du code (\(Pho < Ph\) et \(ChProdPh<0\))

En déplaçant le point \(A\), naturellement le point \(Pho\) « traverse » \(Ph\), on est alors dans le cas où \(ChProdPh<0\). On voit clairement la différence des constructions des parties Prep1Hp2, Prep1Ep1, Prep0Pp1 par rapport aux deux premières parties.

Illustration de la troisième partie (\(Pho < Ph\) et \(ChProdPh>0\))

Toujours dans le cas de la pente négative, pour avoir à la fois \(Pho<Ph\) et \(ChProdPh>0\), il faut une configuration bien différente, avec Prep1Ep3 qui « entre dans l’ellipse par dessous » comme ici

On a encore Prep0Pp1, issue de \(Ph\), est composée de trois arcs de cercles dans l’ellipse et d’un polygone,
alors que Prep0Pp2 (issue de \(Qb\)) est un simple polygone.

On choisit de s’arrêter ici, la suite est du même type, mais moins simple, et le détailler n’apporterait rien de plus. Les personnes (vraiment très) intéressées regarderont les codes des différentes expressions rendues accessibles dans la figure suivante (à dezipper et à utiliser avec DGPad). Le code principal complet est dans la liste La1H1E0P.