Calcul angle moyen avec itérations non listés

Pour toutes les discussions javascript, jQuery et autres frameworks
GeGaX
Messages : 26
Enregistré le : 20 févr. 2018, 21:56

Calcul angle moyen avec itérations non listés

Message par GeGaX » 20 févr. 2018, 21:59

Bonjour,

J'ai une extension Google Chrome qui m'extrait les valeurs d'une page web et qui me liste les instructions sous forme de tableau

Le rendu du popup.html me donne ceci :

Image

La dessus tout va bien pas de soucis ;)

Petite précision qui à son importance, dans la colonne TWA, les valeurs en vert sont positives et les valeurs en rouge sont négatives

Je ne parlerais que de TWA et TWAm ( BTW et BTWm c'est la même chose sauf que cela se passe sur 360° et je possède déjà le minuscule bout de code me permettant de faire la conversion)

[COURS RELOU ... ] En navigation maritime, le vert c'est à droite et on l'appelle tribord ; le rouge c'est à gauche et on l'appelle bâbord. Tribord et Bâbord sont donc 2 "cotés" différents que l'on appelle "bords" [/ COURS RELOU ...]

TWAm ne fait pas parti des valeurs extraites puis listées, c'est une valeur calculée.

# Pour les 2 premières lignes les valeurs sont rouges donc c'est le même bord ( cf COURS RELOU ... ; valeurs négatives)
de T+0:00 pour aller à T+0:10: je dois faire du -45°

de T+0:00 pour aller à T +0:30: (-45 + -50) / 2 ? , ben nan ... il y a une itération non listée ( T +0:20 = -50° ) donc le calcul sera donc (-45 + - 50 + -50) / 3 = -48,3°

# Pour la ligne suivante, les valeurs sont vertes donc changement de bord ( je remet pas le cf et ce qui va avec )
donc la valeur TWA de T +0:30 devient la valeur de réference comme si elle était T +0:00 et la logique de calcul est identique à l'exemple des 2 premieres lignes décrite ci dessus.

Oui MAIS cette logique de calcul est fausse ..., il faut passer par la trigonométrie si on travail avec des angles.

On m'a donné ce code : (Qui fait parfaitement le travail quand on lui rentre les valeurs à la main)

Code : Tout sélectionner

{ 
    const
        anglesMesuré = [ 276, 271, 270, 273, 274, 277 ],
        converDegEnRadian = Math.PI / 180.0,
        converRadianEnDeg = 180.0 / Math.PI;

    let
        arX = [],
        arY = [],
        sommeX = 0.0,
        sommeY = 0.0,
        moyenneX = 0.0,
        moyenneY = 0.0,
        angleMoyen = 0.0;

    for ( const [ i, angle ] of anglesMesuré.entries() ){
        arX[ i ] = Math.cos( angle * converDegEnRadian );
        arY[ i ] = Math.sin( angle * converDegEnRadian );
    }

    for ( const value of arX ){
        sommeX += value;
    }

    moyenneX = sommeX / arX.length;

    for ( const value of arY ){
        sommeY += value;
    }

    moyenneY = sommeY / arY.length;

    angleMoyen = Math.round ( ( Math.atan2( moyenneY, moyenneX ) * converRadianEnDeg ) * 10 ) / 10;

    console.log( `L'angle moyen du vent est de ${angleMoyen}°` );
}

Je souhaiterais mettre en place une fonction qui s'appellerais twam et qui aurait pour argument time ou ttw et twa ( il en faut peut être d'autres ... ) - function twam (time ou ttw, twa) {un code similaire à celui du dessus}
et la est mon soucis ( d'ou le post ) avec prise en compte des itérations manquantes ...

Je vous transmet le popup.js actuelle, tout ce qui concerne TWAm et BTWm est commenté dans le code.

Je suis preneur de toutes infos pouvant m'aider à réaliser cette fonction twam qui automatiserait de façon valide, ce coup ci, le calcul de moyenne limité au bord et qui recommencerait pour le bord suivant et ainsi de suite.

popus.js :

Code : Tout sélectionner

var background = [/download/telecharger-34056452-google-chrome chrome].extension.getBackgroundPage();

/*
var hour_actu = 0;
var hour_change = 0;
var hour_prec = 0;
var nb_step = 0;

var twam = 0;
var twa_prec = 0;
var tot_twa_prec = 0;
var tot_twa = 0;

var btwm = 0;
var btw_prec = 0;
var tot_btw_prec = 0;
var tot_btw = 0;

var twa_btw_change = 0;
*/

function createCell(value, row) {
    var cell = document.createElement("td");
    cell.innerHTML = value;
    row.appendChild(cell);
}

function ttwStyling(value, cell) {
    cell.align = "left";
    cell.innerHTML = value;
}

function dtwStyling(value, cell) {
    cell.align = "left";
    cell.innerHTML = value;
}

function dtgStyling(value, cell) {
    cell.align = "left";
    cell.innerHTML = value;
}

function twsStyling(value1, value2, cell) {
    var tws_foil = value1.replace(" kt", "");
    var twa_bd = value2.replace("\u00B0", "");
    if (tws_foil >= 11.1 && tws_foil <= 39.9 && Math.abs(twa_bd) >= 71 && Math.abs(twa_bd) <= 169) {
        cell.style.backgroundColor = "black";
        cell.style.color = "white";
    } else {
        cell.style.backgroundColor = "white";
        cell.style.color = "black";
    }
    cell.innerHTML = tws_foil + " kt";
}

function twaStyling(value, cell) {
    var twa_bd = value.replace("\u00B0", "");
    if (twa_bd >= 0) {
        cell.style.color = "green";
    } else {
        cell.style.color = "red";
    }
    cell.innerHTML = Math.abs(twa_bd) + "\u00B0";
}

function btwStyling(value, cell) {
    cell.style.color = "blue";
    cell.innerHTML = value;
}

function sailStyling(value, cell) {
    switch (value.trim()) {
        // Upwind sail
        case "Jib":
            cell.style.backgroundColor = "#FFD479";
            break;
        case "LJ":
            cell.style.backgroundColor = "#FFFC79";
            break;
        case "Stay":
            cell.style.backgroundColor = "#D4FB79";
            break;
        // Downwind sail
        case "Spi":
            cell.style.backgroundColor = "#76D6FF";
            break;
        case "LG":
            cell.style.backgroundColor = "#7A81FF";
            break;
        case "HG":
            cell.style.backgroundColor = "#D783FF";
            break;
        // Reaching sail
        case "C0":
            cell.style.backgroundColor = "#FF7E79";
            break;
    }
    cell.innerHTML = value;
}

function twamStyling(value, cell) {
    if (value >= 0) {
        cell.style.color = "green";
    } else {
        cell.style.color = "red";
    }
    if (value != "-") {
        cell.innerHTML = Math.abs(value) + "\u00B0";
    } else {
        cell.style.color = "black";
        cell.innerHTML = value;
    }
}

function btwmStyling(value, cell) {
    cell.style.color = "blue";
    if (value != "-") {
        cell.innerHTML = value + "\u00B0";
    } else {
        cell.style.color = "black";
        cell.innerHTML = value;
    }
}

function createCellWithCustomStyling(value, row, customStyling) {
    var cell = document.createElement("td");
    customStyling(value, cell);
    row.appendChild(cell);
}

function createCellWithCustomStyling2(value1, value2, row, customStyling) {
    var cell = document.createElement("td");
    customStyling(value1, value2, cell);
    row.appendChild(cell);
}

/*
function calc_nb_ite(value) {
    var delta_t = value.match(/.*?([0-9]{1,}):([0-9]{2})/);
    hour_prec = hour_actu;
    hour_actu = delta_t[1] * 6 + delta_t[2] / 10;
    nb_step = hour_actu - hour_prec;
}

function calc_twam(value) {
    ss_tot = parseFloat(value.replace("\u00B0", ""));
    tot_twa = tot_twa_prec + (twa_prec * nb_step);
    if (hour_actu == hour_change) {
        twam = "-";
    } else {
        twam = tot_twa / (hour_actu - hour_change);
        twam = Math.round(twam);
    }
    tot_twa_prec = tot_twa;
    twa_btw_change = 0;
    if ((twa_prec * ss_tot) <= 0) {
        tot_twa_prec = 0;
        twa_btw_change = 1;
    }
    twa_prec = ss_tot;
}

function calc_btwm(value) {
    ss_tot = parseFloat(value.replace("\u00B0", ""));
    // N1
    if (btwm >= 270 && btw_prec <= 90) {
        btw_prec = btw_prec + 360;
    } else {
        if (btwm <= 90 && btw_prec >= 270) {
            btw_prec = btw_prec - 360;
        }
    }
    // End N1
    tot_btw = tot_btw_prec + (btw_prec * nb_step);
    if (hour_actu == hour_change) {
        btwm = "-";
    } else {
        btwm = tot_btw / (hour_actu - hour_change);
        // N2
        if (btwm >= 360) {
            btwm = btwm - 360;
        } else {
            if (btwm < 0) {
                btwm = btwm + 360;
            }
        }
        // End N2
        btwm = Math.round(btwm);
    }
    tot_btw_prec = tot_btw;
    if (twa_btw_change == 1) {
        tot_btw_prec = 0;
        nb_step = 0;
        hour_prec = hour_actu;
        hour_change = hour_actu;
    }
    btw_prec = ss_tot;
}
*/

function reinitializeDisplay() {
    document.getElementById("pointsTable").innerHTML = "";
}

function UtcToLocal(date, time, timezone) {
    var utcYear = date.split("-")[0];
    var utcMonth = (date.split("-")[1])-1;
    var utcDay = date.split("-")[2];

    var utcHour = time.split(":")[0];
    var utcMinutes = time.split(":")[1];

    var utcTimeZone = timezone[1];

    var dateUtc = Date.UTC(utcYear, utcMonth, utcDay, utcHour, utcMinutes, 0, 0);
    var localDate = new Date(dateUtc);

    var year = localDate.getFullYear();
    var month = ("0"+(localDate.getMonth()+1)).slice(-2);
    var day = ("0"+localDate.getDate()).slice(-2);

    var hours = ("0" + localDate.getHours()).slice(-2);
    var minutes = ("0" + localDate.getMinutes()).slice(-2);

    var offset = -localDate.getTimezoneOffset();
    var absOffset = Math.abs(offset);
    var sign = (offset > 0) ? "+" : "-";
    var hoursOffset = Math.trunc(absOffset) / 60;
    var MinutesHoursOffset = (hoursOffset === 0) ? "\u00b1" + "0" : sign + hoursOffset;
    var minutesOffset = absOffset % 60;
    var HoursMinutesOffset = (minutesOffset === 0) ? MinutesHoursOffset : sign + hoursOffset + ":" + minutesOffset;

    var formattedDate = year + "-" + month + "-" + day;
    var formattedTime = hours + ":" + minutes;
    var formattedTimeZone = "UTC" + HoursMinutesOffset;
    return [formattedDate,formattedTime,formattedTimeZone];
}

function getTimeZone(timezone) {
    if (timezone === "CET") {
        return "UTC+1";
    } else if (timezone === "CEST") {
        return "UTC+2";
    }
}

function displayTable(localTime) {
    points.forEach(function (element) {
        var row = document.createElement("tr");
        document.getElementById("pointsTable").appendChild(row);
        if (localTime && element.timezone === "CET" | "CEST") {
            var ceTZ = getTimeZone(element.timezone);
            createCell(element.date, row);
            createCell(element.time, row);
            createCell(ceTZ, row)
        } else if (localTime && element.timezone === "UTC") {
            var localDTZ = UtcToLocal(element.date,element.time,element.timezone);
            createCell(localDTZ[0], row);
            createCell(localDTZ[1], row);
            createCell(localDTZ[2], row);
        } else {
            createCell(element.date, row);
            createCell(element.time, row);
            createCell(element.timezone, row)
        }
        createCellWithCustomStyling(element.ttw, row, ttwStyling);
        //calc_nb_ite(element.ttw);
        createCellWithCustomStyling(element.dtw, row, dtwStyling);
        createCellWithCustomStyling(element.dtg, row, dtgStyling);
        createCell(element.twd, row);
        createCellWithCustomStyling2(element.tws, element.twa, row, twsStyling);
        createCellWithCustomStyling(element.twa, row, twaStyling);
        //calc_twam(element.twa);
        createCellWithCustomStyling(element.btw, row, btwStyling);
        //calc_btwm(element.btw);
        createCellWithCustomStyling(element.sail, row, sailStyling);
        createCell(element.stw, row);
        createCellWithCustomStyling(twam, row, twamStyling);
        createCellWithCustomStyling(btwm, row, btwmStyling);
        var manifest = chrome.runtime.getManifest();
        document.getElementById("version").innerHTML = manifest.version;
    });
}

var displayLocal = function () {
    reinitializeDisplay();
    if (document.getElementById("localtime").checked) {
        chrome.storage.local.set({"localTime" : true});
        displayTable(true);
    } else {
        chrome.storage.local.set({"localTime" : false});
        displayTable(false);
    }
};

document.getElementById("localtime").addEventListener("change", displayLocal);

chrome.storage.local.get("localTime",function (result) {
    if(result.localTime === true){
        document.getElementById("localtime").checked = true;
        displayLocal();
    } else {
        document.getElementById("localtime").checked = false;
    }
});
reinitializeDisplay();
var points = background.points[background.currentTab];
displayTable(false);
S'il vous faut autre chose ( popup.html ou autre fichier composant l'extension je vous les fournirais avec grand plaisir )

Merci d'avoir pris le temps de me lire et au plaisir de vous lire ;)

GeGaX
Messages : 26
Enregistré le : 20 févr. 2018, 21:56

Re: Calcul angle moyen avec itérations non listés

Message par GeGaX » 26 févr. 2018, 13:57

Bonjour,
Plusieurs vues mais pas de pistes, je me dis qu'il doit manquer quelque chose ...
Après réflexion, je me dis que qu'il est peut être opportun d'indiquer comment ce fait l'extraction des données, elle peut indiquer surement certaines choses qui aiderait à comprendre.
Je vais détailler au maximum pour éviter toutes confusions en prenant un exemple concret.
Image

TWAm correspond une moyenne de twa et est calculée avec cette fonction

Code : Tout sélectionner

function twamCalc() {
  const
  twaData = [-28, -38];
  Math.radians = function (degrees) {
    return degrees * Math.PI / 180.0;
  },
  Math.degrees = function (radians) {
    return radians * 180.0 / Math.PI;
  };
  
  let
  arX = [],
  arY = [],
  somX = 0.0,
  somY = 0.0,
  moyX = 0.0,
  moyY = 0.0,
  twam = 0.0;
  
  for (const [i, angle] of twaData.entries()) {
    arX[i] = Math.cos(Math.radians(angle));
    arY[i] = Math.sin(Math.radians(angle));
  }
  
  for (const value of arX) {
  somX += value;
  }
  moyX = somX / arX.length;
 
  for (const value of arY) {
  somY += value;
  }
  moyY = somY / arY.length;
 
  twam = Math.round((Math.degrees(Math.atan2(moyY, moyX)) * 10)) / 10;
  
  return twam ;
}
 
  console.log(twamCalc()); // -33
Dans mon 'cahier des charges' 3 choses :
- Obtenir une valeur pour twam pour chaque ttw listés.
- Le calcul des valeurs twam ( pour ce cas ) doit se limiter aux valeurs négatives puis reprendre pour les valeurs positives (et vice versa tout dépend de la valeur initiale de T+ 0:00)
- le calcul des valeurs twam doit prendre en compte les valeurs twa des itérations de 10min ( ttw ) non listés.

# Si les itérations de 10 min sont prises en compte je dois obtenir:

Code : Tout sélectionner

//T+ 0:00, T+ 0:10, T+ 0:20, T+ 0:30, T+ 0:40, T+ 0:50, T+ 1:00, T+ 1:10, T+ 1:20, T+ 1:30, T+ 1:40, T+ 1:50, T+ 2:00
-45, -45, -45, -45, -50, -50, -45, 50, 50, 35, 35, 35, 45
# Si j'ajoute la condition que je me limite aux valeurs négatives ( pour la première partie puisqu'il y a des valeurs positives après ) je dois obtenir:

Code : Tout sélectionner

//T+ 0:00, T+ 0:10, T+ 0:20, T+ 0:30, T+ 0:40, T+ 0:50, T+ 1:00
-45, -45, -45, -45, -50, -50, -45
# Si je souhaite obtenir une valeur twam pour chaque itération du tableau, twaData doit correspondre pour chaque ttw listé : ( résultat obtenu avec twamCalc() )

Code : Tout sélectionner

- // T+ 0:00 je ne peux pas obtenir une valeur ici car je suis déjà sur ce point
-45 // T+ 0:10 twaData = [-45, -45]
-45 // T+0:40 twaData = [-45, -45, -45, -45]
-46,7// T+ 1:00 twaData = [-45, -45, -45, -45, -50, -50]
-46,4// T + 1:10 twaData = [-45, -45, -45, -45, -50, -50, -45]
##########################################################
#Le calcul stop et recommence pour les valeurs positives #
##########################################################
50// T+ 1:30 twaData = [50, 50]
41// T+ 2:00 twaData = [50, 50, 35, 35, 35]
soit
Image

Ma problématique pour la mise en oeuvre est la suivante:
Il me faut générer twaData, par quelle méthode obtenir le résultat détaillé ici ('cahier des charges') ?

Pour celui ou ceux qui me répondront ( j'espère ) n'hésitez pas à détailler vos conseils ou bouts de code, je souhaite également comprendre la démarche ça fait quelques soirs voir plus que je mets mes neurones en ébullitions alors autant que la méthode pour obtenir ce que je souhaite rentre et soit comprise

PS: J'oubliais ... je suis ce qu'on appelle un noob ... mon domaine c'est l'électronique marine pas le javascript

Code complet, les commentaires du code concernent uniquement ttw et twa.

Code : Tout sélectionner

"use strict";

const pattern = /updi\(event,'([0-9]{4}-[0-9]{2}-[0-9]{2}) ([0-9]{2}:[0-9]{2}) ([A-Z]{3,4}).*(T[+-]{1}.*?[0-9]{1,}:[0-9]{2}).*<br>Distances:.*?([0-9]{1,}\.[0-9]{1,}nm)\/([0-9]{1,}\.[0-9]{1,}nm)<br><b>Wind:<\/b> ([0-9]*?.*) (.*? kt).*\(<b>TWA(.*?)<\/b>\)<br><b>Heading:<\/b>(.*?)<b>Sail:<\/b>(.*?)<br><b>Boat Speed:<\/b>(.*?)'/g
const points = [];
try {
    Array.prototype.slice.call(document.getElementsByTagName("img")).forEach(function (element) {
        var event = element.getAttribute("onmouseover");
        if (event !== null) {
            var match = pattern.exec(event);

            const date = match[1];
            const time = match[2];
            const timezone = match[3];
            const ttw = match[4]; // ici l'extraction de la valeur ttw de chaque ligne d'instruction
            const dtw = match[5];
            const dtg = match[6];
            const twd = match[7];
            const tws = match[8];
            const twa = match[9]; // ici l'extraction de la valeur twa de chaque ligne d'instruction
            const btw = match[10];
            const sail = match[11];
            const stw = match[12];
		   
            points.push({
                date : date,
                time : time,
                timezone : timezone,
                ttw : ttw, // ici on envoie la valeur extraite
                dtw : dtw,
                dtg : dtg,
                twd : twd,
                tws : tws,
                twa : twa, // idem pour twa
                btw : btw,
                sail : sail,
                stw : stw
           });
            pattern.lastIndex = 0;
        }
    });

var background = chrome.extension.getBackgroundPage();

/* Ce code concerne l'ancienne méthode de calcul de twam (et btwm)
var hour_actu = 0;
var hour_change = 0;
var hour_prec = 0;
var nb_step = 0;

var twam = 0;
var twa_prec = 0;
var tot_twa_prec = 0;
var tot_twa = 0;

var btwm = 0;
var btw_prec = 0;
var tot_btw_prec = 0;
var tot_btw = 0;

var twa_btw_change = 0;
*/

function createCell(value, row) {
    var cell = document.createElement("td");
    cell.innerHTML = value;
    row.appendChild(cell);
}

/* ici c'est juste une modification visuel de la valeur dans le tableau
function ttwStyling(value, cell) {
    cell.align = "left";
    cell.innerHTML = value;
}
*/

function dtwStyling(value, cell) {
    cell.align = "left";
    cell.innerHTML = value;
}

function dtgStyling(value, cell) {
    cell.align = "left";
    cell.innerHTML = value;
}

function twsStyling(value1, value2, cell) {
    var tws_foil = value1.replace(" kt", "");
    var twa_bd = value2.replace("\u00B0", "");
    if (tws_foil >= 11.1 && tws_foil <= 39.9 && Math.abs(twa_bd) >= 71 && Math.abs(twa_bd) <= 169) {
        cell.style.backgroundColor = "black";
        cell.style.color = "white";
    } else {
        cell.style.backgroundColor = "white";
        cell.style.color = "black";
    }
    cell.innerHTML = tws_foil + " kt";
}

/*  Ici la valeur twa est soit négative ou positive, on prends la valeur absolue et on la colore (rouge : négative, vert : positive)
function twaStyling(value, cell) {
    var twa_bd = value.replace("\u00B0", "");
    if (twa_bd >= 0) {
        cell.style.color = "green";
    } else {
        cell.style.color = "red";
    }
    cell.innerHTML = Math.abs(twa_bd) + "\u00B0";
}
*/

function btwStyling(value, cell) {
    cell.style.color = "blue";
    cell.innerHTML = value;
}

function sailStyling(value, cell) {
    switch (value.trim()) {
    // Upwind sail
    case "Jib":
        cell.style.backgroundColor = "#FFD479";
        break;
    case "LJ":
        cell.style.backgroundColor = "#FFFC79";
        break;
    case "Stay":
        cell.style.backgroundColor = "#D4FB79";
        break;
    // Downwind sail
    case "Spi":
        cell.style.backgroundColor = "#76D6FF";
        break;
    case "LG":
        cell.style.backgroundColor = "#7A81FF";
        break;
    case "HG":
        cell.style.backgroundColor = "#D783FF";
        break;
    // Reaching sail
    case "C0":
        cell.style.backgroundColor = "#FF7E79";
        break;
    }
    cell.innerHTML = value;
}

/* Idem que pour valeurs twa
function twamStyling(value, cell) {
    if (value >= 0) {
        cell.style.color = "green";
    } else {
        cell.style.color = "red";
    }
    if (value !== "-") {
        cell.innerHTML = Math.abs(value) + "\u00B0";
    } else {
        cell.style.color = "black";
        cell.innerHTML = value;
    }
}
*/

function btwmStyling(value, cell) {
    cell.style.color = "blue";
    if (value !== "-") {
        cell.innerHTML = value + "\u00B0";
    } else {
        cell.style.color = "black";
        cell.innerHTML = value;
    }
}

function createCellWithCustomStyling(value, row, customStyling) {
    var cell = document.createElement("td");
    customStyling(value, cell);
    row.appendChild(cell);
}

function createCellWithCustomStyling2(value1, value2, row, customStyling) {
    var cell = document.createElement("td");
    customStyling(value1, value2, cell);
    row.appendChild(cell);
}

/* Ancien code pour déterminer twam (il est faux, il faut passer par un calcul trigo)
function calc_nb_ite(value) {
    var delta_t = value.match(/.*?([0-9]{1,}):([0-9]{2})/);
    hour_prec = hour_actu;
    hour_actu = delta_t[1] * 6 + delta_t[2] / 10;
    nb_step = hour_actu - hour_prec;
}

function calc_twam(value) {
    var ss_tot = parseFloat(value.replace("\u00B0", ""));
    tot_twa = tot_twa_prec + (twa_prec * nb_step);
    if (hour_actu === hour_change) {
        twam = "-";
    } else {
        twam = tot_twa / (hour_actu - hour_change);
        twam = Math.round(twam);
    }
    tot_twa_prec = tot_twa;
    twa_btw_change = 0;
    if ((twa_prec * ss_tot) <= 0) {
        tot_twa_prec = 0;
        twa_btw_change = 1;
    }
    twa_prec = ss_tot;
}
*/

var twalist = []; // Raison du topic ( comment alimenter cette variable avec les 3 contraintes du 'cahier des charges' )

/* Nouveau code de calcul twam (trigo)
function twamCalc() {
    const
    twaData = twalist;
    Math.radians = function (degrees) {
        return degrees * Math.PI / 180.0;
    },
    Math.degrees = function (radians) {
        return radians * 180.0 / Math.PI;
    };
 
    let
    arX = [],
    arY = [],
    somX = 0.0,
    somY = 0.0,
    moyX = 0.0,
    moyY = 0.0,
    twam = 0.0;
    
    for (const [i, angle] of twaData.entries()) {
        arX[i] = Math.cos(Math.radians(angle));
        arY[i] = Math.sin(Math.radians(angle));
    }
 
    for (const value of arX) {
	   somX += value;
    }
    moyX = somX / arX.length;
 
    for (const value of arY) {
	   somY += value;
    }
    moyY = somY / arY.length;
 
    twam = Math.round((Math.degrees(Math.atan2(moyY, moyX)) * 10)) / 10;
 
    return twam;
}
*/

function calc_btwm(value) {
    var ss_tot = parseFloat(value.replace("\u00B0", ""));
    // N1
    if (btwm >= 270 && btw_prec <= 90) {
        btw_prec = btw_prec + 360;
    } else {
        if (btwm <= 90 && btw_prec >= 270) {
            btw_prec = btw_prec - 360;
        }
    }
    // End N1
    tot_btw = tot_btw_prec + (btw_prec * nb_step);
    if (hour_actu === hour_change) {
        btwm = "-";
    } else {
        btwm = tot_btw / (hour_actu - hour_change);
        // N2
        if (btwm >= 360) {
            btwm = btwm - 360;
        } else {
            if (btwm < 0) {
                btwm = btwm + 360;
            }
        }
        // End N2
        btwm = Math.round(btwm);
    }
    tot_btw_prec = tot_btw;
    if (twa_btw_change === 1) {
        tot_btw_prec = 0;
        nb_step = 0;
        hour_prec = hour_actu;
        hour_change = hour_actu;
    }
    btw_prec = ss_tot;
}

function reinitializeDisplay() {
    document.getElementById("pointsTable").innerHTML = "";
}

function UtcToLocal(date, time) {
    var utcYear = date.split("-")[0];
    var utcMonth = (date.split("-")[1]) - 1;
    var utcDay = date.split("-")[2];
    var utcHour = time.split(":")[0];
    var utcMinutes = time.split(":")[1];
    var dateUtc = Date.UTC(utcYear, utcMonth, utcDay, utcHour, utcMinutes, 0, 0);
    
    var localDate = new Date(dateUtc);
    var year = localDate.getFullYear();
    var month = ("0" + (localDate.getMonth() + 1)).slice(-2);
    var day = ("0" + localDate.getDate()).slice(-2);
    var hours = ("0" + localDate.getHours()).slice(-2);
    var minutes = ("0" + localDate.getMinutes()).slice(-2);

    var offset = -localDate.getTimezoneOffset();
    var absOffset = Math.abs(offset);
    var sign = (offset > 0) ? "+" : "-";
    var hoursOffset = Math.trunc(absOffset) / 60;
    var MinutesHoursOffset = (hoursOffset === 0) ? "\u00b1" + "0" : sign + hoursOffset;
    var minutesOffset = absOffset % 60;
    var HoursMinutesOffset = (minutesOffset === 0) ? MinutesHoursOffset : sign + hoursOffset + ":" + minutesOffset;

    var formattedDate = year + "-" + month + "-" + day;
    var formattedTime = hours + ":" + minutes;
    var formattedTimeZone = "UTC" + HoursMinutesOffset;
    return [formattedDate, formattedTime, formattedTimeZone];
}

function getTimeZone(timezone) {
    if (timezone === "CET") {
        return "UTC+1";
    } else if (timezone === "CEST") {
        return "UTC+2";
    }
}

function displayTable(localTime) {
    points.forEach(function (element) {
        var row = document.createElement("tr");
        document.getElementById("pointsTable").appendChild(row);
        if ((localTime && element.timezone === "CET") || (localTime && element.timezone === "CEST")) {
            var ceZ = getTimeZone(element.timezone);
            createCell(element.date, row);
            createCell(element.time, row);
            createCell(ceZ, row);
        } else if (localTime && element.timezone === "UTC") {
            var localDTZ = UtcToLocal(element.date, element.time, element.timezone);
            createCell(localDTZ[0], row);
            createCell(localDTZ[1], row);
            createCell(localDTZ[2], row);
        } else {
            createCell(element.date, row);
            createCell(element.time, row);
            createCell(element.timezone, row);
        }
        createCellWithCustomStyling(element.ttw, row, ttwStyling); // creation des cellules ttw avec formatage visuel
        calc_nb_ite(element.ttw); // ancien code pour deteminer twam
        createCellWithCustomStyling(element.dtw, row, dtwStyling);
        createCellWithCustomStyling(element.dtg, row, dtgStyling);
        createCell(element.twd, row);
        createCellWithCustomStyling2(element.tws, element.twa, row, twsStyling);
        createCellWithCustomStyling(element.twa, row, twaStyling); //
        calc_twam(element.twa); // ancien code twam
        createCellWithCustomStyling(element.btw, row, btwStyling);
        calc_btwm(element.btw);
        createCellWithCustomStyling(element.sail, row, sailStyling);
        createCell(element.stw, row);
        createCellWithCustomStyling(twam, row, twamStyling);
        createCellWithCustomStyling(btwm, row, btwmStyling);
        var manifest = chrome.runtime.getManifest();
        document.getElementById("version").innerHTML = manifest.version;
    });
}

var displayLocal = function () {
    reinitializeDisplay();
    if (document.getElementById("localtime").checked) {
        chrome.storage.local.set({"localTime" : true});
        displayTable(true);
    } else {
        chrome.storage.local.set({"localTime" : false});
        displayTable(false);
    }
};

document.getElementById("localtime").addEventListener("change", displayLocal);

chrome.storage.local.get("localTime", function (result) {
    if (result.localTime === true) {
        document.getElementById("localtime").checked = true;
        displayLocal();
    } else {
        document.getElementById("localtime").checked = false;
    }
});
reinitializeDisplay();
var points = background.points[background.currentTab];
displayTable(false);
Voilà y'a tout je peux pas faire mieux ...
Je sais que vous allez pas me donner un code tout fait comme ça ( je suis pas contre ) mais je veux bien des infos / conseils concernant l'approche / la méthode pour y arriver.

Comme dit plus haut, je ne suis pas développeur c'est un métier et pas le miens, mais je cherche (énormément) et j'apprends en même temps, c'est passionnant mais j'ai peu de connaissances d'ou la demande de coup de pouce.

Merci d'avance

Cdlt

Avatar du membre
Frosty
Messages : 123
Enregistré le : 20 juil. 2017, 13:23
Localisation : Grenoble

Re: Calcul angle moyen avec itérations non listés

Message par Frosty » 01 mars 2018, 16:32

Salut,
Comme tu peux le voir il n'y a pas grosse activité ici en ce moment, l'activité du forum a du mal à repartir...
Je me demande si je ne suis pas le seul à regarder les nouveaux sujets de temps en temps, et même si je le fais je n'ai pas toujours le temps d'y répondre...
Pour ma part, je ne t'en voudrai pas si tu cherches des réponses sur un site/forum plus actif.

Cela étant dit, si je comprends bien déjà, l'algorithme est le suivant :

Pour calculer le TWAm d'un temps donné :
- prendre toutes les valeurs de même signe à partir du "temps précédent" (-10 minutes)
- faire la moyenne

Apparemment, tu dois le faire pour toutes les valeurs de TWA de ton tableau (même pour les lignes masquées)
Il faut donc partir sur une simple boucle qui va passer sur toutes les valeurs de TWA pour chaque "temps" (+0:00, +0:10, etc.)
A chaque itération de la boucle, tu peux conserver un tableau avec toutes les valeurs précédentes de même signe
=> Si le tableau est vide (au départ), ou que la dernière valeur est de même signe que la valeur à rajouter, on ajoute un élément au tableau avec la nouvelle valeur (celle de T -10 minutes)
=> Sinon, la dernière valeur du tableau est de signe différent => on vide le tableau et on met seulement la nouvelle valeur de TWA à T -10 minutes
=> A partir des valeurs présentes dans le tableau on fait la moyenne ce qui donnera à chaque itération le TWAm
=> Cas particulier : la 1ère itération (T = +0:00) ou il ne faut rien faire pour TWAm, à la rigueur valoriser à null et à l'affichage mettre "-" si la valeur de TWAm vaut null
Reste à traduire ça en Javascript, je te laisse essayer et j'essayerai de t'aider si tu as des difficultés.

Par curiosité, quel est le critère qui détermine qu'on doit afficher une ligne ou non ?

Arenas
Messages : 11
Enregistré le : 01 mars 2018, 19:54

Re: Calcul angle moyen avec itérations non listés

Message par Arenas » 05 mars 2018, 08:26

Bonjour,

Pour comprendre, utiliser Excel. De là, vous le transforme en scripte.
Merci
@r

Nota bene:
Donne les noms complet des colonne?

GeGaX
Messages : 26
Enregistré le : 20 févr. 2018, 21:56

Re: Calcul angle moyen avec itérations non listés

Message par GeGaX » 15 mars 2018, 15:25

Bonjour,
J’ai pas vu que vous m’aviez répondu, désolé
Je suis en vacs actuellement et j’ai que le téléphone
Lundi je pourrais répondre plus en détails à vos questions car j’ai depuis un peu avancé sur le sujet
Merci de d’avoir pris le temps de me répondre je reviens sur le forum bientôt ;)

GeGaX
Messages : 26
Enregistré le : 20 févr. 2018, 21:56

Re: Calcul angle moyen avec itérations non listés

Message par GeGaX » 18 mars 2018, 15:14

Frosty a écrit :
01 mars 2018, 16:32
Salut Frosty,
Comme tu peux le voir il n'y a pas grosse activité ici en ce moment, l'activité du forum a du mal à repartir...
Je me demande si je ne suis pas le seul à regarder les nouveaux sujets de temps en temps, et même si je le fais je n'ai pas toujours le temps d'y répondre...
Pour ma part, je ne t'en voudrai pas si tu cherches des réponses sur un site/forum plus actif.
Salut Frosty, oui j'ai posté ailleurs ma problématique mais sincèrement j'ai pas eu de réflexion aussi constructive qu'ici pour l'instant ( sauf une autre plateforme et justement je me demande si la méthode mise en oeuvre correspond à mes attentes ...je la détaillerais plus tard )
Frosty a écrit :
01 mars 2018, 16:32
Pour calculer le TWAm d'un temps donné :
- prendre toutes les valeurs de même signe à partir du "temps précédent" (-10 minutes)
- faire la moyenne

Apparemment, tu dois le faire pour toutes les valeurs de TWA de ton tableau (même pour les lignes masquées)
Il faut donc partir sur une simple boucle qui va passer sur toutes les valeurs de TWA pour chaque "temps" (+0:00, +0:10, etc.)
A chaque itération de la boucle, tu peux conserver un tableau avec toutes les valeurs précédentes de même signe
=> Si le tableau est vide (au départ), ou que la dernière valeur est de même signe que la valeur à rajouter, on ajoute un élément au tableau avec la nouvelle valeur (celle de T -10 minutes)
=> Sinon, la dernière valeur du tableau est de signe différent => on vide le tableau et on met seulement la nouvelle valeur de TWA à T -10 minutes
=> A partir des valeurs présentes dans le tableau on fait la moyenne ce qui donnera à chaque itération le TWAm
=> Cas particulier : la 1ère itération (T = +0:00) ou il ne faut rien faire pour TWAm, à la rigueur valoriser à null et à l'affichage mettre "-" si la valeur de TWAm vaut null
C'est de cette réponse constructive dont je parle plus haut, tu as assez bien cerné ce que je dois mettre en oeuvre pour TWAm sauf qu'il me parait pas obligatoire de calculé un TWAm pour une itération non listé.
Frosty a écrit :
01 mars 2018, 16:32
Par curiosité, quel est le critère qui détermine qu'on doit afficher une ligne ou non ?
Les lignes affichées sont les lignes listées du code source du site, j'ai pas besoin d'afficher les lignes non listés ( je pourrais le faire mais ça ne presente pas grand interêt et surtout ça fait énormément de travail en plus.
Mes compétences étant limitées, je souhaite pas partir dans quelque chose que je vais mettre des mois à réaliser ( nan je blague pas en disant des mois ... )
Les colonnes TWAm et BTWm sont des valeurs calculées tout le reste est listé à l'extraction.
Arenas a écrit :
05 mars 2018, 08:26
Bonjour,
Pour comprendre, utiliser Excel. De là, vous le transforme en scripte.
Merci
@r

Nota bene:
Donne les noms complet des colonne?
Salut Arenas,
Oui effectivement Excel peut être une solution mon problème est que je maitrise à la perfection la fonction SI j'en colle partout ... ( J'exagère mais pas tant que ça ... )

Pour le nom des colonnes, les abréviations correspondent à ceci :
Date et time = pas besoin de l'expliquer ;)
TZ = Timezone (fuseau horaire)
TTW = Time To Waypoint (Temps jusqu'au Waypoint à partir de T+ 0:00)
DTW = Distance To Waypoint (Distance du Waypoint à partir de T+ 0:00)
DTG = Distance To Go (Distance restante jusqu'a la ligne d'arrivée ou d'une bouée de parcours)
TWD = True Wind Direction (Direction du vent vrai)
TWS = True Wind Speed (Vitesse du vent vrai)
TWA = True Wind Angle (Angle du vent vrai)
BTW = Bearing To Waypoint (Cap magnétique à suivre pour atteindre le prochain Waypoint)
STW = Speed Through Water ( Vitesse bateau donné par le speedo)


J'espère que ça répond à vos questions ...

GeGaX
Messages : 26
Enregistré le : 20 févr. 2018, 21:56

Re: Calcul angle moyen avec itérations non listés

Message par GeGaX » 18 mars 2018, 16:08

Concernant mon avancement :
On m'a soumis la méthode Map avec laquelle je suis en mesure de générer un combo de valeurs ( twa et btm ) pour une clé ttw (c'est 100% fonctionnelle) et donne ceci :

Code : Tout sélectionner

var myMap = new Map();
var ttwLast = "T+ 0:00";
var twaLast = null;
var btwLast = null;

function space(val) {
    if (val < 10) {
        val = " " + val;
    }
    return val;
}

function genIteNext (ttwCurr) {
    var ttwCurr = ttwCurr.match(/.*?([0-9]{1,3}):([0-9]{2})/);
    var ttwNext = [];
    if ((parseFloat(ttwCurr[2]) + 10) < 60) {
        ttwNext = "T+" + space (parseFloat(ttwCurr[1])) + ":" + ("0" + (parseFloat(ttwCurr[2]) + 10)).slice(-2);
    } else {
        ttwNext = "T+" + space (parseFloat(ttwCurr[1]) + 1) + ":" + ("0" + (parseFloat(ttwCurr[2]) + 10) % 60).slice(-2);
    }
    return ttwNext;
}

for (var i = 0; i < points.length; i++) {
    while (points[i].ttw !== ttwLast) {
        myMap.set (ttwLast, {twaVal : twaLast, btwVal : btwLast} );
        ttwLast = genIteNext(ttwLast);
    }
    ttwLast = points[i].ttw;
    twaLast = points[i].twa;
    btwLast = points[i].btw;
    myMap.set(points[i].ttw, {twaVal : points[i].twa, btwVal : points[i].btw} );
}
console.log(myMap);
Concernant la fonction

Code : Tout sélectionner

genIteNext(ttwCurr)
j'ai deux méthodes pour gérer l'espace pour les heures < 10 et le zero pour les minutes < 10 ...
J'ai pas réussi à utilisé un slice pour les heures sachant qu'elles varient de 1 à 3 caractères et que pour celles avant 10 il faut un espace, je pourrais mettre en oeuvre une fonction

Code : Tout sélectionner

function zero(val) {
    if (val < 10) {
        val = "0" + val;
    }
    return val;
}
pour remplacer le slice(-2) des minutes
Si vous avez des pistes pour uniformiser je prends ( c'est pas très important puisque c'est fonctionnel mais juste pour faire quelque chose de propre )

Là où je me pose des questions c'est que je 'travail' sur une map globale, l'idée de Frosty, de pouvoir gérer ça à chaque ligne est très interessante puisque la boucle pourrait générer les valeurs twa et btw nécessaire aux calculs de TWAm et BTWm à chaque ligne et non en globale à qui je vais devoir trouver un moyen d'attribuer seulement les itérations nécessaires ( je sais pas si vous comprenez bien ce que je veux dire, même moi ça me semble confus ... )

Si vous avez une méthode pour arriver plus facilement à ce que je souhaite je veux bien me creuser la tête pour y arriver ( je ne veux pas un code tout cuit) mais qu'on me guide pour y arriver ( si vous avez le temps et que ma problématique vous intéresse )

Merci, au plaisir de vous lire en espérant que vous serez en mesure de pouvoir m'aider

Kenavo ;)

Avatar du membre
Frosty
Messages : 123
Enregistré le : 20 juil. 2017, 13:23
Localisation : Grenoble

Re: Calcul angle moyen avec itérations non listés

Message par Frosty » 19 mars 2018, 12:43

Salut GeGaX

Merci pour toutes ces précisions, ça a dû te prendre un moment pour les rédiger

Voici quelques conseils / pistes pour essayer de t'orienter.

Le but étant, si j'ai bien suivi, d'adapter un tableau (dont l'affichage est déjà fonctionnel) où il faut rajouter les valeurs calculées TWAm et BTWm pour chaque ligne affichée.

J'ai proposé de calculer toutes les valeurs de TWAm en une boucle qui "accumule dans un tableau" les valeurs de même signe, car les valeurs de TWAm (même si on ne considère que celles qui seront affichées au final) dépendent des valeurs de TWA précédentes (y compris non listées).
On n'est pas obligé de calculer TWAm pour les lignes qui ne seront pas affichées (ça fait l'économie d'un calcul de moyenne :-) ). Mais on peut toujours mettre à jour le tableau accumulé. J'imagine que la logique va être très similaire pour BTWm.

Il y a d'autres solutions, mais de toute façon il faut parcourir au moins une fois toutes les lignes. Par exemple ; boucler sur les lignes à afficher, et pour chaque ligne à afficher, faire une boucle qui revient en arrière pour détecter le précédent changement de signe... Ca me paraît un peu moins optimal et pratique car on fait intervenir 2 boucles (bien que pour l'instant, on cherche juste à faire en sorte que ça fonctionne)

A la fin, si tes données initiales sont dans le tableau "points", le top serait au bout du traitement (et avant affichage), dans ce même tableau d'avoir en plus :
- un champ qui indique si la ligne doit être affichée ou non (s'il n'y est pas déjà avant le calcul de TWAm et BTWm)
- TWAm et BTWm calculés (peut être vide ou absent pour les lignes non affichées)

Comme ça à l'affichage il y a juste besoin de boucler sur le tableau en n'affichant que les lignes qui doivent l'être.

Normalement avec une telle approche tu ne devrais pas avoir besoin de t'embêter à "encoder" / "décoder" les TTW dans une boucle imbriquée dans une autre boucle :-)

Si tu as besoin d'aide sur des points techniques particuliers n'hésites pas

GeGaX
Messages : 26
Enregistré le : 20 févr. 2018, 21:56

Re: Calcul angle moyen avec itérations non listés

Message par GeGaX » 25 mars 2018, 18:23

Frosty a écrit :
19 mars 2018, 12:43
Salut GeGaX
Merci pour toutes ces précisions, ça a dû te prendre un moment pour les rédiger
Salut Frosty ;),
Effectivement ça m'a prit un peu de temps mais c'était un mal necessaire ;).
Frosty a écrit :
19 mars 2018, 12:43
Voici quelques conseils / pistes pour essayer de t'orienter.
Le but étant, si j'ai bien suivi, d'adapter un tableau (dont l'affichage est déjà fonctionnel) où il faut rajouter les valeurs calculées TWAm et BTWm pour chaque ligne affichée.
C'est exactement ça.
Frosty a écrit :
19 mars 2018, 12:43
J'ai proposé de calculer toutes les valeurs de TWAm en une boucle qui "accumule dans un tableau" les valeurs de même signe, car les valeurs de TWAm (même si on ne considère que celles qui seront affichées au final) dépendent des valeurs de TWA précédentes (y compris non listées).
On n'est pas obligé de calculer TWAm pour les lignes qui ne seront pas affichées (ça fait l'économie d'un calcul de moyenne :-) ). Mais on peut toujours mettre à jour le tableau accumulé. J'imagine que la logique va être très similaire pour BTWm.
Oui la méthode sera la même que pour TWAm.
Frosty a écrit :
19 mars 2018, 12:43
Il y a d'autres solutions, mais de toute façon il faut parcourir au moins une fois toutes les lignes. Par exemple ; boucler sur les lignes à afficher, et pour chaque ligne à afficher, faire une boucle qui revient en arrière pour détecter le précédent changement de signe... Ca me paraît un peu moins optimal et pratique car on fait intervenir 2 boucles (bien que pour l'instant, on cherche juste à faire en sorte que ça fonctionne)
J'ai déja une boucle existante, il serait donc possible de l'utiliser plutôt que d'en créer une nouvelle, non ?
Frosty a écrit :
19 mars 2018, 12:43
A la fin, si tes données initiales sont dans le tableau "points", le top serait au bout du traitement (et avant affichage), dans ce même tableau d'avoir en plus :
- un champ qui indique si la ligne doit être affichée ou non (s'il n'y est pas déjà avant le calcul de TWAm et BTWm)
- TWAm et BTWm calculés (peut être vide ou absent pour les lignes non affichées)
Comme ça à l'affichage il y a juste besoin de boucler sur le tableau en n'affichant que les lignes qui doivent l'être.
Normalement avec une telle approche tu ne devrais pas avoir besoin de t'embêter à "encoder" / "décoder" les TTW dans une boucle imbriquée dans une autre boucle :-)
Si tu as besoin d'aide sur des points techniques particuliers n'hésites pas
Ce dernier point j'y réfléchirais au moment où j'y serais, cette approche m'a l'air pas mal du tout il faudra que je murisse tout ça.

GeGaX
Messages : 26
Enregistré le : 20 févr. 2018, 21:56

Re: Calcul angle moyen avec itérations non listés

Message par GeGaX » 25 mars 2018, 18:56

J'ai un peu avancé concernant mon tableau twaList.

Voici le code :

Code : Tout sélectionner

var myMap = new Map();
var ttwLast = "T+ 0:00";
var twaLast = null;
var btwLast = null;
var twaList = [];
//var btwList = [];

function space(val) {
    if (val < 10) {
        val = " " + val;
    }
    return val;
}

function zero(val) {
    if (val < 10) {
        val = "0" + val;
    }
    return val;
}

function genIteNext (ttwCurr) {
    var ttwCurr = ttwCurr.match(/.*?([0-9]{1,3}):([0-9]{2})/);
    var ttwHours = parseInt(ttwCurr[1]);
    var ttwMinutes = parseInt(ttwCurr[2]);
    var ttwNext = [];
    if (ttwMinutes + 10 < 60) {
        ttwNext = "T+" + space (ttwHours) + ":" + zero (ttwMinutes + 10);
    } else {
        ttwNext = "T+" + space (ttwHours + 1) + ":" + zero (ttwMinutes - 50);
    }
    return ttwNext;
}

for (var i = 0; i < points.length; i++) {
    while (points[i].ttw !== ttwLast) {
        myMap.set (ttwLast, {twaVal : twaLast, btwVal : btwLast} );
        ttwLast = genIteNext(ttwLast);
        if (twaList.length !== 0) {         // Ce code devrait faire l'affaire
            if (twaLast * twaList[0] < 0) { // pour générer les valeurs
                twaList = [];               // twa dont j'ai besoin
            }                               // pour " alimenter " la fonction twaCalc
        }                                   //
        twaList.push(twaLast);              //
    }
    ttwLast = points[i].ttw;
    twaLast = points[i].twa;
    btwLast = points[i].btw;
    myMap.set(points[i].ttw, {twaVal : points[i].twa, btwVal : points[i].btw} );
}
Je rencontre cependant un petit souci ... les valeurs twa listées et générées sont formatées de cette manière " -50° " par exemple.
Il me faut supprimer ce " ° " (degrés) mais je vois pas comment m'y prendre dans le code ci dessus ...
Un coup de pouce serait apprécié, merci

Répondre