Calcul min et max d'un Array

Fermé
DoctorHow - Modifié le 25 juin 2022 à 14:46
Pitet Messages postés 2826 Date d'inscription lundi 11 février 2013 Statut Membre Dernière intervention 21 juillet 2022 - 26 juin 2022 à 10:48
Salut,
mon code qui me sert à créer des formes (soit en SVG soit sur Canvas2d) est à peu près ça:

function Triangle(name, arrayX, arrayY){
if(arrayX.length!==arrayY.length)}{console.log("erreur# les paramètres arrayX et arrayY doivent être de même longueur!");
return}
return {
 name:name,
 x:arrayX,
 y:arrayY,
 width:Math.max(this.x)-Math.min(this.x),
 height:Math.max(this.y)-Math.min(this.y),
 getWidth:function(){return Math.max(this.x)-Math.min(this.x) },
 getHeight:function(){return Math.max(this.x)-Math.min(this.x) },
 updateWidth:function(){this.width=getWidth()},
 updateHeight:function(){this.height=getHeight()}
}

}

let tri=Triangle('tri', [15, 42, 84], [10, 37, 48])
console.log(tri.getWidth())


j'ai bien un Array de x et y mais le calcul de width,height, getWidth() et getHeight() ne marchent pas(renvoient NaN ou 'undefined'), une idée?
J'ai essayé ceci sans succès:
//-- dans l'objet
width:Math.max(...this.x)-Math.min(...this.x)

Testé en SVG mon triangle s'affiche correctement donc pas de soucis de ce côté là.

ps: je ne prends pas en compte de coordonnés négatives pour l'instant.


Merci de vos réponses
A voir également:

2 réponses

jordane45 Messages postés 38241 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 17 septembre 2024 4 689
25 juin 2022 à 16:17
Bonjour
C'est arrayX et non pas x...
Sinon il faut faire un objet et initialise x avec ta variable.... Et pas juste dans le return...
0
C'est bien un objet en écriture littérale(JSON) qui est renvoyé
console.log(typeof {})//-- affiche "object"


arrayX est donc le paramètre(équivalent d'un argument de constructeur) et this.x l'attribut d'e l'instance d'un objet(un Array ici).
En JavaScript une fonction est un objet et un objet est une fonction c'est ce qui permet cela.

console.log(Function instanceof Object)//-- true
console.log(Object instanceof Function)//-- true
//-- perturbant en effet


Il n' a pas toutes les propriétés d'un Object.create() ou fait avec class et c'est tant mieux pour les besoins ici. On peut même mettre des attributs en private comme ceci:

function objetLitteral(valeurPrivate, valeurPublic){
let privee=valeurPrivate
 return{
  val:valeurPublic,
  getPrivee:()=>privee
 }
}
let o=objetLitteral(10,'a')
o.val='b'//-- ok
o.getPrivee()//-- renvoi 10
o.privee=12 //-- erreur o.privee n'existe pas



merci quand même mais tout le reste fonctionne ce n'est que mon calcul de largeur/hauteur qui bugue.
0
Pitet Messages postés 2826 Date d'inscription lundi 11 février 2013 Statut Membre Dernière intervention 21 juillet 2022 524
25 juin 2022 à 18:58
Bonjour,

L'attribut this.x n'est pas encore défini lorsque tu initiales ton attribut width, utilises tes paramètres à la place :
function Triangle(name, arrayX, arrayY) {
    if (arrayX.length !== arrayY.length) {
        console.log("erreur# les paramètres arrayX et arrayY doivent être de même longueur!");
        return;
    }

    return {
        name: name,
        x: arrayX,
        y: arrayY,
        width: Math.max(...arrayX) - Math.min(...arrayX),
        height: Math.max(...arrayY) - Math.min(...arrayY),
        getWidth: function(){
            return Math.max(...this.x) - Math.min(...this.x);
        },
        getHeight: function(){
            return Math.max(...this.y) - Math.min(...this.y);
        },
        updateWidth: function(){
            this.width = getWidth();
        },
        updateHeight: function(){
            this.height = getHeight();
        }
    }

}

let tri = Triangle('tri', [15, 42, 84], [10, 37, 48]);
console.log(tri.getWidth());
console.log(tri.getHeight());
0
Ah c'est peut-être le truc qu'expliquait Jordane45.
Je vais tester ça même si je ne comprends pas pourquoi this.x n'existerais pas au moment où je l'utilise dans width. J'ai l'équivalent avec une forme de cercle et pas besoin de Math.min ou Math.max pour ça et ça fonctionne très bien.
Dans un cercle width/height sont obtenus en multipliant le radius par X2(width:this.radius*2) mais peut-être est ce différent avec une valeur en Array.
Je teste ça de suite merci de ta proposition.

En fait j'utilise l'héritage donc tout est déjà instancié au moment où je fait le calcul de width.

J'ai allégé le code pour me concentrer sur ce qui faisait une erreur, c'est plus cela(code allégé aussi):

function PolygonShape(arrayX,arrayY){//--Abstract
return {primitive:'PolygonShape',
 type:'PolygonShapeAbstract',
 name:null,
 x:arrayX,y:arrayY,
 component:new Map(),
 list:[]
//-- autres méthodes...
}
}


function ShapeTriangle(name, x, y, x1, y1,x2, y2){
 let tri=PolygonShape([x,x1,x2],[y,y1,y2])
 tri.type='PolygonShapeTriangle'
 tri.name=name
    tri.width=Math.max(this.x)-Math.min(this.x)
 tri.getWidth=function(){return Math.max(this.x)-Math.min(this.x)}
 tri.heigth= Math.max(this.y)-Math.min(this.y)
 tri.getHeight=function(){return Math.max(this.y)-Math.min(this.y)}
return tri
}


Mais je teste quand même en utilisant le paramètres au lieu de this.x/this.y pour voir si ça change
0
DoctorHow > DoctorHow
Modifié le 26 juin 2022 à 09:30
Toujours pas.
J'ai rajouté dans mon objet Abstract PolygonShape
function PolygonShape(arrayX,arrayY){//--Abstract
return {primitive:'PolygonShape',
 type:'PolygonShapeAbstract',
 name:null,
 x:arrayX,y:arrayY,
 width:Math.max(...arrayX)-Math.min(...arrayX),
 height:Math.max(...arrayY)-Math.min(...arrayY)
}
//--et dans l'objet enfant:
function ShapeTriangle(name, x, y, x1, y1,x2, y2){
 let tri=PolygonShape([x,x1,x2],[y,y1,y2])
 tri.type='PolygonShapeTriangle'
 tri.name=name
    tri.getWidth=function(){return Math.max(...this.x)-Math.min(...this.x)}
    tri.getHeight=function(){return Math.max(...this.y)-Math.min(...this.y)}
}

let tri=ShapeTriangle('tri', [15, 42, 84], [10, 37, 48])
console.log('tri.getWidth => '+tri.getWidth())//-- NaN
//--testé aussi ça mais même résultat:
tri.getWidth=function(){return Math.max(...tri.x)-Math.min(...tri.x)}
//-- même chose comme ceci:
tri.getWidth=function(){return parseFloat(Math.max(...this.x))-parseFloat(Math.min(...this.x))}



je crois qu'il me reste qu'à faire une comparaison dans une boucle pour extraire la valeur max et min :s tant pis pour l'optimisation et l'élégance
0
Pitet Messages postés 2826 Date d'inscription lundi 11 février 2013 Statut Membre Dernière intervention 21 juillet 2022 524 > DoctorHow
26 juin 2022 à 10:01
Toujours une erreur de syntaxe dans ton code (une accolade en trop) et ta fonction ShapeTriangle ne possède pas de return. Reprends un guide sur l'héritage en js et utilise la syntaxe ES6 :
https://www.javascripttutorial.net/es6/javascript-inheritance/
0
DoctorHow > DoctorHow
Modifié le 26 juin 2022 à 10:31
Autant pour moi il fallait faire les deux corrections(un peu cafouille parce que à faire sur la version non simplifiée et sur la simplifiée et que c'est répartit sur plusieurs fichers).
Merci d'avoir regardé.

Au final ça donne ça:

function PolygonShape(arrayX,arrayY){//-- Abstract
 if(arrayX.length!==arrayY.length){
  console.log('ERROR# arrayX and arrayY must have same length!');
  return
 }
 console.log('x: '+arrayX+' y: '+arrayY)
 return {primitive:'PolygonShape',
 type:'PolygonShapeAbstract',
 name:null,
 x:arrayX,y:arrayY
}
function ShapeTriangle(name, x, y, x1, y1,x2, y2){
 let tri=PolygonShape([x,x1,x2],[y,y1,y2])
 tri.type='PolygonShapeTriangle'
 tri.name=name
 tri.width=Math.max(...tri.x)-Math.min(...tri.x)
 tri.getWidth=function(){return Math.max(...this.x)-Math.min(...this.x)
 }
 tri.heigth= Math.max(...tri.y)-Math.min(...tri.y)
 tri.getHeight=function(){return Math.max(...this.y)-Math.min(...this.y)}
 return tri
}
0
DoctorHow > Pitet Messages postés 2826 Date d'inscription lundi 11 février 2013 Statut Membre Dernière intervention 21 juillet 2022
Modifié le 26 juin 2022 à 10:50
ah erreur de copié collé sûrement l'accolade en trop. Je fait de l'ES6 majoritairement mais ici la syntaxe JSON est bien pratique.

En tout cas tout fonctionne pour mon SVG:
const SVGNS='http://www.w3.org/2000/svg'
function isReal(v){return v===null || v==='undefined' ? false : true}

function DrawSVGTriangle(shp,target, addTo='svg'){
 let svg=document.createElementNS(SVGNS,'polygon'),
  pts=shp.getPoints(),
  style='',
  tmp;
 svg.setAttributeNS(null,'points',
 pts[0][0]+','+pts[0][1]+','+pts[1][0]+','+pts[1][1]+','+pts[2][0]+','+pts[2][1] )
 style += isReal(shp.properties.graphic.fillColor) ? 'fill:'+shp.properties.graphic.fillColor+';':''
 style += isReal(shp.properties.graphic.strokeColor) ? 'stroke:'+shp.properties.graphic.strokeColor+';':''
 style += isReal(shp.properties.graphic.lineWidth) ? 'stroke-width:'+shp.properties.graphic.lineWidth+';':''
 svg.setAttribute('style', style)
// saylog(shp.height)
 if(addTo==='svg'){
  tmp=document.createElementNS(SVGNS,addTo)
  tmp.setAttribute('id','svg-'+shp.name)
  tmp.setAttribute('width',(shp.getWidth()+Math.min(...shp.x)+shp.properties.graphic.lineWidth)+'px')
  tmp.setAttribute('height',(shp.getHeight()+Math.min(...shp.y)+shp.properties.graphic.lineWidth)+'px')
 }else if(addTo.tagName==='svg'){
  tmp=addTo
 }
 tmp.appendChild(svg)
 svg=tmp
    target.appendChild(svg)
    return svg
}


résolu merci encore
0