changement indices d'un tableau et affichage tableau

bonjour,
j'ai plusieurs projets en cours et pour deux d'entre eux il faudrait que je renomme les axes X et Y d'un tableau 2D et aussi que je change leurs indices
sa donnerai un truc du genre : (valeurs fictives, je n'ai pas encore relevé les vrais valeurs)

int temp [5] = { 20 , 25 , 30 , 32 , 35 };
int capt [5] = { 900 , 1000 , 1200 , 1700 , 1800 };
int tableau [temp][capt]={
//
//   900///1000//1200//1700//1800
    { 1,    2,    3,    4,    5}  //20
    { 6,    7,    8,    9,   10}  //25
    {11,   12,   13,   14,   15}  //30
    {16,   17,   18,   19,   20}  //32
    {21,   22,   23,   24,   25}  //35
};

bon malheureusement sa marche pas comme sa :smiley:
si quelqu'un pouvait voler a mon secours sa fait parti des dernières choses qui me bloquent pour mon programme.

ensuite le problème numéro 2 est pour mon projet de gestion de chauffage, j'ai fait un super menu de 4 sélections avec plein de sous menus pour régler plein de paramètre mais pour afficher des images j'aurais voulu créer un tableau d'images associé avec un draw.Bitmap (j'utilise adafruit SDD1306) pour afficher l'image pointée par un pointeur sa ferait un truc du genre:

   int tableau [5][5]={

    { image1,    image2,    image3,    image4,    image5}
    { image6,    image7,    image8,    image9,   image10}
    {image11,   image12,   image13,   image14,   image15}
    {image16,   image17,   image18,   image19,   image20}
    {image21,   image22,   image23,   image24,   image25}
};

mais bon la pareil j'ai essayé avec le pointeur du tableau, un pointeur autre, pointer l'adresse directement.... au pire j'ai soit une
erreur ou un message de problème de conversion et au mieux pas d'erreur mais aucun affichage (essais avec une image déclarée dans le scope). quelle fonction utiliser?

ça, ça ne veut rien dire....int tableau [temp][capt]on donne la dimension du tableau en paramètre pas un pointeur sur un tableau...

Rajoutez une virgule après chaque sous tableau et des valeurs de dimension ou laissez le compilateur calculer

int tableau [5][5]={
    { 1,    2,    3,    4,    5}[color=red][b],[/b][/color]  //20
    { 6,    7,    8,    9,   10}[color=red][b],[/b][/color]  //25
    {11,   12,   13,   14,   15}[color=red][b],[/b][/color]  //30
    {16,   17,   18,   19,   20}[color=red][b],[/b][/color]  //32
    {21,   22,   23,   24,   25}  //35
};

justement si je pose la question c'est que je ne sais pas comment l'écrire "korécteman" :wink:

int tableau [temp][capt]

c'était pour pouvoir mettre la suite de chiffre en indice du tableau .
Les virgules manquantes je m'excuse j'ai fait sa un peu énervé aprés plus de 2h de recherches sur
gogole et j'ai baclé le code^^

Ah si je comprends bien vous voudriez que tableau[20][900] contienne 1 ou alors tableau[20][1000] contienne 2?

Ce n'est pas possible de faire cela en C avec un tableau, pas la peine de chercher...

Soit vous utilisez un autre type de structure - mais l'adressage ne sera pas direct - soit la méthode sans doute la plus simple c'est de définir le tableau temp et capt comme vous l'avez fait et tableau comme je l'ai fait et quand vous avez une température T et une valeur de capt C chercher leurs indices dans chacun des 2 tableaux en faisant une bloucle for - par exemple si T vaut 25 alors indiceT = 1, si C vaut 1200 alors indiceC = 2 - et ensuite accédez à tableau[indiceT][indiceC] pour trouver votre valeur.

Rien ne vous empêche de mettre cela dans une fonction tableau(T,C) qui retourne un entier et le tour est joué :slight_smile:

steve59:
justement si je pose la question c'est que je ne sais pas comment l'écrire "korécteman" :wink:

Moi j'ai plutôt l'impression que le problème est mal posé et que du coup tu débouches sur cette solution "alambiquée"

J-M-L:
Ah si je comprends bien vous voudriez que tableau[20][900] contienne 1 ou alors tableau[20][1000] contienne 2?

c'est exactement sa; enfin c'était vu que c'est pas possible :cry:
retourner un entier me pose un peu probléme car mon tableau de base est géré par un dérivé de 3 maps pour avoir une lecture continue meme entre les cases exemple

    { 1,    2,    3,    4,    5}  //20
    { 6,    7,    8,    9,   10}  //25
    {11,   12,   13,   14,   15}  //30
    {16,   17,   18,   19,   20}  //32
    {21,   22,   23,   24,   25}  //35

pour I=0.5 et J=0.5 j'ai menu*[J]= 4*
pour I=3.2 et J=2.8 j'ai menu*[J]= 18.20*
sa me permet d'avoir un tableau trés précis avec un minimum de cases .
donc dans l'idéal la solution serait bien de faire 2 tableau pour "convertir" mes axes
mais il faudrait que autant la lecture capteur (T) et l'indice renvoyé (indiceT) puissent étre flottant.
voila le calcul utilisé pour "lier" les cellules du tableau:
*_ <em>*V = valeur; C= indice case ; x= position pointeur sur l'axe des cases ((Vmax-Vmin)*((x-Cmin)/(Cmac-Cmin)))+Vmin*</em> _*
avec trois calculs comme sa je détermine précisément ma valeur en fonction des 4 points qui l'entoure.
je l'aurait bien fait avec la fonction "map" mais il délire entre les INT et les FLOAT.
sinon avec un tableau de se genre:
*_ <em>*int I [5][2]={{  1,    2,  3,    4,    5},               {900, 1000, 1200, 1700, 1800}};               int J [5][2]={{  1,    2,  3,    4,    5},               { 20,  25,  30,  32,  35}};*</em> _*
serait t-il possible de pointer une case du bas en fonction de la valeur et pouvoir récupérer la valeur
du haut(l'indice) en déplaçant le pointeur d'une case vers le haut?
merci :smiley:

ça, ça ne va pas passer au compilateur, vous déclarez un tableau qui contient 5 tableaux de 2 valeurs et vous déclarez un tableau qui contient 2 tableaux de 5 valeurs.. faut inverser le 5 et le 2.

int I [5][2]={{  1,    2,   3,    4,    5},
              {900, 1000, 1200, 1700, 1800}};
              
int J [5][2]={{  1,    2,   3,    4,    5},
              { 20,   25,  30,   32,   35}};

faut inverser le 5 et le 2.

int I[2][5] = {
  {  1,    2,   3,    4,    5},
  {900, 1000, 1200, 1700, 1800}
};

int J[2][5] = {
  {  1,    2,   3,    4,    5},
  { 20,   25,  30,   32,   35}
};

Sinon - j'ai rien compris à vos explications... :fearful: :fearful: :grin: :grin:

pouvez vous expliquer en français, sans tableau ni code, quelles sont vos entrées et ce que vous essayez d'obtenir ?

les fameux axes X et Y je m'y trompe presque a chaque fois et je corrige après l'erreur lol.
en gros pour l'exemple j'ai :
ENTREE:
-un signal RPM qui va de valeur 900 a valeur 1800. (RPM)
-un signal pression qui va de valeur 20 a valeur 35. (PRESSION)
sortie:
-une sortie fictive qui va de valeur 0 a valeur 25. (S)

je veut obtenir (S) en fonction de (RPM) et (PRESSION).

MAIS:

pour ne pas créer de saccades dans la sortie, je doit pouvoir lire "entre les cases". Ce que fait parfaitement ma petite équation.

[valeur1] [valeur2]
X

[valeur3] [valeur3]

phase 1, calcul en 1 dimension:

-calcule DELTA entre valeur1 et valeur2 (V2-V1), calcule en % la position de X entre valeur1
et valeur2, transforme le % en coefficient pour le multiplier par le delta, additionne le
résultat avec valeur 1. on a valeurA pour la colonne xx,xx

-calcule DELTA entre valeur3 et valeur4 (V4-V3), calcule en % la position de X entre valeur3
et valeur4, transforme le % en coefficient pour le multiplier par le delta, additionne le
résultat avec valeur 3. on a valeurB pour la colonne xx,xx

phase 2, calcul dans la 2éme dimension:

-calcule DELTA entre valeurA et valeurB (VB-VA), calcule en % la position de X entre valeurA
et valeurB, transforme le % en coefficient pour le multiplier par le delta, additionne le
résultat avec valeur A. on a le résultat pour tableau[xx.xx][xx.xx]

j'ai mis le programme de cette fonction en pièce jointe.

donc le problème est donc que je doit pouvoir accéder a mes axes de tableau en fonction
de (RPM) et (PRESSION) mais que ces 2 la sont des floats

désolé si c'est un peu la m**de a comprendre j'ai moi même mis plusieurs jours créer sa et
je suis sur arduino depuis début d'année donc c'est trés brouillon lol

tableau_infini_OK.ino (2.78 KB)

Je n'ai pas trop regardé dans le détail vos maths, mais l'approche de trouver les encadrants me semble presque OK (problème si votre potard est au max nbrHTmoins vaudra 4 et nbrHTplus vaudra 5 qui est en dehors des index autorisés du tableau)

Si vous voulez être régulier évitez map() qui va biaiser vos résultats, vaut mieux la réécrire directement en flottant:

float mapf(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Bon ce que vous dites si on met cela sous forme mathématique, c'est que vous avez une surface dans un espace à 3 dimensions (RPM et PRESSION) en Xinit et Yinit et vous cherchez un Sinit qui est la troisième dimension (Z)

Votre surface est une interpolation car vous connaissez des "points stratégiques" (le S pour un RPM et PRESSION donnés)

ce que vous voulez faire c'est en fonction de Xinit et Yinit donnés, trouver les "points stratégiques" Px et Py encadrants X et Y,

Px1 < Xinit < Px2
Py1 < Yinit < Py2

pour le couple (Px1, Py1) vous connaissez le Z Px1y1
pour le couple (Px1, Py2) vous connaissez le Z Px1y2
pour le couple (Px2, Py1) vous connaissez le Z Px2y1
pour le couple (Px2, Py2) vous connaissez le Z Px2y2

Vous supposez que vous avez une surface dans l'espace reliant les 4 points en coordonnées 3D
(Px1, Py1, Px1y1)
(Px1, Py2, Px1y2)
(Px2, Py1, Px2y1)
(Px2, Py2, Px2y2)

(challenge cependant car il ne faut que 3 points pour définir un plan en 3D, avec 4 vous n'avez plus forcément un plan)

et vous devez trouver l'intersection de la droite (x = Xinit, y = Yinit) et de cette surface

En supposant que votre surface est un plan (sinon il faut définir la tête de la surface reliant vos 4 points dans l'espace) alors c'est un "simple calcul matriciel" (système de 3 équations à 3 inconnues) que vous pouvez résoudre formellement et ensuite juste injecter vos coordonnées.

je sais que le calcul seul n'est pas propre mais il ne pose pas de soucis car même si nbrHTmoins vaut 4 et nbrHTplus vaut 5 il ne va pas tenir compte du delta car x est a max 4 donc le delta farfelu de l'opération sera multiplié par zéro.J'en prend note quand même de lui imposer des limites :grin:

bon j'ai lu au moins 10 fois ton post et mon cerveau a fait "pouf" :o RAM saturée :grin:
j'ai pas trop compris pourquoi tu parle de 4 points dans mon calcul, il se sert effectivement
de 4 points "connus" mais au final je n'ai qu'une valeur X et une valeur Y (donc 2)
qui me servent a trouver la valeur Z
si tu pouvait développer un peu cette solution j'aimerai comprendre comment elle fonctionne :wink:

sinon de mon coté (en mode simplifié^^) j'ai fait un peu le tour et en reprenant en partie
le code de base j'ai pensé:

    int RPM[5]= {900   1000  1200  1700  1800};
    int PRESSION[5]= {20   25  30  32  35};

(pour simplifier l'exemple on oubli les FLOAT, on parle de INT)
avec ces tableaux , si j'ai mon signal
"rpm" valeur 1200. comment pointer la valeur "1200" et afficher l'indice?

simplifié:
j'ai valeur 1200 , je veut que le programme me sorte l'indice du tableau (ici pour exemple : 2 )

merci :slight_smile:

up? :-[

steve59:
j'ai valeur 1200 , je veut que le programme me sorte l'indice du tableau (ici pour exemple : 2 )

Bonjour,

La méthode la plus simple est de parcourir le tableau et de trouver la valeur 1200

  int i;
  for (i=0; i<sizeof RPM/sizeof RPM[0] && RPM[i]!=1200; i++);
  if (i<sizeof RPM/sizeof RPM[0])
  {
    Serial.print("Index: ");
    Serial.println(i);
  }

Si le tableau est trié on peut améliorer l'algorithme.

simplifié:
j'ai valeur 1200 , je veut que le programme me sorte l'indice du tableau (ici pour exemple : 2 )

comment vous avez fait, en tant qu'humain pour voir que c'était l'index N° 2?

si vous savez répondre à cette question, vous avez trouvé comment programmer cela...

Damned - kamill a encore frappé :slight_smile:

Sinon ce que je raconte plus haut avec ma discussion mathématique c'est à peu près cela

vous connaissez les points clés, genre A,B,C,D qui vous permettent de définir votre surface dans votre espace 3D.

Vous faites l'acquisition des coordonnées x et y et vous cherchez le z associé

Pour cela vous devez trouver le point rouge sur la surface jaune qui est l'intersection de la ligne verticale partant de (x,y,0) (donc dont l'équation est {X = x, Y = y , Z quelconque}) et de la surface au dessus.

Ici j'ai mis des jolis points A,B,C,D qui permettent d'avoir une surface plane entre ces 4 points, mais dans la vraie vie, 4 points arbitraires dans l'espace 3D ne forment pas forcément un plan. On définit un plan en 3D à partir de 3 points.

Donc en imaginant que vos points sont bien fichus et que la surface Jaune est plane ce que vous devez faire c'est

1/ trouver les X et Y des projetés de A,B,C,D qui sont des points connus encadrant x et y sur la plan Z = 0

2/ une fois que vous avez trouvé ces points encadrants, en connaissant leur Z, vous en prenez 3 et écrivez les équations du plan passant par ces 3 points -> la surface jaune "au dessus" de (x, y, 0 )

3/ vous calculez l'intersection de ce plan avec la droite verticale {X = x, Y = y , Z quelconque}. cela se fait par une résolution de système de 3 équations à 3 inconnues assez simple (puisque vous connaissez x et y)

c'est la valeur que vous voulez.

ce que je dis c'est que tout cela c'est du "simple" calcul matriciel, donc étant donnés 3 points A,B,C vous écrivez en fonction de leur coordonnées les formules qui vont bien, vous isolez Z, vous injectez les x et y connus et ça vous donne Z de façon formelle. (le cas général est traité en exemple ici si vous voulez)

En application pratique, vous n'avez plus qu'à trouver les points encadrants, et injecter leurs coordonnées dans la formule

je ne sais pas si c'est plus clair :slight_smile: