[Résolu]Résoudre une équation à deux inconnues (coniques)

Bonsoir/bonjour à tous,

Je cherche à savoir si il est possible de résoudre une fonction à deux inconnues avec une arduino uno et quelle serait la syntaxe à employer. J'ai cherché (google, le forum...), sans doutes mal, et j'ai trouvé pour seule info ce post programmation cartésienne. - Français - Arduino Forum qui ne répond pas à ma question.

Pour être plus précis l'objectif est de déterminer les coordonnées cartésiennes des deux points d'intersection de deux cercles dont je connais les rayons (puis à terme le point d'intersection de 3 cercles choisis pour qu'il existe).

Donc ça me donnerait ce système de deux équations
(x-a)²+(y-b)²=r1
(x-c)²+(y-d)²=r2

... que je cherche à résoudre pour déterminer les couples (x,y) coordonnées des points d'intersection.

Si cela n'est pas possible j'ai aussi pensé à procéder par approximations en déterminant (x1,y1) du cercle 1 pour un angle alpha donné grâce aux fonctions trigonométriques, que je compare avec toutes les valeurs possibles (x2,y2) (toujours déterminées grâce à la trigo), puis je recommence en incrémentant alpha si aucun couple ne concorde... mais j'ai peur que cela soit une usine à gaz.

Si vous avez quelques pistes de réflexion je suis preneur!

Merci d'avance pour vos réponses :slight_smile:

Il y a deux solutions (je te conseille un copier-coller :wink: ).
La première:

x = -(1/2)(-a^4+2a^3c-a^2b^2+2a^2bd-a^2d^2-2ac^3+b^2c^2-2bc^2d+c^4+c^2d^2+a^2r1-a^2r2-2acr1+2acr2+c^2r1-c^2r2+sqrt(-(a-c)^2(a^4-4a^3c+2a^2b^2-4a^2bd+6a^2c^2+2a^2d^2-4ab^2c+8abcd-4ac^3-4acd^2+b^4-4b^3d+2b^2c^2+6b^2d^2-4bc^2d-4bd^3+c^4+2c^2d^2+d^4-2a^2r1-2a^2r2+4acr1+4acr2-2b^2r1-2b^2r2+4bdr1+4bdr2-2c^2r1-2c^2r2-2d^2r1-2d^2r2+r1^2-2r1r2+r2^2))b-sqrt(-(a-c)^2(a^4-4a^3c+2a^2b^2-4a^2bd+6a^2c^2+2a^2d^2-4ab^2c+8abcd-4ac^3-4acd^2+b^4-4b^3d+2b^2c^2+6b^2d^2-4bc^2d-4bd^3+c^4+2c^2d^2+d^4-2a^2r1-2a^2r2+4acr1+4acr2-2b^2r1-2b^2r2+4bdr1+4bdr2-2c^2r1-2c^2r2-2d^2r1-2d^2r2+r1^2-2r1r2+r2^2))d)/((a^2-2ac+b^2-2bd+c^2+d^2)(a-c))

y = (1/2)(a^2b+a^2d-2abc-2acd+b^3-b^2d+bc^2-bd^2+c^2d+d^3-br1+br2+dr1-dr2+sqrt(-(a-c)^2(a^4-4a^3c+2a^2b^2-4a^2bd+6a^2c^2+2a^2d^2-4ab^2c+8abcd-4ac^3-4acd^2+b^4-4b^3d+2b^2c^2+6b^2d^2-4bc^2d-4bd^3+c^4+2c^2d^2+d^4-2a^2r1-2a^2r2+4acr1+4acr2-2b^2r1-2b^2r2+4bdr1+4bdr2-2c^2r1-2c^2r2-2d^2r1-2d^2r2+r1^2-2r1r2+r2^2)))/(a^2-2ac+b^2-2bd+c^2+d^2)

La deuxième:

x = (1/2)(a^4-2a^3c+a^2b^2-2a^2bd+a^2d^2+2ac^3-b^2c^2+2bc^2d-c^4-c^2d^2-a^2r1+a^2r2+2acr1-2acr2-c^2r1+c^2r2+sqrt(-(a-c)^2(a^4-4a^3c+2a^2b^2-4a^2bd+6a^2c^2+2a^2d^2-4ab^2c+8abcd-4ac^3-4acd^2+b^4-4b^3d+2b^2c^2+6b^2d^2-4bc^2d-4bd^3+c^4+2c^2d^2+d^4-2a^2r1-2a^2r2+4acr1+4acr2-2b^2r1-2b^2r2+4bdr1+4bdr2-2c^2r1-2c^2r2-2d^2r1-2d^2r2+r1^2-2r1r2+r2^2))b-sqrt(-(a-c)^2(a^4-4a^3c+2a^2b^2-4a^2bd+6a^2c^2+2a^2d^2-4ab^2c+8abcd-4ac^3-4acd^2+b^4-4b^3d+2b^2c^2+6b^2d^2-4bc^2d-4bd^3+c^4+2c^2d^2+d^4-2a^2r1-2a^2r2+4acr1+4acr2-2b^2r1-2b^2r2+4bdr1+4bdr2-2c^2r1-2c^2r2-2d^2r1-2d^2r2+r1^2-2r1r2+r2^2))d)/((a^2-2ac+b^2-2bd+c^2+d^2)(a-c))

y = -(1/2)(-a^2b-a^2d+2abc+2acd-b^3+b^2d-bc^2+bd^2-c^2d-d^3+br1-br2-dr1+dr2+sqrt(-(a-c)^2(a^4-4a^3c+2a^2b^2-4a^2bd+6a^2c^2+2a^2d^2-4ab^2c+8abcd-4ac^3-4acd^2+b^4-4b^3d+2b^2c^2+6b^2d^2-4bc^2d-4bd^3+c^4+2c^2d^2+d^4-2a^2r1-2a^2r2+4acr1+4acr2-2b^2r1-2b^2r2+4bdr1+4bdr2-2c^2r1-2c^2r2-2d^2r1-2d^2r2+r1^2-2r1r2+r2^2)))/(a^2-2ac+b^2-2bd+c^2+d^2)

Bonsoir,

Wiiik:
Donc ça me donnerait ce système de deux équations
(x-a)²+(y-b)²=r1
(x-c)²+(y-d)²=r2

Il existe plusieurs méthodes pour résoudre un système de 2 équations à 2 inconnues.
Le problème n’est pas la résolution mais la lenteur de la nono lorsqu’il s’agit d’utiliser des float.
Que recherches-tu exactement (la méthode de résolution ou un algorithme numérique) ?
@+
[edit] : Intersection de deux cercles

Bonsoir,

3Sigma:
Il y a deux solutions (je te conseille un copier-coller :wink: ).
........................................................

C'est la super forme 3Sigma :sweat_smile:

Ouais, demain soir ça va donner !

En version C optimisé, ça donne ça:

Première solution:

t1 = a - c;
t2 = c * c;
t3 = b * b;
t4 = a * a;
t5 = pow(t4, 2);
t6 = a * (a - 2 * c);
t7 = c * a;
t8 = d * d;
t6 = pow(t1, 2) * ((-2 * t8 - 2 * t4 - 2 * t3 - 2 * t2) * r1 + (-2 * t4 - 2 * t3 - 2 * t2) * r2 + t2 * (-4 * t7 + 2 * t8 + 2 * t3) + 6 * t3 * t8 + (4 * a * (r1 - t4) + (6 * t4 + t2) * c) * c + (b * ((-4 * c + 8 * a) * c + 4 * r1 + 4 * r2 - 4 * t3 - 4 * t4) + ((d - 4 * b) * d - 2 * r2 + 2 * t6) * d) * d + r1 * r1 + r2 * r2 + (-2 * r1 + 4 * t7) * r2 + (int) pow((double) t3, (double) 2) + t5 + 2 * t6 * t3);
t9 = b - d;
t10 = (-d + 2 * b) * d;
t8 = -2 * b * d + t2 + t3 + t4 - 2 * t7 + t8;
t11 = b + d;
t8 = 1 / t8;
t1 = 0.1e1 / t1;
x = -(2 * a * t4 * c + t2 * (r1 - r2 - t10 + t3 + t2) + t4 * (r1 - r2 + t10 - t3) + t9 * sqrt(-t6) - t5 + t7 * (-2 * r1 + 2 * r2 - 2 * t2)) * t8 * t1 / 2;
y = (b * t3 + (-d * t9 - t3) * d - r1 * t9 + r2 * t9 + t2 * t11 + t4 * t11 + sqrt(-t6) - 2 * t7 * t11) * t8 / 2;

Deuxième solution:

t1 = a - c;
t2 = c * c;
t3 = b * b;
t4 = a * a;
t5 = a * (a - 2 * c);
t6 = c * a;
t7 = d * d;
t5 = pow(t1, 2) * ((-2 * t4 - 2 * t7 - 2 * t2 - 2 * t3) * r1 + (-2 * t4 - 2 * t2 - 2 * t3) * r2 + t2 * (-4 * t6 + 2 * t7 + 2 * t3) + 6 * t3 * t7 + (4 * a * (r1 - t4) + (6 * t4 + t2) * c) * c + (b * ((-4 * c + 8 * a) * c + 4 * r1 + 4 * r2 - 4 * t3 - 4 * t4) + ((d - 4 * b) * d - 2 * r2 + 2 * t5) * d) * d + r1 * r1 + r2 * r2 + (-2 * r1 + 4 * t6) * r2 + (int) pow((double) t3, (double) 2) + (int) pow((double) t4, (double) 2) + 2 * t5 * t3);
t8 = b - d;
t9 = (-d + 2 * b) * d;
t7 = -2 * b * d + t2 + t3 + t4 - 2 * t6 + t7;
t10 = -b - d;
t7 = 1 / t7;
t1 = 0.1e1 / t1;
x = (2 * a * c * t2 - (int) pow((double) t2, (double) 2) + t2 * (-r1 + r2 + t9 - t3) + t4 * (-r1 + r2 - t9 + t4 + t3) + t8 * sqrt(-t5) + t6 * (2 * r1 - 2 * r2 - 2 * t4)) * t7 * t1 / 2;
y = -(-b * t3 + (d * t8 + t3) * d + r1 * t8 - r2 * t8 + t2 * t10 + t4 * t10 + sqrt(-t5) - 2 * t6 * t10) * t7 / 2;

Bonsoir,

Merci pour vos réponses.

Mon objectif est de déterminer le point d'intersection de 3 cercles pour trianguler la position d'un robot équipé d'une arduino. Donc je cherche plutôt à développer un algorithme qui soit rapide et répétable pour l'arduino :slight_smile:

3Sigma:
Il y a deux solutions (je te conseille un copier-coller :wink: ).

D'où viennent ces solutions?

Re,
Je trouve que la réduction du système d'équations à la résolution d'une équation du deuxième degré plus simple et plus rapide.
Mais ce ne sont pas les méthodes qui manquent.
Perso, j'aime bien de temps en temps la méthode des tâtonnements successifs :grin:
@+

Wiiik:
D'où viennent ces solutions?

Maple. Je n'ai aucun mérite :wink:

3Sigma:

Wiiik:
D'où viennent ces solutions?

Maple. Je n'ai aucun mérite :wink:

icare:
Re,
Je trouve que la réduction du système d'équations à la résolution d'une équation du deuxième degré plus simple et plus rapide.
Mais ce ne sont pas les méthodes qui manquent.
Perso, j'aime bien de temps en temps la méthode des tâtonnements successifs :grin:
@+

Mince, en vous lisant tous les deux je m'en veux de ne pas y avoir pensé, ça me donne l'impression de ne pas avoir réfléchi...
En tous cas merci pour votre rapidité :). Me reste à bien comprendre la réduction et à tester les 3 méthodes, ça serait intéressant de voir comment elles se défendent et de les comparer.

Edit: mis en résolu

Re,

Wiiik:
Me reste à bien comprendre la réduction et à tester les 3 méthodes, ça serait intéressant de voir comment elles se défendent et de les comparer.
Edit: mis en résolu

Tu nous mettras le résultat de la comparaison.
Pour mettre en résolu : tu te places sur ton premier message et tu insères ton [RESOLU] dans le Subject

Bonsoir,

Je viens seulement de trouver le temps de reprendre ce projet. Voici les premiers résultats:

-méthode “maple”: le résultat n’est pas bon, la faute à un signe moins sous la racine mais je n’ai pas encore trouvé son origine.

-méthode de la réduction du système avec résolution d’un trinôme: ici tout est bon, ça fonctionne très bien. Il faut en moyenne 1600 microsecondes à mon arduino uno pour faire tomber le résultat.

-méthode “par tâtonnements successifs”. Ici mon programme ne fonctionne pas correctement mais on peut déjà voir qu’il faut plusieurs longues secondes pour faire parcourir l’intervalle [0, 2Pi] à téta. Voici le brouillon de mon code, mais ça faisait longtemps que je n’avais pas pratiqué, donc j’ai peur que ce ne soit pas beau à voir :slight_smile:

const float pi=3.14;
const float p=0.05; //precision
const float i=0.01; // iteration
float teta =0;
float alpha =0;
float x0=8;
float y0=6;
float R0=5;
float R1=3;
float x1=3;
float y1=2;
float X0=0;
float Y0=0;
float X1=0;
float Y1=0;

void setup() {

Serial.begin(9600);
}

void loop() 
{
  Serial.println(p);
  Serial.println(i);
while (teta<=2*pi)
{

  X0=x0+R0*cos(teta);
  Y0=y0+R0*sin(teta);

  while (alpha<=2*pi)
  {
    X1=x1+R1*cos(alpha);
    Y1=y1+R1*sin(alpha);
    if ((X0-p)<=X1 && X1<=(X0+p) && (Y0-p)<=Y1 && Y1<=(Y0+p))
    {
      break;
    }
    alpha=alpha+i;
   }
if ((X0-p)<=X1 && X1<=(X0+p) && (Y0-p)<=Y1 && Y1<=(Y0+p))
  {
    break;
    }
  teta=teta+i;
  Serial.println(teta,5);
 
}
Serial.println(X0-p);
Serial.println(teta,5);
  Serial.println(alpha,5);
  Serial.println("Coord");
  Serial.println(X1,5);
  Serial.println(Y1,5);
  Serial.println(X0,5);
  Serial.println(Y0,5);
  delay(10000);
}

Salut,

Dans tes if a 4 conditions, tu peux simplifier avec abs(x0-x1) <= p et abs(y0-y1) <=p

Ensuite je ferais :
If ( abs(x0-x1) <= p) {
If ( abs(y0-y1) <=p) break;
}

Comme ça, si le test n’est pas vérifié sur les x, on ne le fait pas sur les y…

Ensuite tu peux commencer par chercher d’abord avec une précision faible et un i plus grand … Et affiner ensuite sans refaire le tour complet …

Je ne suis pas un pro des compilateurs, mais au lieu de mettre 2*pi dans les while je mettrai directement 6,28 …

B83s:
Je ne suis pas un pro des compilateurs, mais au lieu de mettre 2*pi dans les while je mettrai directement 6,28 …

Normalement les constantes sont déterminées au moment de la compilation donc cela ne devrait rien changer.

Merci, je vais essayer :slight_smile: