11536 sujets

JavaScript, DOM et API Web HTML5

Bonjour,
J'aimerai utiliser un tableau à 3 dimensions , la première dimension contiendrai les coordonnées d'un point (x,y), la deuxième dimension contiendrai le numéro du point et la troisième dimension contiendrai le numéro de la projection.
-J'arrive à remplir un tableau à 2 dimensions en utilisant la fonction push dans une boucle for

function calcul()
   {
   for (var k =0; k <(long_tab); k++)
	 {....
         ptspara.push([xpara,ypara]) ;
         }
   }

Cela rempli le tableau ptspara avec les coordonnées x,y , en 2 dimensions
J'ai créé un second tableau

   for (var j =0; j <20; j++)
	 {
         calcul()
         tableau_pts[j]=ptspara ;
         }

Actuellement je n'arrive pas à "réinitialisé" le tableau ptspara,je pense que si j'arrivai à effacer le tableau ptspara après l'affectation dans le tableau tableau_pts cela remplirai correctement le tableau tableau_pts.
Modérateur
Salut,


let dataPoints = [
  {
    id: 1,
    x: 123,
    y: 456,
    z: 789
  }, 
  // etc.
]


Pour aller plus loin, autant créer une class s'il y a des méthodes associées.
Modifié par niuxe (23 Mar 2025 - 18:56)
" niuxe"je ne connais pas cette écriture

let dataPoints = [
  {
    id: 1,
    x: 123,
    y: 456,
    z: 789
  }, 
  // etc.
]


Est ce un tableau a 2 dimensions dont une dimension contient 4 informations id,x,y et z?
Modérateur
le principe est simple. Ce que j'ai pu comprendre, tu veux représenter des points dans un espace 3D (Ton sujet n'explique pas précisément ce que tu veux faire au final). Tu génères des objets qui représenteront des points dans un espace 3D (x,y,z). À mon avis, ce ne sera pas suffisant, mais comme je ne connais pas le but, je ne peux pas me prononcer. Ton tableau ne sera qu'une liste de tes objets.
Modifié par niuxe (24 Mar 2025 - 15:41)
Salut,

je suppose que ton tableau ptspara est une variable "globale" (je suis pas convaincu que tu en as conscience) et ça me semble "crade" comme solution (surtout vu comment tu t'en sers Smiley ohwell )

Je dirais qu'il faut plutôt déclarer ton tableau dans ta fonction calcul puis de retourner ton tableau à la fin de la fonction :


function calcul()
{
    let ptspara=[]
    for (var k =0; k <(long_tab); k++)
    {....
        ptspara.push([xpara,ypara]) ;
    }
    return ptspara;
}



for (var j =0; j <20; j++)
{
    tableau_pts[j]=calcul();
}



Et ensuite je pense qu'il faudrait mieux expliquer ton problème car ça me semble bizarre entre ta description de problème et le peu de code qu'on a.
Dans ta description tu sembles vouloir associer un seul point à la fois, donc tableau_pts[0] devrait contenir un seul point, mais tu semble lui affecté un tableau de plusieurs points (de taille long_tab).
Et si à chaque fois c'est bien une association 1->1 , ça semble plus logique d'utiliser une structure comme propose niuxe qui rassemble toutes les infos ensembles pour un point
Modifié par Mathieuu (25 Mar 2025 - 11:50)
Bonjour,
"Niuxe" mon projet consiste à partir du contour d'un terrain quelconque de calculer le trajet d'une tondeuse . La tondeuse commence a tondre en suivant le périmètre puis de réduire le périmètre extérieur du passage de la tondeuse pour obtenir un nouveau tracé. La troisième dimension du tableau représente le nombre de passage et contient les segments parallèles à ceux d'origines .
A partir d'un certain nombre de tours, il y a des segments qui se croisent, donc la c'est trop compliqué pour ma petite tête.

"Mathieuu" effectivement le tableau ptspara est une variable globale, je ne pense pas que cela pose problème.
En réalisant votre suggestion , je perds la dimension de mon tableau .

Le tableau ptspara contient les points correspondant au périmètre du terrain , j correspond au nombre de passage de la tondeuse et "long_tab" au nombre de point constituant le périmètre d'origine.
Le problème est qu'en réduisant le périmètre ,le nombre de point peut aussi se réduire .

Je ne connais "très peu" javascript, mais cela me permet de réaliser des dessins . V upload/1742917470-87068-contourterrain.png oici le code qui certainement contient des "aberrations", c'est avec plaisir que j'accepterai vos remarques .


<!doctype html>								                                	<!-- indique le type de document au navigateur -->
<html lang="fr">							                                	<!-- indique la langue du document -->

  <head>									                                      <!-- balise ,contient les informations (metadonnées) du document -->
    <meta charset="UTF-8" />							                      <!-- détermine le jeu de caratères , comme la prise en charge des accents-->
    <title>calul trajet robot </title>		                  		<!-- détermine le texte dans l'onglet du navigateur web -->
  </head>
  <body>									                                      <!-- balise ,détermine le corps du document -->
    En info_test
    <canvas id="test" width="2000" height="1000"></canvas>			<!-- Détermine une surface de dessin en bitmap -->
    

      <script type="application/javascript">				           // traitement des données , importation d'un script externe : <script src="javascript.js">
        var mespoints = [
        [1,1],
        [4,5],
        [2,17],
        [8,18],
        [11,15],
        [9,12],
        [12,10],
        [17,9],
        [16,12],
        [21,14],
        [26,10],
        [23,3],
        [20,5],
        [13,6],
        [10,3],
        [11,1],
        [1,1]
      ];
    var coef_droite=[];                                        // tableau contenant les coefs a,b,bb, et distance entre b et bb  y=ax+b et parallele : y=ax+bb 
    var ptspara=[];                                            // tableau a 2 dimensions, 1 dimension : numero du point  2ieme dimension= x ou y du point
    var tableau_pts=[];                                        // tableau a 3 dimensions, 1 dimension = nbre de passage ; numero du point  2ieme dimension= dimension : numero du point 3ieme dim:x ou y du point
    var long_tab;
    var larg_passage =0.5;

    long_tab= mespoints.length;                                // donne  la longeur du tableau 
   
    function draw() 								                          // déclaration de la fonction draw -->
      { 
      const info_test = document.getElementById("test");			// récupére les informations de l'id "test" -->
	     
      if (info_test.getContext) {						                  // test l'existance de l'objet contexte de dessin  -->
          const ctx = info_test.getContext("2d");			      	// création de la variable pour dessiner   -->
          
          ctx.lineWidth=3;                                    // épaisseur du trait
          ctx.beginPath();
          ctx.font = "48px serif";                            // taille des lettres

	        for (var i =0; i < long_tab; i++)
		        {
		        ctx.lineTo(mespoints[i][0]*50,1000-(mespoints[i][1])*50 );
            ctx.fillText(i, mespoints[i][0]*50,1000-(mespoints[i][1])*50 );                   // ecrit le numero des points du dessin
		        }
          ctx.strokeStyle = "red";
          ctx.stroke(); 
          ctx.lineWidth=1;                                     // épaisseur du trait
         
          ctx.beginPath();
          for ( j=1; j <3; j++)                                //  affiche les tours de terrain
            {
            ctx.moveTo (tableau_pts[j][0][0]*50,1000-(tableau_pts[j][0][1])*50);
            for (var i =1; i < 16; i++)
		         {
		         ctx.lineTo(tableau_pts[j][i][0]*50,1000-(tableau_pts[j][i][1])*50 );
		         }
          ctx.lineTo(tableau_pts[j][0][0]*50,1000-(tableau_pts[j][0][1])*50 );
          ctx.strokeStyle = "blue";
            }
          ctx.stroke(); 
          }
        }

      function parallele(numero)                                // calcul les prametres des droites passant par les segments
        {
        let a,b,dist;

        a=(mespoints[numero+1][1]-(mespoints[numero][1]))/(mespoints[(numero+1)][0]-mespoints[numero][0])  ;    // calcul de a  de y=ax+b 
        b= mespoints[numero][1]-a*mespoints[numero][0] ;                                                        // calcul de b  de y=ax+b                                                                         
        if((mespoints[numero+1][0]-(mespoints[numero][0])) >0 )                                                 // Si delta x>0 on soustrait le deplacement  
            dist=-larg_passage*Math.sqrt(1+a*a) ;                                                               //calcul de la distance entre les paralleles de y=ax+b vers y=ax+bb
        else
            dist=+larg_passage*Math.sqrt(1+a*a) ; 
                                                                                                    
        coef_droite.push([a,b,dist]);
        }

      function calcul_points(nb_passage) 								                                 // calcul des nouveaux points  intersection des droites paralleles
        { 
        for (var k =0; k <(long_tab-2); k++)
		      {
		      var xpara,ypara;
          var bb12,bb23;
    
          bb12=coef_droite[k][1]+(coef_droite[k][2]*(nb_passage));                        // calcul du nouveau coef b de la parallele
          bb23=coef_droite[k+1][1]+(coef_droite[k+1][2]*(nb_passage));
          xpara=(bb23-bb12)/(coef_droite[k][0]-coef_droite[k+1][0])  ;                    // calcul de x intersection des droites paralleles x= (bb23-bb12)/(a12-a23) 
          ypara=(coef_droite[k][0]*xpara + bb12 );                                        // bb=b+nbr_passage*dist_para   
          ptspara.push([xpara,ypara])   ; 
          }
        
        // calcul du dernier point  
        bb12=coef_droite[k][1]+(coef_droite[k][2]*(nb_passage));
        bb23=coef_droite[0][1]+(coef_droite[0][2]*(nb_passage));  
        xpara=(bb23-bb12)/(coef_droite[k][0]-coef_droite[0][0])  ;                                     // calcul de x intersection des droites paralleles x= (bb23-bb12)/(a12-a23) 
        ypara=(coef_droite[k][0]*xpara + bb12 );   
        ptspara.push([xpara,ypara]) ;                                                                    // sauvegarde des coordonnees dans le tableau   
        }
   
      for (var j=0; j < (long_tab-1); j++)                                          // il y a 17 points donc 16 droites , calcul des coefficients des droites
          {
		      parallele(j);
          document.write('a = '+coef_droite[j][0]+'b = '+coef_droite[j][1]+'distance parallele = '+coef_droite[j][2]+  '<BR>') ;
          }

      for ( j=0; j < 20; j++)                                                       // nombre de passage
            {
            calcul_points(j);
            tableau_pts[j]=ptspara;
            ptspara=[];
            }
      
      draw();								// appel de la fonction draw -->   
   
   
   </script>
  </body>
</html>

Modifié par herve_37 (25 Mar 2025 - 19:22)
Salut,

"mode vieux con qui n'aime pas les variables globales Smiley lol ". Je confirme que ton tableau ptspara n'a pas d'utilité à être globale vu que tu passe ton temps à le réinitialiser.

Du coup mini modif : https://jsfiddle.net/fzhtm5o6/
En résumé : J'ai supprimé la variable globale, je la recrée en local dans ta fonction calcul_points, un petit return à la fin de la fonction, et une récupération du retour de la fonction en bas du code ( tableau_pts[j] = calcul_points(j) )

Et globalement je n'aime pas du tout ton code Smiley sweatdrop
Une fonction ça utilise des paramètres, ça travaille avec puis ça renvoie un résultat, là dans ton code elles sont toutes dépendantes de variables globales et donc externe à la fonction, je trouve ça pénible à suivre.
Là en l'état il n'y a pas une seule fonction où je peux dire à tiens elle est pas mal cette fonction je vais la copier dans un autre projet, il faudra faire plein d'adaptation du code avant à cause des variables globales Smiley ohwell

Exemple de modification : A la place d'une fonction draw() , je ferai plutôt une fonction draw_line qui dessine une seule ligne, et qui s'adapte automatiquement en fonction de la ligne que je lui passe en paramètre.

Pour la liste de points je ferai plutôt comme le suggère Niuxe avec x et y, ça permettra de rentre le code plus lisible en faisant .x et .y plutôt que [0] ou [1]
J'ai repris ton code à ma sauce pour essayer de tenir compte de mes remarques :
- Globalement j'ai laissé seulement larg_passage en variable globale (que j'ai écris en majuscule pour indiquer que c'est une constante). Il faudrait en faire autant pour les 50 et 1000 qu'il y a plusieurs reprises dans le code.
- J'ai redéfini ton tableau de points pour utiliser .x et .y, cela se répercute dans le code des fonctions (à la place des [0] et [1]). Même principe pour les "coef_droites" avec a b dist à la place de [0] [1] [2].
- J'ai redéfini tes fonctions pour qu'elle fasse une tache de manière autonome à partir du moment où l'on rempli correctement les paramètres.
- J'ai rajouté une "magouille" dans la fonction calcul_points pour que ta ligne soit fermée.
- Je ne sais pas comment sont générés tes points de départ donc je n'ai pas rajouté dans le code, mais il y a des risques de faire des divisions par 0 lors du calcul de xpara et il faudrait prévoir un if pour protéger ça.


 var LARG_PASSAGE = 0.5;

      function draw_line(line, color="blue", text=false){
        //console.log(line);
        const info_test = document.getElementById("test") // récupére les informations de l'id "test" -->

        if (info_test.getContext) {
          // test l'existance de l'objet contexte de dessin  -->
          const ctx = info_test.getContext("2d") // création de la variable pour dessiner   -->

          ctx.lineWidth = 3 // épaisseur du trait
          ctx.beginPath()
          ctx.font = "48px serif" // taille des lettres

          line.forEach( (monpoint, index) => {
            ctx.lineTo(monpoint.x * 50, 1000 - monpoint.y * 50);
            if(text)
            {
              ctx.fillText(index, monpoint.x * 50, 1000 - monpoint.y * 50);
            }
          });

          ctx.strokeStyle = color;
          ctx.stroke()
        }
      }    

      function parallele(line) {
        let coef_droite = [];

        for(let i=0;i<line.length-1;i++){
          let a, b, dist
          a =(line[i+1].y - line[i].y) / (line[i+1].x - line[i].x); // calcul de a  de y=ax+b
          b = line[i].y - a * line[i].x; // calcul de b  de y=ax+b

          if (line[i+1].x - line[i].x > 0){
            // Si delta x>0 on soustrait le deplacement
            dist = -LARG_PASSAGE * Math.sqrt(1 + a * a) //calcul de la distance entre les paralleles de y=ax+b vers y=ax+bb
          }
          else{
            dist = +LARG_PASSAGE * Math.sqrt(1 + a * a);
          } 
          coef_droite.push({"a":a, "b":b, "dist":dist});
        }

        coef_droite.forEach(coef => document.write("a = " +coef.a +" b = " +coef.b +" distance parallele = " +coef.dist +"<BR>"))

        //console.log(coef_droite); 

        return coef_droite;
      }


      function calcul_points(line, coef_droite, nb_passage) {
        let ptspara = []
        // calcul des nouveaux points  intersection des droites paralleles
        for (var k = 0; k < line.length - 2; k++) {
          var xpara, ypara
          var bb12, bb23

          bb12 = coef_droite[k].b + coef_droite[k].dist * nb_passage // calcul du nouveau coef b de la parallele
          bb23 = coef_droite[k + 1].b + coef_droite[k + 1].dist * nb_passage
          xpara = (bb23 - bb12) / (coef_droite[k].a - coef_droite[k + 1].a) // calcul de x intersection des droites paralleles x= (bb23-bb12)/(a12-a23)
          ypara = coef_droite[k].a * xpara + bb12 // bb=b+nbr_passage*dist_para
          ptspara.push({"x":xpara, "y":ypara})
        }

        // calcul du dernier point
        bb12 = coef_droite[k].b + coef_droite[k].dist * nb_passage
        bb23 = coef_droite[0].b + coef_droite[0].dist * nb_passage
        xpara = (bb23 - bb12) / (coef_droite[k].a - coef_droite[0].a) // calcul de x intersection des droites paralleles x= (bb23-bb12)/(a12-a23)
        ypara = coef_droite[k].a * xpara + bb12
        ptspara.push({"x":xpara, "y":ypara}) // sauvegarde des coordonnees dans le tableau


        ptspara.push({"x":ptspara[0].x,"y":ptspara[0].y});  //magouille pour que ce soit fermé. 

        return ptspara;
      }    

      // traitement des données , importation d'un script externe : <script src="javascript.js">
      var mespoints = [
        { x: 1, y: 1 },
        { x: 4, y: 5 },
        { x: 2, y: 17 },
        { x: 8, y: 18 },
        { x: 11, y: 15 },
        { x: 9, y: 12 },
        { x: 12, y: 10 },
        { x: 17, y: 9 },
        { x: 16, y: 12 },
        { x: 21, y: 14 },
        { x: 26, y: 10 },
        { x: 23, y: 3 },
        { x: 20, y: 5 },
        { x: 13, y: 6 },
        { x: 10, y: 3 },
        { x: 11, y: 1 },
        { x: 1, y: 1 },
      ];

      draw_line(mespoints, "red", true);

      let coef_droite= parallele(mespoints);
      for (let j = 1;j < 4;j++) {
        draw_line(calcul_points(mespoints, coef_droite, j));
      }



Et nouveau jsfiddle qui illustre : https://jsfiddle.net/fzhtm5o6/1/
"Mathieu" c'est vrai que mon code est illisible.
Je rencontre le même problème cet après-midi que hier soir ,après ta remarque pour réaliser une fonction "simple", a savoir:
-si je veux un tableau à 3 dimensions ,une représentant le nombre de tour de terrain, la seconde représentant les points du périmètre et la troisième correspondant au coordonnées du point ,
- la fonction qui calcul le point d'intersection de 2 droites et remplit un simple tableau"tab_points" avec le x et y du point avec un envoi du tableau:

function point_intersection( coefs des droites...)
..
tab_points.push([x,y])
 return tab_points 

en lisant le tableau, tab_points[0] correspond à x,y et tab_points[1] n'est pas défini .
Je pensais trouver tab_points[0] = x et tab_points[1] = y

Pourtant cela semble fonctionner dans ton premier exemple avec la fonction

calcul_points(nb_passage)
 ...  ptspara.push([x_pt,y_pt])
   return ptspara


tableau_pts[j] = calcul_points(j)
Avec ton code la :
- tab_points c'est un tableau
- tu push un tableau à l’intérieur <=> tab_points[0] contient le premier point (representé par un tableau [x,y]) => tu accèdes au x du premier point en faisant tab_points[0][0] et y en faisant tab_points[0][1].

Et une de mes modifications de ton code (suggestion de niuxe pour être précis), plutôt que de mettre un tableau c'est de mettre un "objet" : {"x":x , "y":y}
Comme ça quand tu feras tab_points.push tu ajouteras un objet et tu accéderas via tab_points[0].x et tab_points[0].y ce qui facilite la lecture du code ensuite