Forum Liberty Basic France

Général » Confiner une courbe dans un cadre sauf que là, elle en sort...
Le 23/03/2020 à 19h20

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
Hello tout le monde,

C'est plus pour bavarder qu'autre chose, surtout en ces temps de confinement.

Encore passé une après-midi et un bout de matinée là-dessus, c'est fou. mais pour aujourd'hui, ou jusqu'à la prochaine fois, je laisse tomber.

Il doit y avoir une erreur de raisonnement quelque part : il faut afficher des courbes dans une zone bien définie d'un graphicbox, dite "zone utile", afin de laisser, autour de cette zone, la place nécessaire pour dessiner les axes, graduations, unités et valeurs.

Jusque là tout va bien, mes courbes restent dans une zone bien délimitée. Là où ça ne va pas, c'est que cette zone déborde de la zone attribuée, toujours des mêmes cotés et toujours du même débordement. J'ai vérifié dix fois mes équations sans trouver le loup. Quand on ne veut pas voir ?

Après quelques clics sur "série de 20" on en obtient la preuve :



La courbe bleue aurait dû rester dans la zone noire.

Les marges délimitant cette zone sont définies en début de listing, pour qu'on n'ait pas besoin de courir jusqu'à leur emplacement d'utilisation pour les modifier.

Toujours pour éviter de plonger dans les profondeurs du listing, voilà le calcul de la position d'un point sur la grahicbox :
Code VB :
 
        'point 1
        x1=val(tableau$(a,absc))-camin
        y1=val(tableau$(a,c1))-c1min
        x1p=zux+x1*zul/caplage
        y1p=zuy+zuh-y1*zuh/c1plage
 

  • Les points sont dans le tableau tableau$()
  • a est le numéro de la ligne qui contient la donnée
  • absc et c1 sont les numéros identifiant les colonnes où prendre les données
  • x1 et y1 coordonnées réelles du point, telles qu'elles sont consignées dans le tableau
  • x1p et y1p les coordonnées en pixels du même point dans le graphicbox
  • camin : ca pour Courbe de lAbscisse, min pour minima, valeur minimale de x trouvée pour l'abscisse
  • c1min : C pour courbe, 1 pour son numéro, et min pour valeur minimale trouvée pour la courbe 1
  • zu pour "zone utile" :
  • zux et zuy : zu pour "zone utile", et x et y coordonnées de l'origine de la zone d'affichage dans la graphicbox
  • zul : largeur de la zone, en pixels
  • zuh : hauteur de la zone
  • caplage : écart entre min et max de l'axe des abscisses, dans l'unité utilisée par la courbe
  • c1plage : écart entre min et max de la courbe 1


Pas de panique, c'est juste un rapport de proportionnalité assorti d'un déplacement d'origine. Ils auraient dû faire en sorte, et c'est là que se trouve le diabolique de la situation, que la courbe touche les bords du cadre noir sans en sortir.

Voici le listing, pour les curieux. Il n'y a qu'une courbe affichée, même si les tableaux sont dimensionnés pour en recevoir deux, et les valeurs sont recalculées à chaque affichage de courbe, en utilisant rnd(1).

Roland aura constaté, certainement avec bonheur et soulagement, que j'ai abandonné mes sempiternels "print" quand ils sont suivis d'un #quelquechose, et que c'est effectivement plus clair à lire)

Code VB :
 
' affiche trois courbes comprises dans un fichier
'le fichier est ici simulé par un tableau chaine à 3 colonnes

nomainwin
 
'paramètres de départ
    'tableau à 3 colonnes
    nlig=20 'nombre de lignes de données

    'zone d'affichage du graphique
    ms=0.10 'marge supérieure
    mi=0.30 'marge inférieure
    mg=0.10 'marge gauche
    md=0.20 'marge droite
    'exprimés en coefficient (0.00 à 1.00, 1.00 étant la taille du graphicbox)

 
'mise en place de l'environnement graphique

'afficheur de courbes
gbx=50
gby=50
gbl=300
gbh=300
graphicbox #p.gb,gbx,gby,gbl,gbh
button #p.bt, "Série de 20",[tirage1],UL,150,20,100,20
 
'ouvrir la fenetre...
WindowWidth=400
WindowHeight=400
 
open "Essai de graphique" for window as #p
    #p, "trapclose [quitter]"
    gosub [tirage]
    gosub [stats]
    gosub [dessin]
wait
 
 
[tirage1]   'quand on vient de cliquer sur le bouton "série de 20"
    for serie=1 to 20
        gosub [tirage]
        gosub [stats]
        gosub [dessin]
    next
    wait
 
[tirage]
    ncol=3  'nombre de données par lignes
    dim tableau(nlig,ncol)
 
    'remplissage de tableau$() avec des données de test
    for a=0 to nlig-1
        tableau(a,0)=int(rnd(1)*100)
        tableau(a,1)=50-int(rnd(1)*100)
        tableau(a,2)=50-int(rnd(1)*100)
    next
 
    'affectation des colonnes
    absc=0  'colonne qui sera utilisée comme abscisse
    c1=1    'courbe 1
    c2=2    'courbe 2

    'tri du tableau sur la colonne "absc"
    '(le logiciel prévu utilisera une des colonnes pour l'axe des abscisse)
    sort tableau(), 0, nlig-1, absc
 
    'Le tableau qu'on utilisera pour le programme final est un tableau chaine
    'conversion
    dim tableau$(nlig,ncol)
    for a=0 to nlig-1
        for b=0 to ncol-1
            tableau$(a,b)=str$(tableau(a,b))
        next
    next
 
    return
 
[stats]
    'détermination mini, maxi, amplitude des données

    'colonne des abscisses
    minb=0
    maxb=0
    for a=0 to nlig-1
        b=val(tableau$(a,absc))
        if b<minb then minb=b
        if b>maxb then maxb=b
    next
    camin=minb
    camax=maxb
    caplage=abs(camax-camin)
 
    'courbe 1
    minb=0
    maxb=0
    for a=0 to nlig-1
        b=val(tableau$(a,c1))
        if b<minb then minb=b
        if b>maxb then maxb=b
    next
    c1min=minb
    c1max=maxb
    c1plage=abs(c1max-c1min)
 
    'courbe 2
    minb=0
    maxb=0
    for a=0 to nlig-1
        b=val(tableau$(a,c2))
        if b<minb then minb=b
        if b>maxb then maxb=b
    next
    c2min=minb
    c2max=maxb
    c1plage=abs(c1max-c1min)
 
    return
 
[dessin]
    'dessin des courbes

    'dimensions de la zone utile
    zux=gbl*mg
    zuy=gbh*ms
    zul=gbl*(1-md)
    zuh=gbh*(1-mi)
 
    'contrôle dimensions et placement zone utile
    #p.gb, "down"
    #p.gb, "backcolor black"
    #p.gb, "place ";zux;" ";zuy
    #p.gb, "boxfilled ";zul;" ";zuh
    #p.gb, "up"
 
    'adaptation des courbes à la zone utile
    'tracé des courbes
    #p.gb, "down"
    #p.gb, "color cyan"
    for a=0 to nlig-2
 
        'point 1
        x1=val(tableau$(a,absc))-camin
        y1=val(tableau$(a,c1))-c1min
        x1p=zux+x1*zul/caplage
        y1p=zuy+zuh-y1*zuh/c1plage
 
        'point2
        x2=val(tableau$(a+1,absc))-camin
        y2=val(tableau$(a+1,c1))-c1min
        x2p=zux+x2*zul/caplage
        y2p=zuy+zuh-y2*zuh/c1plage
 
        #p.gb, "line ";x1p;" ";y1p;" ";x2p;" ";y2p
 
    next
 
    #p.gb, "up"
    return
 
[quitter]
    close #p
    end
 
 


A vot'bon coeur m'sieudames ;)
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 24/03/2020 à 11h44

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
Je vais essayer de comprendre ton mic mac; c'est très rigolo la courbe qui sort de la graphicbox :D
Mais là-->: http://libertybasic.fr/forum/topic-444+vitesse-et-energie-cinetique.php
Tes courbes restent bien confouinées
Et là aussi-->: http://libertybasic.fr/forum/topic.php?id=419&pt=5
Alors, caisse y se passe ??
Je pense que tu t'es planté dans l'affectation des variables (trop de variables peut nuire à la santé); la graphicbox c'est pas la noire, c'est la blanche ! :|
____________________
Roro

   
Le 24/03/2020 à 20h19

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
Ca y est, c'est rectifié. C'est juste ça qui n'allait pas :
Code VB :
 
[dessin]
    'dessin des courbes

    'dimensions de la zone utile
    zux=gbl*mg
    zuy=gbh*ms
    zul=gbl*(1-md)
    zuh=gbh*(1-mi)
 
    'contrôle dimensions et placement zone utile
    #p.gb, "down"
    #p.gb, "backcolor black"
    #p.gb, "place ";zux;" ";zuy
    #p.gb, "boxfilled ";zul;" ";zuh
    #p.gb, "up"
 
 


et que j'ai remplacé par ça :
Code VB :
 
[dessin]
    'dessin des courbes

    'dimensions de la zone utile
    zux=gbl*mg
    zuy=gbh*ms
    zul=gbl*(1-md-mg)
    zuh=gbh*(1-mi-ms)
 
    'contrôle dimensions et placement zone utile
    #p.gb, "down"
    #p.gb, "backcolor black"
    #p.gb, "place ";zux;" ";zuy
    #p.gb, "boxfilled ";zux+zul;" ";zuy+zuh
    #p.gb, "up"
 
 

Deux erreurs :
  • mg, ms, md, mi pour marge gauche, marge droite, marge supérieure, marge inférieure, marges prévues pour l'affichage des axes et de leurs unités. Le calcul de la longueur et de la largeur de la zone noire ne prenaient en compte qu'une marge au lieu des deux.
  • Il manquait à la longueur et à la hauteur du cadre noir, les coordonnées de son point haut gauche. Les longueurs et largeur étaient donc affichées à partir de l'origine du graphicbox, et non de l'origine de la zone noire.

La courbe dépasse encore d'un pixel, c'est franchement pas ça qui va me gêner pour la suite du projet, il suffit de faire ma zone noire plus grande d'un pixel de chaque côté ou la courbe ciblée sur un pixel de moins de chaque côté de sa zone, mais c'est pas la priorité du moment

J'aurais bien bataillé. Je suis bien rouillé ou je suis pas doué, voire peut-être même les deux. Pour ma défense, je dirais que ce n'était pas là que je cherchais l'erreur.

Version rectifiée :
Code VB :
 
 
' affiche deux courbes comprises dans un fichier, en utilisant une
'troisième colonne du fichier comme axe des abscisses

'le fichier est ici simulé par un tableau chaine à 3 colonnes

nomainwin
 
'paramètres de départ
    'tableau à 3 colonnes
    nlig=20 'nombre de lignes de données

    'zone d'affichage du graphique
    ms=0.10 'marge supérieure
    mi=0.10 'marge inférieure
    mg=0.10 'marge gauche
    md=0.10 'marge droite
    'exprimés en coefficient (0.00 à 1.00, 1.00 étant la taille du graphicbox)

 
'mise en place de l'environnement graphique

'afficheur de courbes
gbx=50
gby=50
gbl=300
gbh=300
graphicbox #p.gb,gbx,gby,gbl,gbh
button #p.bt, "Série de 20",[tirage1],UL,150,20,100,20
 
'ouvrir la fenetre...
WindowWidth=400
WindowHeight=400
 
open "Essai de graphique" for window as #p
    #p, "trapclose [quitter]"
    gosub [tirage]
    gosub [stats]
    gosub [dessin]
wait
 
 
[tirage1]   'quand on vient de cliquer sur le bouton "série de 20"
    for serie=1 to 20
        gosub [tirage]
        gosub [stats]
        gosub [dessin]
    next
    wait
 
[tirage]
    ncol=3  'nombre de données par lignes
    dim tableau(nlig,ncol)
 
    'remplissage de tableau$() avec des données de test
    for a=0 to nlig-1
        tableau(a,0)=int(rnd(1)*100)
        tableau(a,1)=50-int(rnd(1)*100)
        tableau(a,2)=50-int(rnd(1)*100)
    next
 
    'affectation des colonnes
    absc=0  'colonne qui sera utilisée comme abscisse
    c1=1    'courbe 1
    c2=2    'courbe 2

    'tri du tableau sur la colonne "absc"
    '(le logiciel prévu utilisera une des colonnes pour l'axe des abscisse)
    sort tableau(), 0, nlig-1, absc
 
    'Le tableau qu'on utilisera pour le programme final est un tableau chaine
    'conversion
    dim tableau$(nlig,ncol)
    for a=0 to nlig-1
        for b=0 to ncol-1
            tableau$(a,b)=str$(tableau(a,b))
        next
    next
 
    return
 
[stats]
    'détermination mini, maxi, amplitude des données

    'colonne des abscisses
    minb=val(tableau$(0,absc))
    maxb=val(tableau$(0,absc))
    for a=0 to nlig-1
        b=val(tableau$(a,absc))
        if b<minb then minb=b
        if b>maxb then maxb=b
    next
    camin=minb
    camax=maxb
    caplage=abs(camax-camin)
 
    'courbe 1
    minb=val(tableau$(0,c1))
    maxb=val(tableau$(0,c1))
    for a=0 to nlig-1
        b=val(tableau$(a,c1))
        if b<minb then minb=b
        if b>maxb then maxb=b
    next
    c1min=minb
    c1max=maxb
    c1plage=abs(c1max-c1min)
 
    'courbe 2
    minb=val(tableau$(0,c2))
    maxb=val(tableau$(0,c2))
    for a=0 to nlig-1
        b=val(tableau$(a,c2))
        if b<minb then minb=b
        if b>maxb then maxb=b
    next
    c2min=minb
    c2max=maxb
    c1plage=abs(c1max-c1min)
 
    return
 
[dessin]
    'dessin des courbes

    'dimensions de la zone utile
    zux=gbl*mg
    zuy=gbh*ms
    zul=gbl*(1-md-mg)
    zuh=gbh*(1-mi-ms)
 
    'contrôle dimensions et placement zone utile
    #p.gb, "down"
    #p.gb, "backcolor black"
    #p.gb, "place ";zux;" ";zuy
    #p.gb, "boxfilled ";zux+zul;" ";zuy+zuh
    #p.gb, "up"
 
    'adaptation des courbes à la zone utile
    'tracé des courbes
    #p.gb, "down"
    #p.gb, "color cyan"
    for a=0 to nlig-2
 
        'point 1
        x1=val(tableau$(a,absc))-camin
        y1=val(tableau$(a,c1))-c1min
        x1p=zux+x1*zul/caplage
        y1p=zuy+zuh-y1*zuh/c1plage
 
        'point2
        x2=val(tableau$(a+1,absc))-camin
        y2=val(tableau$(a+1,c1))-c1min
        x2p=zux+x2*zul/caplage
        y2p=zuy+zuh-y2*zuh/c1plage
 
        #p.gb, "line ";x1p;" ";y1p;" ";x2p;" ";y2p
 
    next
 
    #p.gb, "up"
    return
 
[quitter]
    close #p
    end
 
 


Voilà ;)
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 25/03/2020 à 11h43

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
Il y a des nombres pour lesquels tu va pouvoir virer les décimales
et d'autres ou elles sont seules représentatives
Bonjour le formatage pour les mises aux échelles.
C'est normal qu'il y ait des nombres négatifs ?

Comme il va y avoir besoin des valeurs et des maximums j'ai fait ça (comme je n'ai pas touché à la première ligne du csv c'est un peu le bazar dans les listbox); mais c'est pour donner des idées:
Code VB :
 
    NOMAINWIN
    WindowWidth = 900: WindowHeight = 550
    UpperLeftX = 10: UpperLeftY = 5
    STATICTEXT #w.stabs, "Abscisse", 40, 20, 100, 20
    LISTBOX #w.abs, abs$(), [abs], 20, 50,130, 140
    STATICTEXT #w.stc1, "Courbe 1", 180, 20, 100, 20
    LISTBOX #w.c1, c1$(), [c1], 170, 50, 120, 140
    STATICTEXT #w.stc2, "Courbe 2", 320, 20, 100, 20
    LISTBOX #w.c2, c2$(), [c2], 310, 50, 120, 140
    TEXTEDITOR #w.te, 20, 200, 300, 100
    STATICTEXT #w.reabs, "Abscisse", 80, 310, 100, 20
    TEXTEDITOR #w.tex1, 20, 335, 200, 150
    STATICTEXT #w.reord, "Ordonnée", 280, 310, 100, 20
    TEXTEDITOR #w.tex2, 225, 335, 200, 150
    TEXTBOX #w.box1, 450, 360, 120, 25
    TEXTBOX #w.box2, 450, 400, 120, 25
    GRAPHICBOX #w.m 450, 50, 400, 300
    OPEN "Help" FOR window_nf AS #w
    #w, "TRAPCLOSE [closeHelp]"
    #w.m  "down;fill white"
    #w.abs, "singleclickselect": #w.c1, "singleclickselect": #w.c2, "singleclickselect"
    name "fg_log_ASK21.csv" as "fg_log_ASK21.txt"
      dim t$(1000): dim tligne$(1000): dim tabu$(1000,1000)
    open "fg_log_ASK21.txt" for input as #g
        while eof(#g)=0
           line input #g, donn$
        wend
        close #g
        lign$=""
        for x=1 to len(donn$)
           lign$=lign$+mid$(donn$,x,1)
           if mid$(donn$,x,1)=chr$(10) then
              n=n+1: tligne$(n)=lign$
              lign$=""
           end if
        next x
          t=0 '   '--------------
          for a=1 to n
            lign$=""
            for b=1 to len(tligne$(a))
            if mid$(tligne$(a),b,1)="," then
              lign$=lign$+"   ": b=b+1
            end if
            lign$=lign$+mid$(tligne$(a),b,1)
          next b
            t=t+1
            t$(t)= lign$ ' tableau des données
        next a
        for x=1 to 10 'rempliss tableaux list
          abs$(x)=word$(t$(1),x): c1$(x)=word$(t$(1),x):  c2$(x)=word$(t$(1),x)
        next x
        #w.abs, "reload": #w.c1 "reload": #w.c2 "reload"
  wait
  [abs]
    #w.abs, "selection? selectedabs$": #w.abs, "selectionindex? indexa"
    #w.te, "Choix abcisse:  ";selectedabs$
    #w.tex1, "!cls"
    for x=1 to t
      #w.tex1, word$(t$(x),indexa)
      absmax=val(word$(t$(x),indexa)): #w.box1, "absmax: ";str$(absmax)
    next x
  wait
  [c1]
    #w.c1, "selection? selectedc1$": #w.c1, "selectionindex? indexc1"
    #w.te, "Courbe 1:  ";selectedc1$; "  F de: ";selectedabs$
    #w.tex2, "!cls"
    for x=1 to t
      #w.tex2, word$(t$(x),indexc1)
      ordomax1=val(word$(t$(x),indexc1)): #w.box2, "ordomax1: ";str$( ordomax1)
    next x
  wait
  [c2]
    #w.c2, "selection? selectedc2$"
    #w.te, "Courbe 2:  ";selectedc2$; "  F de: ";selectedabs$
  wait
  wait
  [closeHelp]
    name "fg_log_ASK21.txt" as "fg_log_ASK21.csv"
    CLOSE  #w
    END
 
____________________
Roro

   
Le 25/03/2020 à 20h37

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
Il est toujours plus court que le mien, même s'il n'a pas d'instructions graphiques.

Pour les idées, j'ai prévu, en effet, d'afficher et de faire des recherches et des calculs à partir des données numériques présentes dans le fichier. Mais il faut déjà que les courbes s'affichent correctement avant de s'attaquer à cet aspect.

Citation:
Il y a des nombres pour lesquels tu va pouvoir virer les décimales
et d'autres ou elles sont seules représentatives
Bonjour le formatage pour les mises aux échelles.
C'est normal qu'il y ait des nombres négatifs ?


Pour les nombres négatifs, oui, du moment qu'ils permettent d'afficher l'intégralité de la courbe dans sa fenêtre, et il y a aussi tout le restant de la vie qui est de l'autre coté du zéro, et on peut en mettre beaucoup en colonnes ;)

Blague à part, dans notre fichier et si je n'en oublie pas, on en trouve dans la vitesse verticale, le braquage de la gouverne de profondeur, et le réglage du trim de profondeur. Les valeurs négatives seront mises en évidence dans la prochaine version par le dessin de l'axe des abscisses.

Pour le formatage, je suis en plein dedans. ça ne devrait pas être compliqué mais il faut réfléchir un peu car il faut afficher sur le même graphique deux courbes aux échelles et unités différentes, par exemple pour mettre en évidence l'action d'un paramètre sur un autre en fonction du temps.

Quant aux nombres à virgule, ils sont un peu saoûlants mais nécessaires pour le débugage, je ne les affiche plus lorsque le bout de code sur lequel je travaille fonctionne.

Le code tel qu'il est à ce jour, en utilisant des listbox :
en version zippée, parce qu'il commence à être un peu long pour faire du copier-coller à partir du forum : lirecsv_0-02a-listbox

et le même en clair, si c'est juste pour regarder :
Code VB :
 
'lecture et affichage des données en fichier csv généré par FlightGear

'préréglages
nomainwin
Version$="0.02a"
'0.01 - mise en place de l'environnement, fonctionnement de l'importation des données
'0.02 - déterminer mini et maxis pour l'affichage basique des courbes, les afficher,
'0.03 - mise à l'échelle, graduation des axes
'0.04 - faire correspondre les colonnes lues avec les unités et nom de données de Flightgear
'0.05 - fonctionnalités diverses
'1.00 - version 0.xx aboutie

'définition de l'interface
'taille de la fenêtre
WindowWidth=1000
WindowHeight=600
 
'menu
MENU #p, "&Actions", "Ouvrir CSV", [ouvrir], | ,"Quitter", [quitter]
 
'visualisation des détails techniques des opérations
TEXTEDITOR #p.te, 10, 325, 965, 180
fontebasefiltre$="!font Liberation_Mono 12"
 
'afficheur de courbes
gbx=500
gby=20
gbl=280
gbh=280
graphicbox #p.gb,gbx,gby,gbl,gbh
 
'lister et choisir les données

'état des indicateurs de courbe
actifabs=0    '1=demande à afficher 0 = ne pas afficher
actifc1=0
actifc2=0
 
'abscisse
STATICTEXT #p.stabs, "Abscisse", 20, 20, 100, 20
LISTBOX #p.abs, liste$(), [abs], 20, 50, 130, 160
 
'courbe 1
STATICTEXT #p.stc1, "Courbe 1", 160, 20, 100, 20
LISTBOX #p.c1, liste$(), [c1], 160, 50, 130, 160
coulC1$="cyan"
 
'courbe 2
STATICTEXT #p.stc2, "Courbe 2", 300, 20, 100, 20
LISTBOX #p.c2, liste$(), [c2], 300, 50, 120, 160
coulC2$="yellow"
 
'ouverture de l'interface
open "Explore CSV FlightGear" for window as #p
 
    'police de caractère du texteditor
    print #p.te, fontebasefiltre$
 
    'état des boutons, combo et texteditor au départ
    gosub [initialisation]
 
    'mode de fonctionnement des listbox
    #p.abs, "singleclickselect"
    #p.c1, "singleclickselect"
    #p.c2, "singleclickselect"
 
    'mode débugage seulement, court-circuite la fenetre de choix de fichier
    gosub [ouvrir]
 
    'quitter par le gadget de fermeture
    print #p, "trapclose [quitter]"
 
wait
 
'fin du programme
end
 
'********* sous programmes ********

' **** initialisation

[initialisation]
 
    'abscisse

    'courbe 1

    'courbe 2

    'informations au lancement
    print #p.te, "<Lire-CSV-FlightGear>, version ";Version$
    print #p.te, "Création de graphiques à partir de données de vol"
    print #p.te, ""
    print #p.te, "Menu "+chr$(34)+"Actions/ouvrir CSV"+chr$(34)+" pour charger un fichier de données"
 
    return
 
[ouvrir]
    print #p.te, "sp [ouvrir] : ouvrir un fichier csv FlightGear"
 
    'ouverture fichier :
    FILEDIALOG "Choisir un fichier csv de FlightGear (*.csv) ", "*.csv;*.txt", chemin$
    print #p.te, "chemin$=";chemin$
 
    'si pas de sélection par l'utilisateur
    if chemin$="" then
        print #p.te, "Annulation de l'opération par l'utilisateur"
    else
        fichier$="":car$=""
        tr=len(chemin$)
        fin=0
        while fin=0
            car$=mid$(chemin$,tr,1)
            if car$="/" or car$="\" or tr<1 then fin=1 else fichier$=car$+fichier$
            tr=tr-1
        wend
        print #p.te,"Fichier sélectionné : ";fichier$
        print #p.te,"Chemin : ";left$(chemin$,tr)
        gosub [explorer_fichier]
        gosub [preparer_affichage_donnees]
 
    end if
wait
 
[explorer_fichier]
 
    'on ne peut pas utiliser LINE INPUT car le fichier à lire vient du monde UNIX
    'on lit donc caractère par caractère jusqu'à trouver la fin de ligne
    'on stocke les caractères dans une chaine
    'on compte les virgules dans la ligne, on ajoute 1 pour le nombre de donnée

    open chemin$ for input as #fic
    print #p.te,""
 
    'déterminer le nombre de colonnes présentes dans le fichier
    'lecture caractère par caractère pour raisons de compatibilité avec le monde Linux
    arreter=0
    virgule=0
    while arreter=0
        car$=input$(#fic,1)
        if car$=chr$(44) then virgule=virgule+1
        if car$=chr$(10) then findeligne=1
        if eof(#fic)=-1 or findeligne=1 then arreter=1
    wend
 
    'déterminer le nombre de lignes de données dans le fichier
    nombredelignes=0
    while eof(#fic)=0
        if input$(#fic,1)=chr$(10) then nombredelignes=nombredelignes+1
    wend
    close #fic
 
    nombredecolonnes=virgule+1
 
    'créer le tableau multidimensionnel
    dim lefichier$(nombredelignes+1,nombredecolonnes)
 
    'remplir le tableau avec les données du fichier
    ligne=0
    colonne=0
    mot$=""
        'for x=1 to 10 'rempliss tableaux list
        '  abs$(x)=word$(t$(1),x): c1$(x)=word$(t$(1),x):  c2$(x)=word$(t$(1),x)
        'next x
    open chemin$ for input as #fic
    while eof(#fic)=0
 
        car$=input$(#fic,1)
 
        if car$<>chr$(10) then      'nous ne sommes pas au bout de la ligne
            if car$=chr$(44) then   'virgule, le mot précédent la virgule est terminé
                lefichier$(ligne,colonne)=mot$
                mot$=""
                colonne=colonne+1
            else    'on complète le mot
                mot$=mot$+car$
            end if
 
        else    'on change de ligne
            lefichier$(ligne,colonne)=mot$
            mot$=""
            ligne=ligne+1
            colonne=0
        end if
    wend
    close #fic
 
    return
 
[preparer_affichage_donnees]
 
    '
    'ajouter l'item "--rien--" qui permettra de désafficher une courbe
    dim liste$(nombredecolonnes+1)
    liste$(0)="-- rien --"
 
    'puis ajouter les titres de colonne
    for a=1 to nombredecolonnes
        liste$(a)=lefichier$(0,a-1)
    next
 
    'mise à jour des listbox
    #p.abs, "reload"
    #p.c1, "reload"
    #p.c2, "reload"
 
    return
 
 
[afficher_les_données]
'   NE PAS OUBLIER pour l'aspect graphique :
    'créer le segment, afficher le segment, et effacer le segment avant le dessin d'une nouvelle courbe
#p.te,""
#p.te,"dessin des courbes"
    'paramétrer la zone d'affichage
    ms=0.10 'marge supérieure
    mi=0.10 'marge inférieure
    mg=0.10 'marge gauche
    md=0.10 'marge droite
    'exprimés en coefficient (0.00 à 1.00)

    'd'ou il ressort que les dimensions de la zone utile seront
    zux=gbl*mg
    zuy=gbh*ms
    zul=gbl*(1-md-mg)
    zuh=gbh*(1-mi-ms)
 
    'peindre en noir la zone utile
    gosub [effacer_graphe]
 
    'pour afficher les deux courbes simultanément,
    'il faut connaître leurs valeurs mini et maxi
    'on ne garde que le plus petit mini et le plus grand maxi
    'garder le plus petit mini

    's'il y a deux courbes
    if actifc1=1 and actifc2=1 then
        if minC1<minC2 then ming=minC1 else ming=minC2  'garder le plus petit mini
        if maxC1>maxC2 then maxg=maxC1 else maxg=maxC2  'garder le plus grand maxi
        plageg=abs(maxg-ming)   'calculer l'amplitude
    end if
 
    's'il n'y a que c1
    if actifc1=1 and actifc2=0 then
        ming=minC1:maxg=maxC1:plageg=plageC1
    end if
 
    's'il n'y a que c2
    if actifc1=0 and actifc2=1 then
        ming=minC2:maxg=maxC2:plageg=plageC2
    end if
 
    'dessin courbe 1
    if actifc1=1 then
        #p.gb, "down"
        #p.gb, "color ";coulC1$
        for a=1 to nombredelignes-2
 
            'point 1
            x1=val(lefichier$(a,indexa-2))-minabscis
            y1=val(lefichier$(a,index1-2))-ming
            x1p=zux+x1*zul/plageabsis
            y1p=zuy+zuh-y1*zuh/plageg
 
            'point2
            x2=val(lefichier$(a+1,indexa-2))-minabscis
            y2=val(lefichier$(a+1,index1-2))-ming
            x2p=zux+x2*zul/plageabsis
            y2p=zuy+zuh-y2*zuh/plageg
 
            #p.gb, "line ";x1p;" ";y1p;" ";x2p;" ";y2p
 
        next
        #p.gb, "up"
    end if
 
    'dessin courbe 2
    if actifc2=1 then
        #p.gb, "down"
        #p.gb, "color ";coulC2$
        for a=1 to nombredelignes-2
 
            'point 1
            x1=val(lefichier$(a,indexa-2))-minabscis
            y1=val(lefichier$(a,index2-2))-ming
            x1p=zux+x1*zul/plageabsis
            y1p=zuy+zuh-y1*zuh/plageg
 
            'point2
            x2=val(lefichier$(a+1,indexa-2))-minabscis
            y2=val(lefichier$(a+1,index2-2))-ming
            x2p=zux+x2*zul/plageabsis
            y2p=zuy+zuh-y2*zuh/plageg
 
            #p.gb, "line ";x1p;" ";y1p;" ";x2p;" ";y2p
 
        next
        #p.gb, "up"
    end if
    return
 
 
[effacer_graphe]
    #p.gb, "down"
    #p.gb, "backcolor black"
    #p.gb, "place ";zux;" ";zuy
    #p.gb, "boxfilled ";zux+zul;" ";zuy+zuh
    #p.gb, "up"
    return
 
' **** lister les données et décider de les afficher

[abs]     'choisir l'axe des abscisses

    #p.abs, "selection? selectedabs$"
    #p.te, "Choix abcisse : ";selectedabs$ 
    #p.abs, "selectionindex? indexa"
    #p.te, "index sélectionné :"; indexa;
 
    If indexa>1 then
 
        colabs=indexa-2 'numéro de la colonne de données sélectionnée

        'prm$(numéro de colonne, première donnée, dernière donnée de colonne)
        minabscis=val(word$(prm$(colabs,1,nombredelignes),1,":"))
        maxabscis=val(word$(prm$(colabs,1,nombredelignes),2,":"))
        plageabsis=val(word$(prm$(colabs,1,nombredelignes),3,":"))
 
        'le choix de l'abscisse est fait
        actifabs=1
 
    else
        'on n'a pas choisi d'abscisse
        actifabs=0
    end if
 
    'le choix
    gosub [ok_pour_dessin]
    wait
 
 
[c1]      'choisir la colonne de données pour la courbe 1
    #p.c1, "selection? selectedc1$"
    #p.te, "Courbe 1:  ";selectedc1$; "  F de: ";selectedabs$
    #p.c1, "selectionindex? index1"
    #p.te, "index sélectionné :"; index1
    if index1>1 then
 
    '    'on détermine les mini/maxis
        colc1=index1-2
 
        'prm$(numéro de colonne, première donnée, dernière donnée de colonne)
        minC1=val(word$(prm$(colc1,1,nombredelignes),1,":"))
        maxC1=val(word$(prm$(colc1,1,nombredelignes),2,":"))
        plageC1=val(word$(prm$(colc1,1,nombredelignes),3,":"))
 
        'le choix de la courbe 1 est fait
        actifc1=1
 
    else
        'on ne dessinera pas la courbe 1
        actifc1=0
    end if
 
    gosub [ok_pour_dessin]
    wait
 
 
[c2]      'choisir la colonne de données pour la courbe 2
    #p.c2, "selection? selectedc2$"
    #p.te, "Courbe 2:  ";selectedc2$; "  F de: ";selectedabs$
    #p.c2, "selectionindex? index2"
    #p.te, "index sélectionné :"; index2
 
    if index2>1 then
 
        'on détermine les mini/maxis
        colc2=index2-2
 
        'prm$(numéro de colonne, première donnée, dernière donnée de colonne)
        minC2=val(word$(prm$(colc2,1,nombredelignes),1,":"))
        maxC2=val(word$(prm$(colc2,1,nombredelignes),2,":"))
        plageC2=val(word$(prm$(colc2,1,nombredelignes),3,":"))
 
        'le choix de la courbe 2 est fait
        actifc2=1
    else
         'on ne dessinera pas la courbe 2
        actifc2=0
    end if
 
    gosub [ok_pour_dessin]
    wait
 
 
[ok_pour_dessin]
    #p.te, "[ok_pour_dessin]"
    #p.te, "abscisse : ";actifabs;", courbe 1 :";actifc1;", courbe 2 : ";actifc2
    if actifabs>0 then
        if actifc1+actifc2>0 then gosub [afficher_les_données]
    end if
    return
 
' **** quitter

[quitter]
    close #p
    end
 
' **** fonctions

function prm$(index,debut,fin)
 
    min=val(lefichier$(debut,index))
    max=min
 
    for a=debut to fin
        d=val(lefichier$(a,index))
        if d<min then min=d
        if d>max then max=d
    next
 
    amplitude=max-min
    prm$=str$(min);":";str$(max);":";str$(amplitude)
 
end function
 
 


Dans cette version, lorsque deux courbes sont affichées, on se base sur la plus grande des plus grandes données et sur la plus petite des plus petites données pour que l'ensemble tienne dans le cadre, d'autres représentations sont à l'étude.

Je rencontre encore des divisions par zéro : ça doit etre le problème des données inexistantes, celles qui dans le fichier sont repérables à deux virgules consécutives : ce n'est ni 0, ni "espace", c'est "inexistant". Elles n'existent pas car le système qui génère ces colonnes n'était pas actif au moment de l'enregistrement. Il s'agit des colonnes "V cible" et "Pitch", paramètres du pilote automatique.

habituellement on laisse l'abscisse à la colonne "time", mais si on choisit Altitude pour abscisse, vitesse verticale en courbe 1 et vitesse air pour la courbe 2, on obtient un drôle de résultat, certes insensé physiquement parlant, mais tout à fait juste informatiquement ;) ;)

J’arrête ma prose avant de me surprendre à m'écouter écrire,

Bonne soirée
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 26/03/2020 à 10h48

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
Citation:
mettre en évidence l'action d'un paramètre sur un autre en fonction du temps.

Pour afficher trois paramètres sur un graphique à deux dimensions (abcisse-ordonnée) tu a le choix entre:
A): Ecrire le troisième param sur la courbe du second et l'expliciter en cartouche; ex: temps en abcisse, vitesse en courbe rouge, et trim en nombres vert sur la courbe.
B): Mettre deux (ou plusieurs) échelles aux couleurs des courbes concernées
Citation:
Je rencontre encore des divisions par zéro

Pour JB, "0.446534", c'est zéro.
Il doit y avoir une procédure spéciale pour qu'il prenne le nombre tel qu'il est), du genre:
% : entier signé
! : décimal simple précision (short IEEE) => par défaut dans les vieux Basic si rien n'est précisé.
# : décimal double précision (long IEEE)
A creuser...
____________________
Roro

   
Le 26/03/2020 à 13h18

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
Désolé d'être aussi bavard... j'en rajoute encore une tranche ;)

Citation:
Pour JB, "0.446534", c'est zéro.

Serions-nous le premier avril ? Avec un VAL() devant, multiplie-le par 10 ou 2.33 et tu verra si c'est zéro ;)

Je pencherais davantage pour une donnée inexistante dans mon fichier texte, et qui par ma programmation, se retrouve considérée comme un zéro, à tort.

Quant à la précision des calculs, je ne sais pas trop quoi penser. A priori, et ça m'a toujours un peu étonné, il n'est pas nécessaire de spécifier la précision quand on définit une variable.

Je ne connais pas la cuisine interne du compilateur, mais dans le code ci-dessous, je suis descendu jusqu'à 20 chiffres après la virgule, puis monté à20 chiffres avant la virgule, et par un procédé inverse j'ai retrouvé mes deux nombres de départ, et ça n'aurait pas été possible s'il avait pris les 8 ou 16 premiers chiffres et tronqué la suite.

Ceci dit, je suis pas matheux, et j'ai qu'un vague aperçu de ces histoires de précision, et du moment que les variables et calculs que j'utilise couramment me donnent les résultats attendus, ça me va bien.

Le listing de test :

Code VB :
 
essais=20
 
n1=12.54
n2=27.264
print "voyage vers l'infiniment petit "
for a=1 to essais
    r=n1+n2
    print a;"  :  ";n1;"+";n2;"=";r
    n1=n1/13
    n2=n2/13
next
 
'prendre en compte le pas de plus qui n'est pas affiché
'du fait de la structure de la boucle
n1=n1*13
n2=n2*13
print
 
print "et revenir à notre époque :"
for a=essais to 1 step-1
    r=n1+n2
    print a;"  :  ";n1;"+";n2;"=";r
    n1=n1/13
    n2=n2/13
next
 
n1=12.54
n2=27.264
print
print "voyage vers l'infiniment grand :"
for a=1 to essais
    r=n1+n2
    print a;"  :  ";n1;"+";n2;"=";r
    n1=n1*13
    n2=n2*13
next
 
'prendre en compte le pas de plus qui n'est pas affiché
'du fait de la structure de la boucle
n1=n1/13
n2=n2/13
print
 
print "et revenir à notre époque :"
for a=essais to 1 step-1
    r=n1+n2
    print a;"  :  ";n1;"+";n2;"=";r
    n1=n1/13
    n2=n2/13
next
 
 
 


Citation:
Pour afficher trois paramètres sur un graphique à deux dimensions (abcisse-ordonnée)

C'est un peu comme ça que je le voyais aussi, et ça va son petit train peinard, ça devrait être pas mal une fois terminé.
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 26/03/2020 à 13h52

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
Citation:
Serions-nous le premier avril ? Avec un VAL() devant, multiplie-le par 10 ou 2.33 et tu verra si c'est zéro

Je ne me rappelle pas à quelle occasion ça m'est arrivé, mais ça m'est arrivé. (peut-être avec des str$ et val successifs ?)

Ton histoire ça pas être simple vu la disparité des données et le nombre de paramètres.
J'ai voulu prendre le soft de voltige, mais purée 1,6Go y en a pour la semaine avec le débit dont je dispose.

EDIT: Je pense que tu a intérêt à faire des tableaux pour chaque paramètre.
____________________
Roro

   
Le 28/03/2020 à 02h09

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
En effet, j'y ai pensé, on gagnerait en rapidité puisqu'il n'y aurait plus à faire la conversion chaine vers nombre pour chaque donnée. Ce serait jouable pour les colonnes du graphique, mais d'un intérêt limité, puisque si l'on veut afficher une nouvelle courbe, il faudra préalablement la récupérer dans le tableau chaine, copie du fichier sous forme exploitable, et donc convertir des chaines en nombres.

De toutes manière, les données issues d'un fichier étant des caractères, on sera obligé de passer à un moment ou à un autre par une conversion. Mais, faut voir et je n'ai pas encore vu, il y a peut-être des différences de temps de traitement en fonction de l'endroit où on fait la conversion.

Pour l'accès aux données, le plus commode serait effectivement un tableau par colonne, et là, on ferait dès le chargement la conversion chaine vers nombre, et on n'aurait plus besoin de convertir les données au moment de les afficher. Le problème est qu'on ne peut pas générer un nombre quelconque de tableaux : on est obligé d'avoir une liste de DIM() préétablie, et le jour où il en manque une, eh bien on est coincé : c'est en cela que le tableau multidimensionnel est très souple, il est un peu plus difficile à manipuler, mais on créée autant de colonnes qu'on veut.

Citation:
J'ai voulu prendre le soft de voltige

Bienvenue au club ;) on peut aussi y faire de la voltige. Au lancement, si c'est la première fois qu'on se trouve dans un lieu donné, il télécharge aussi les scènes, c'est une particularité de FlightGear; Si tu parles bien de FlightGear ;)

Citation:
Je ne me rappelle pas à quelle occasion ça m'est arrivé, mais ça m'est arrivé.

Comme moi hier, on en fait des bonnes : j'étais persuadé que la casse n'avait pas d'importance dans LB/JB, et que "a" valait "A", et j'ai mis un bout de temps à comprendre que non, et que si mon programme ne marchait plus, c'est pas à cause de ma modif, mais parce que j'y avais écrit courbeC1 au lieu de courbec1

a+, l'est déjà deux heures du mat...
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 28/03/2020 à 10h08

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
Citation:
différences de temps de traitement en fonction de l'endroit où on fait la conversion.

Le temps dépend plutôt du nombre de fois qu'on converti
Citation:
et le jour où il en manque une, eh bien on est coincé

Ajouter un tableau ou modifier un tableau, c'est pareil, ça fait toucher au code.
Citation:
j'étais persuadé que la casse n'avait pas d'importance

Si tu utilise "c" et "C", une bande apparaît en bas qui te demande si c'est la même variable.
____________________
Roro

   
Le 28/03/2020 à 14h04

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
Citation:
Citation:
différences de temps de traitement en fonction de l'endroit où on fait la conversion.


Le temps dépend plutôt du nombre de fois qu'on converti


En fait, à notre niveau, il n'y a que le bon sens et l'essai de plusieurs solutions pour garder la plus rapide, on n'a aucune idée de ce qui se trame derrière le compilateur, il est donc difficile d'optimiser "au jugé".

Citation:
Ajouter un tableau ou modifier un tableau, c'est pareil, ça fait toucher au code.

Non, parce qu'on ne s'est pas compris : si je dimensionne dix tableaux et que j'en ai soudain besoin de vingt, je dois modifier le programme en créant les dix tableaux supplémentaires.

si je prend un tableau multidimensionnel et que j'ai besoin de 8 colonne, je précise à mon programme que a=8, et je l'envoie faire un dim tableau(x,a), et j'ai mes 8 colonnes.
Le contexte change et j'ai soudain besoin de 20 colonnes, je précise a=20, je l'envoie faire un dim tableau(x,a), et j'ai mes 20 colonnes. Il n'y a pas de modification du programme, et on peut l'écrire pour qu'il s'adapte de lui-même au nombre de colonnes qu'il doit traiter.

l'inconvénient que je trouve aux tableaux multidimensionnels, c'est que la lecture du code est plus compliquée Par exemple,
Code VB :
 
r=valeurs(5,6)/valeurs(5,7)
 

fait la même chose que
Code VB :
 
r=tension(5)/intensite(5)
r=U(5)/I(5)
 

Avec le multidimensionnel, je dois me souvenir que j'ai défini la colonne 6 comme étant la tension, et la colonne 7 comme étant l'intensité. Peut-être qu'un jour, avec l'évolution de JB/LB on pourra définir des alias permettant d'utiliser des noms plutôt que des numéros de colonne, mais pour le moment il faut mémoriser le nom du paramètre assigné à la colonne, ou avoir son petit calepin à côté de soi

Citation:
Si tu utilise "c" et "C", une bande apparaît en bas qui te demande si c'est la même variable.


C'est grâce à elle que j'ai réalisé que quelque chose n'allait pas ;) En fait, c'est juste une info, j'ai pas vu de bouton pour valider le fait que c'était la même variable. Le clic droit m'a apporté une seule option, "hide", j'ai essayé, et hop, plus de bande ! Mais alors comment la faire réapparaitre ? En faisant "run", probablement...
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 28/03/2020 à 15h52

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
Citation:
Avec le multidimensionnel, je dois me souvenir que j'ai défini la colonne 6 comme étant la tension, et la colonne 7 comme étant l'intensité

Tu a mis le doigt dessus.
r=tension(5)/intensite(5) est tellement plus "reposant".
____________________
Roro

   
Le 08/04/2020 à 19h51

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
Donc voici deux exemples qui font la même chose, l'un avec un tableau multidimensionnel, l'autre avec trois tableaux distincts :

La version avec le tableau multidimensionnel
Code VB :
 
'*** formatage d'un nombre
'
'formatage en milions, miliers, unités, milli...

 
[u]
data "G:9:Giga","M:6:Méga","k:3:kilo"," :0: ","m:-3:milli","µ:-6:micro"
data "n:-9:nano","p:-12:pico","f:-15:femto"
 
du=9    'nombre de définitions de multiples
dim multiples$(du,3)
 
restore [u]
for a=0 to du-1
    read a$
    multiples$(a,0)=word$(a$,1,":")
    multiples$(a,1)=word$(a$,2,":")
    multiples$(a,2)=word$(a$,3,":")
next
 
print:print "liste des multiples disponibles :"
for a=0 to du-1
    print tab(3);multiples$(a,2);tab(10);multiples$(a,0);tab(13);multiples$(a,1)
next
print
 
input "entrer un nombre : ";pgn
 
'recherche de la position du premier chiffre significatif
nb=pgn
en=0
fin=0
if pgn>=1 then
    while fin=0
        if nb>10 then nb=nb/10:en=en+1 else fin=1
    wend
else
    while fin=0
        if nb<1 then nb=nb*10:en=en-1 else fin=1
    wend
end if
 
'détermination de la tranche de multiple à laquelle appartient l'exposant
te=0
for a=0 to du-2
    if en<val(multiples$(a,1)) and en>=val(multiples$(a+1,1)) then te=a+1
next
 
'formatage du nombre
pgnn=pgn*10^(0-val(multiples$(te,1)))
mltps$=multiples$(te,0)
mltpn$=multiples$(te,2)
 
'et affichage d'icelui
print pgn;" s'écrit : ";nb;"*10^";en;" ou ";pgnn;" ";mltps$;" ou ";pgnn;" ";mltpn$
 
 


Et la version avec trois tableaux
Code VB :
 
'*** formatage d'un nombre
'
'formatage en milions, miliers, unités, milli...

 
[u]
data "G:9:Giga","M:6:Méga","k:3:kilo"," :0: ","m:-3:milli","µ:-6:micro"
data "n:-9:nano","p:-12:pico","f:-15:femto"
 
du=9    'nombre de définitions de multiples
dim symbolmulti$(du),expomulti$(du),nommulti$(du)
 
restore [u]
for a=0 to du-1
    read a$
    symbolmulti$(a)=word$(a$,1,":")
    expomulti(a)=val(word$(a$,2,":"))
    nommulti$(a)=word$(a$,3,":")
next
 
print:print "liste des multiples disponibles :"
for a=0 to du-1
    print tab(3);nommulti$(a);tab(10);symbolmulti$(a);tab(13);expomulti(a)
next
print
 
input "entrer un nombre : ";pgn
 
'recherche de la position du premier chiffre significatif
nb=pgn
en=0
fin=0
if pgn>=1 then
    while fin=0
        if nb>10 then nb=nb/10:en=en+1 else fin=1
    wend
else
    while fin=0
        if nb<1 then nb=nb*10:en=en-1 else fin=1
    wend
end if
 
'détermination de la tranche de multiple à laquelle appartient l'exposant du nombre
te=0
for a=0 to du-2
    if en<expomulti(a) and en>=expomulti(a+1) then te=a+1
next
 
'formatage du nombre
pgnf=pgn*10^(0-expomulti(te))
mltps$=symbolmulti$(te)
mltpn$=nommulti$(te)
 
'et affichage d'icelui
print pgn;" s'écrit : ";nb;"*10^";en;" ou ";pgnf;" ";mltps$;" ou ";pgnf;" ";mltpn$
 


Le but ici n'était pas de mettre au point les programmes : l'instruction INPUT attend une série de chiffres suivi d'un <enter>, et entrer une lettre plutôt qu'un chiffre a bloqué l'appli, il a fallu faire l'équivalent d'un ctrl-alt-suppr pour la tuer et reprendre la main. Honnêtement, je ne sais pas pourquoi, il semble si facile d'entrer par erreur une lettre.

Au moins, on a l'illustration du mérite comparé des deux modes de fonctionnement des tableaux ;)
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 09/04/2020 à 09h19

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
On peut aussi mettre le nombre en chaine et analyser la chaine en dehors de toute considération mathématique.

Citation:
entrer une lettre plutôt qu'un chiffre a bloqué l'appli, il a fallu faire l'équivalent d'un ctrl-alt-suppr pour la tuer

Bah il faut mettre une procédure de vérification de validité (on appelle ça "sécuriser" ?).
Comme quand on met un "if var$="" then [passer]; pour éviter une division par zéro si la var$ est exploitée en nombre.

Tu en es où avec tes courbes, moi je me perds dans les valeurs d'échelles. :hot
____________________
Roro

   
Le 09/04/2020 à 14h46

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
Surprenant quand même qu'INPUT soit si fragile, il y a peut-être eu autre chose en simultané (je n'ai pas cherché à reproduire le bug).

Pour les courbes, j'ai réglé le problème d'échelle, et j'en suis à déterminer automatiquement le nombre de graduation pour qu'on ait un affichage pas fouillis et des étiquettes du genre "2" "2.25" "2.5" et pas "1.98" "2.70" "3.42", l'amplitude de la courbe posant elle-même les limites de l'affichage.

ça avance à son rythme...
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 09/04/2020 à 15h00

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
Citation:
j'en suis à déterminer automatiquement le nombre de graduation pour qu'on ait un affichage pas fouillis et des étiquettes du genre "2" "2.25" "2.5" et pas "1.98" "2.70" "3.42"


C'est pas simple, j'ai le cerveau qui fume là dessus.
____________________
Roro

   
Le 10/04/2020 à 12h21

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
Faut y aller pas à pas...

Pour le moment j'ai ça :
Code VB :
 
mini=-55
maxi=1210
 
'pour afficher des nombres ronds en face des graduations
'on choisit, de mini ou maxi, celui qui est le plus grand en valeur absolue
if abs(mini)>abs(maxi) then pgd=abs(mini) else pgd=abs(maxi)
 
'on détermine la quantité de chiffres de ce nombre
fin=0
chiffre=0
nbre=pgd
while fin=0
    if nbre>1 then nbre=nbre/10 : chiffre=chiffre+1 else fin=1
wend
print pgd;" contient ";chiffre;" chiffres"
 
'cette quantité de chiffres est aussi la puissance de dix du premier chiffre rencontré
'cette puissance de dix permet le calcul du pas,
pas=10^(chiffre-2)
ymin=int(mini/pas)*pas  'y plus petite valeur de graduation affichée
ymax=int(maxi/pas)*pas  'y plus grande "    "   "   "   "   "   "

'si le nombre de pas est plus grand que ce qu'on désire afficher
'on multiplie la valeur du pas par 2 jusqu'à obtenir la quantité
'de pas compatible avec l'affichage
fin=0
nbgradmax=10    'nombre maxi souhaité de graduations
stopper=0       'sortir de la boucle si je me suis gouré dans les calculs
amplitude=ymax-ymin
while fin=0
    if amplitude/pas>nbgradmax then pas=pas*2 else fin=1
    stopper=stopper+1
    if stopper>20 then fin=1
wend
 
'se baser sur le zéro pour afficher les graduations
zer0=int(mini/pas)*pas
zer1=int(maxi/pas)*pas
 
'résultat : afficher les graduations
print:print "mini du graphique : ";mini:print
print "graduations sur l'axe y :"
for a=zer0 to zer1 step pas
    print a
next
print:print "maxi du graphique : ";maxi:print
 


Il reste encore à formater le nombre de la graduation pour obtenir un affichage au rythme de 1, 10, ou 100 (plus de trois chiffres bouffe de la place sur le graphique et n'est pas forcément lisible)
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 10/04/2020 à 16h20

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
Pour test, y a un gloups:
Code VB :
 
 NOMAINWIN
    WindowWidth = 615: WindowHeight = 440
    UpperLeftX = 10: UpperLeftY = 20
    TEXTBOX  #w.min, 20 , 20, 80, 25
    TEXTBOX  #w.max, 20 , 50, 80, 25
    GRAPHICBOX #w.m 5, 5, 600, 400
    OPEN "Help" FOR window_nf AS #w
    #w, "TRAPCLOSE [closeHelp]"
    #w.m  "down;fill darkgreen;color white; backcolor darkgreen"
     x=50: y=350
      for a=1 to 50 '---ligne abcisse
        #w.m, "line ";x;" ";y;" ";x+520;" ";y
      next a
      for a=1 to 50 '---ligne ordonnée
        #w.m, "line ";x;" ";y;" ";x;" ";y-270
      next a
'----------------------------
mini=-55
maxi=1210
#w.min, str$(mini): #w.max, str$(maxi)
'pour afficher des nombres ronds en face des graduations
'on choisit, de mini ou maxi, celui qui est le plus grand en valeur absolue
if abs(mini)>abs(maxi) then pgd=abs(mini) else pgd=abs(maxi)
 
'on détermine la quantité de chiffres de ce nombre
fin=0
chiffre=0
nbre=pgd
while fin=0
    if nbre>1 then nbre=nbre/10 : chiffre=chiffre+1 else fin=1
wend
print pgd;" contient ";chiffre;" chiffres"
 
'cette quantité de chiffres est aussi la puissance de dix du premier chiffre rencontré
'cette puissance de dix permet le calcul du pas,
pas=10^(chiffre-2)
ymin=int(mini/pas)*pas  'y plus petite valeur de graduation affichée
ymax=int(maxi/pas)*pas  'y plus grande "    "   "   "   "   "   "

'si le nombre de pas est plus grand que ce qu'on désire afficher
'on multiplie la valeur du pas par 2 jusqu'à obtenir la quantité
'de pas compatible avec l'affichage
fin=0
nbgradmax=10    'nombre maxi souhaité de graduations
stopper=0       'sortir de la boucle si je me suis gouré dans les calculs
amplitude=ymax-ymin
while fin=0
    if amplitude/pas>nbgradmax then pas=pas*2 else fin=1
    stopper=stopper+1
    if stopper>20 then fin=1
wend
 
'se baser sur le zéro pour afficher les graduations
zer0=int(mini/pas)*pas
zer1=int(maxi/pas)*pas
 
'résultat : afficher les graduations
print:print "mini du graphique : ";mini:print
print "graduations sur l'axe y :"
for a=zer0 to zer1 step pas
    print a
    #w.m, "place ";x-40;" ";y:  #w.m, "\ ";a
    y=y-pas
next
print:print "maxi du graphique : ";maxi:print
  wait
  [closeHelp]
    CLOSE  #w
    END
 
____________________
Roro

   
Le 10/04/2020 à 20h52

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
Normal, tu as pris les valeurs à afficher comme si elles étaient déjà des pixels, tu as oublié de les convertir avant de les afficher.

Avec cette correction, ça devrait être bon :
Code VB :
 
'résultat : afficher les graduations
print:print "mini du graphique : ";mini:print
print "graduations sur l'axe y :"
ytotal=y-70
for a=zer0 to zer1 step pas
    print a
    y=350-a*ytotal/(maxi-mini)
    #w.m, "place ";x-40;" ";y:  #w.m, "\ ";a
    'y=y-pas

next
 


Juste avant la boucle j'ai ajouté ytotal=y-70
  • Le 70 indique le début de l'axe dans le repère "fenêtre JB/lB" ou la fin de celui-ci dans le repère "graphique"
  • <y> reste celui que tu as défini avant l'ouverture de la fenêtre
  • ytotal constitue la longueur de l'axe vertical du graphique.

et j'ai intégré cet ytotal dans le calcul de la position des graduations : 350-a*ytotal/(maxi-mini)
  • 350- parce que l'orientation de l'axe est inversé
  • a*ytotal/(maxi-mini) est la simple application du produit en croix (valeur à afficher)/(amplitude des valeurs)=(pixels à afficher)/(amplitude en pixels)




Edité par Christophe Le 10/04/2020 à 20h53
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 11/04/2020 à 01h13

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
Nickel chrome ! :) :) :)
____________________
Roro

   
Général » Confiner une courbe dans un cadre sauf que là, elle en sort...  

 |  |

1 Utilisateur en ligne : 0 Administrateur, 0 Modérateur, 0 Membre et 1 Visiteur
Utilisateur en ligne : Aucun membre connecté
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie