Calculer diagonale rectangle sans Pythagore ?

Bonjour à tous
Je sollicite aujourd'hui vos compétences pour m'aider à résoudre un problème atypique qui je l'espère n'est pas insoluble.

Je suis développeur web, cela fait une (grosse) dizaine d'années que j'ai terminé mon cursus scolaire et mes connaissances en mathématiques se sont quelque peu évaporées.

Quelques explications concernant la maquette ci-dessous :
  • Le rectangle rouge représente un écran d'ordinateur (ou plutôt la fenêtre de votre navigateur web).
  • Le cercle vert représente l'image d'arrière-plan d'un site Internet. Elle est circulaire parce que je souhaite lui appliquer un effet de rotation, de sorte à ce que l'image recouvre toujours entièrement la surface de l'écran, peu importe son angle de rotation.

Existe-t-il un moyen de calculer le diamètre (D) du cercle, sachant que :
  • Je connais la longueur (L) et la largeur (l) du rectangle. Cependant ce ne sont pas des nombres réels (je ne suis pas sûr du vocabulaire, je veux dire par là que ce ne sont pas des entiers ou des nombres décimaux mais des constantes que je peux utiliser).
  • Je ne peux pas calculer la racine carrée, le sinus ou le cosinus de mes constantes L et l.

En gros, le problème revient à trouver une relation entre L, l et D en employant uniquement additions, soustractions, multiplications et/ou divisions.

J'ai volontairement simplifié certains aspects du problème pour ne pas apporter de confusion supplémentaire. Je préciserai au fur et à mesure si besoin.

Merci pour votre aide.78986

Réponses

  • La valeur cherchée est : $D = \sqrt{L²+\ell²}$.

    Bien sûr, on a la relation : $D^2 = L²+\ell²$ ou encore $D\times D = L\times L+\ell \times \ell$

    Peut-on approcher la racine carrée par un algorithme (une petite boucle) qui utilise les opérations autorisées dans ce que tu veux faire ? Voir ici et en plus c'est une méthode qui converge vite.
  • Bonjour,

    Mazette !

    Tu appliques la formule suivante avec $\ell \leq L$ qui est une bonne approximation si une longueur est bien plus petite que l'autre :
    $\displaystyle D = L \Big(1+{1 \over 2} \big({\ell\over L}\big)^2 -{1 \over 8} \big({\ell\over L}\big)^4 + {1 \over 16} \big({\ell\over L}\big)^6 + \ldots\Big).$
    Si elles sont proches, tu utilises $D=1.414 (\ell+L)/2$
  • Merci à tous les deux pour vos réponses. :-)

    Je creuserai tout cela en détails demain, en attendant :

    @Dom
    Je ne peux pas faire de boucle, il faut trouver la valeur de D en 1 opération.

    @YvesM
    • Je ne peux pas calculer les 2, 4, etc. :-(
    • Le truc, c'est que l'on peut avoir l <= L, mais aussi l >= L (un écran de téléphone portable) !

    Ce n'est pas très grave si on ne trouve pas la valeur exacte de D, il faut par contre que la valeur trouvée ne soit pas inférieure à la valeur réelle.
  • Peux-tu donner un encadrement des valeurs possibles de $\ell$ et $L$ ?
  • Tu peux utiliser la manière de John Carmack pour calculer rapidement une racine carrée. https://fr.wikipedia.org/wiki/John_Carmack#Un_programmeur_astucieux
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • L et l sont des constantes (ou des variables) que je peux utiliser dans une opération mathématique, mais ce ne sont pas des nombres.

    Ils symbolisent la longueur et la largeur (hauteur) d'une fenêtre d'un navigateur web. Il existe des dizaines et des dizaines de résolutions d'écran différentes en fonction des supports (ordinateur, tablette, téléphone). Mais sur un ordinateur un utilisateur peut également redimensionner sa fenêtre comme il le souhaite, donc on peut avoir l < L, l = L, l > L, mais aussi l << L (très inférieur à), l >> (très supérieur à).
  • En utilisant l'approximation ($\ell<L$) : $\displaystyle D = L \Big(1+{1 \over 2} \big({\ell\over L}\big)^2\Big)$ si je ne fais pas d'erreur on ne se trompe que d'environ un dixième.

    On peut écrire : $D = L+\ell \times \ell / L / 2$
  • Hey c'est peut-être pas mal ça ! Ça fonctionne quand l = L et l > L ?

    Je teste demain, je mettrai une démo accessible en ligne pour que vous puissiez regarder par vous-mêmes.

    @nicolas.patrois
    Le langage que j'utilise n'est pas un langage de programmation. Je ne peux donc pas effectuer des opérations multiples, des assignations de variables, des calculs complexes etc.

    Merci !
  • @Hermer, en quel langage programmés-tu ou quel programme utilisés tu? Je suis étonnée que les opérations ne sont pas disponible.
  • 1) C'est préférable pour $\ell < L$.

    En gros, la théorie dit que c'est "bien" quand $\dfrac{\ell}{L}<1$.
    Pour le cas de l'égalité, c'est encore assez "bien".

    Je rectifie : l'erreur n'est pas un dixième mais $L\times 0,1$, pardon ça change quand même la donne...
    En tous les cas, on peut te donner une formule plus précise (celle de @YvesM est meilleure) et s'arranger pour que les opérations utilisées soient celles que tu cites.

    2) Ne peut-on pas non plus effectuer un test pour renverser le calcul lorsque $L< \ell$ ?

    C'est intrigant même si je ne m'y connais que trop peu.
  • @vorobichek
    Je cherche ici une solution avec le langage CSS. C'est le langage qui est utilisé pour la mise en page et la mise en forme des pages web, ce n'est pas un langage de programmation. Il intègre une fonction calc() pour effectuer des opérations mathématiques, mais elle est extrêmement limitée (addition, soustraction, multiplication et divison). Ce que j'appelle l et L dans mon exemple sont en fait des unités relatives aux dimensions de l'écran (vw et vh).
  • @Dom
    Je peux effectuer 2 opérations différentes, quand l < L et l > L. Par contre je ne peux pas cibler l = L, je suppose que le navigateur prendra l'une ou l'autre, mais en pratique cela n'arrivera jamais (une fenêtre de navigateur carrée).

    Quelle serait la formule à utiliser lorsque l > L ?
  • Et bien, la même en échangeant les rôles de $\ell$ et $L$.

    Explicitement : Si $\ell > L$, $D = \ell+L \times L / \ell / 2$
  • Une approximation avec moins de 0.2% d'erreur relative :

    Si $\ell<L$ : poser $a=\dfrac{\ell^2}{L^2}$. On a $D\simeq L\times \dfrac{a^2+8a+8}{4a+8}$.

    Si $\ell\geqslant L$ : poser $a=\dfrac{L^2}{\ell^2}$. On a $D\simeq \ell\times \dfrac{a^2+8a+8}{4a+8}$.
  • Un autre test : j'ai choisi la tangente en $0,5$ et j'ai arrondi les coefficients.

    C'est très arbitraire mais ça donne aussi une approximation d'au plus $L\times 0,02$.

    $D\simeq 0,41\times \ell \times \ell \div L + L\times 1,02$
  • Bon... Je suis très déçu. Il apparait suite à de nombreux tests que je n'ai pas la possibilité de multiplier ou diviser les constantes L et l entre elles. Ce qui rend à mon avis le problème impossible à résoudre.

    La seule opération exploitable est donc celle de YvesM : D=1.414(l+L)/2
    Mais comme il l'a expliqué, cela ne convient pas lorsque les valeurs de l et L sont éloignées.

    Vous pouvez tester le rendu ici (attention, cela ne fonctionnera qu'avec un navigateur Firefox, Chrome ou Edge, pas sur Internet Explorer) :
    http://jsbin.com/jinotoxiqa/edit?css,output

    Si vous redimensionnez la prévisualisation (ou la fenêtre de votre navigateur), vous constaterez que plus les tailles des côtés sont éloignées, moins le cercle s'adapte aux dimensions du rectangle.

    Il faudrait trouver un coefficient d'agrandissement du cercle par rapport au rectangle, en sachant que je peux aussi travailler avec des pourcentages (ex. D = 110% de L), mais pas sûr que cela soit possible et/ou fiable...
  • On peut aussi améliorer la méthode de YvesM. Si $\ell\leqslant L$, on a une valeur approchée $D\simeq aL+b\ell$ en se reportant sur le tableau ci-dessous.
    Condition	         a	  b
    Si 0,0L < l =< 0,1L	0,999	0,050
    Si 0,1L < l =< 0,2L	0,989	0,148
    Si 0,2L < l =< 0,3L	0,970	0,243
    Si 0,3L < l =< 0,4L 	0,944	0,330
    Si 0,4L < l =< 0,5L 	0,912	0,410
    Si 0,5L < l =< 0,6L 	0,876	0,482
    Si 0,6L < l =< 0,7L 	0,838	0,545
    Si 0,7L < l =< 0,8L 	0,800	0,600
    Si 0,8L < l =< 0,9L 	0,762	0,648
    Si 0,9L < l =< 1,0L 	0,725	0,689
    

    Exemple : si $L=1$, $\ell=0,8$ alors $a=0,8$, $b=0,6$ et $aL+b\ell=1,28$ alors que $\sqrt{L^2+\ell^2}\simeq 1,2806$, l'erreur est de moins de 1 pour mille.

    Dans le cas où $\ell\geqslant L$, on échange les rôles de $\ell$ et $L$.
  • Les seules conditions que je peux mettre en place sont L > l et L < l.

    Si on oublie la recherche d'une valeur approchée de D, est-ce qu'une opération simple est possible garantissant une valeur de D raisonnablement supérieure à L (dans le cas où L > l), et D raisonnablement supérieure à l ( quant l > L).

    Il ne faut pas que D < L ou D < l, si mon cercle est "un peu" plus grand que mon rectangle, ça me va !
  • On peut prendre $D\simeq L+0.414\ell$ (si $\ell\leqslant L$) et $D\simeq \ell +0.414 L$ (si $L\leqslant \ell$) mais l'erreur relative atteint 8% lorsque $\ell/L=0.4$.
  • Merci JLT, ça fonctionne parfaitement !

    En simulation réduite, cela donne ça :
    http://jsbin.com/mitejanisi/1/edit?css,output

    Et en simulation pleine page :
    http://jsbin.com/yoqupuloku/edit?output

    (Pour rappel il vous faut une version récente de Firefox, Chrome ou Edge pour que les démos fonctionnent. En redimensionnant la fenêtre de votre navigateur, vous constaterez que l'image recouvre toujours entièrement la zone de prévisualisation, ce qui correspond bien à l'effet recherché).

    Il me reste à peaufiner l'effet de rotation, la taille et l'optimisation des images, mais ça c'est mon boulot. :-)

    Merci à tous pour votre aide, je vous souhaite une bonne continuation (et n'hésiterai pas à repasser pour un autre problème tordu).
Connectez-vous ou Inscrivez-vous pour répondre.