IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SDL Discussion :

Problème affichage horloge (encore :) )


Sujet :

SDL

  1. #1
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    713
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 713
    Par défaut Problème affichage horloge (encore :) )
    Hello tout le monde,

    Toujours sur mes tests d'affichage d'horloge (ça progresse lentement, j'ai aussi d'autres choses à faire), j'ai un souci d'affichage. Par rapport à mon post précédent, j'ai décidé (provisoirement) que l'affichage de l'aiguille me suffisait. Mon problème est autre, et je n'ai pas la capacité de le solutionner.

    Commençons par deux print screens:
    Nom : 0187.png
Affichages : 64
Taille : 3,6 Ko Nom : 0186.png
Affichages : 58
Taille : 3,7 Ko

    On peut s'apercevoir que la distance entre la fin de l'aiguille et le cercle qui indique les minutes est différente entre les deux images, et que l'aiguille ne pointe pas exactement sur le centre du disque (moins important). Je suis (quasiment) certain que le problème vient du calcul de la variable r dans la fonction DisplayWatch(), mais j'ai besoin d'aide pour le résoudre.

    Voici le code au complet, mais vous pouvez ignorer les lignes 36 à 82, elles ont fait leurs preuves.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    #include <math.h>
    #include <time.h>
    #include <stdio.h>
    #include <stdbool.h>
    #include <sdl2/sdl.h>
     
    #define WND_SIZE_HORZ               600
    #define WND_SIZE_VERT               600
    #define WND_COLOR_R                 50
    #define WND_COLOR_G                 100
    #define WND_COLOR_B                 150
    #define WND_TITLE                   "Test degree"
    #define RDR_DEFAULT_DRIVER          -1
    #define UNUSED(x)                   (void)x
     
    #define R(x)                        ((x)>>16)
    #define G(x)                        (((x)>>8) & 0xff)
    #define B(x)                        ((x) & 0xff)
    #define TO_SDL_OPAQUE_COLOR(color)  (SDL_Color){R(color), G(color), B(color), SDL_ALPHA_OPAQUE}
     
    #define PI                          3.14159265358979323846
    #define RAY                         100
    #define DISK_RAY                    6
    #define DISK_COLOR_1                0x808080
    #define DISK_COLOR_5                0xf0f0f0
    #define BG_COLOR                    0x326496
    #define TORADIAN(x)                 ((x)*(PI/180))
     
     
    struct minute_disks {
        SDL_Texture *p1;                // le disque pour les minutes
        SDL_Texture *p5;                // le disque pour les multiples de 5 minutes
    };
     
     
    void DisplaySDLVersion(void) {
        SDL_version v;
        SDL_GetVersion(&v);
        printf("SDL version %hd.%hd.%hd\n", v.major, v.minor, v.patch);
    }
     
     
    void HorzLine(SDL_Surface *dest, int x, int y, int w, int thickness, Uint32 color) {
        SDL_Rect r={.x=x, .y=y, .w=w, .h=thickness};
        SDL_FillRect(dest, &r, color);
    }
     
     
    void DrawFilledCircle(SDL_Surface *dest, int cx, int cy, int ray, Uint32 color) {
        for(int x=0, y=ray, d=3-(2*ray); y>=x; ++x) {
            HorzLine(dest, cx-x, cy-y, 2*x+1, 1, color);
            HorzLine(dest, cx-x, cy+y, 2*x+1, 1, color);
            HorzLine(dest, cx-y, cy-x, 2*y+1, 1, color);
            HorzLine(dest, cx-y, cy+x, 2*y+1, 1, color);
            if(d<0)
                d+=4*x+6;
            else {
                d+=4*(x-y)+10;
                --y;
            }
        }
    }
     
     
    SDL_Surface *CreateFilledCircle(int diameter, Uint32 bg_color, Uint32 fg_color) {
        SDL_Surface *circle;
     
        circle=SDL_CreateRGBSurface(0, diameter, diameter, 32, 0, 0, 0, 0);
        SDL_FillRect(circle, NULL, bg_color);
        DrawFilledCircle(circle, diameter/2, diameter/2, diameter/2-1, fg_color);
     
        return(circle);
    }
     
    void CreateMinutesPoint(SDL_Renderer *rdr, struct minute_disks *m) {
        SDL_Surface *tmp=CreateFilledCircle(DISK_RAY-1, BG_COLOR, DISK_COLOR_1);
        m->p1=SDL_CreateTextureFromSurface(rdr, tmp);
        SDL_FreeSurface(tmp);
        tmp=CreateFilledCircle(DISK_RAY, BG_COLOR, DISK_COLOR_5);
        m->p5=SDL_CreateTextureFromSurface(rdr, tmp);
        SDL_FreeSurface(tmp);
    }
     
     
    void DisplayWatch(SDL_Renderer *rdr, SDL_Point *center, struct minute_disks *d) {
        for(int a=0; a<360; a+=6) {
            SDL_Rect r;
            r.x=center->x+cos(TORADIAN(a))*RAY;
            r.y=center->y+sin(TORADIAN(a))*RAY;
            r.w=r.h=DISK_RAY;
            SDL_Texture *tx=a%5 ? d->p1 : d->p5;
            SDL_RenderCopy(rdr, tx, NULL, &r);
        }
    }
     
     
    int main(int argc,char *argv[]) {
        UNUSED(argc);
        UNUSED(argv);
    //  DisplaySDLVersion();
        SDL_Init(SDL_INIT_VIDEO);
        SDL_Window *wnd=SDL_CreateWindow(WND_TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WND_SIZE_HORZ, WND_SIZE_VERT, SDL_WINDOW_SHOWN);
        SDL_Renderer *rdr=SDL_CreateRenderer(wnd, RDR_DEFAULT_DRIVER, SDL_RENDERER_ACCELERATED);
        SDL_Point center={.x=WND_SIZE_HORZ/2, .y=WND_SIZE_VERT/2};
        struct minute_disks minutes_point;
        CreateMinutesPoint(rdr, &minutes_point);
     
     
    //  time_t tstart=time(NULL);
        int r=0;
        while(true) {
            SDL_SetRenderDrawColor(rdr, R(BG_COLOR), G(BG_COLOR), B(BG_COLOR), SDL_ALPHA_OPAQUE);
            SDL_RenderClear(rdr);
            DisplayWatch(rdr, &center, &minutes_point);
            SDL_SetRenderDrawColor(rdr, 0xff, 0xff, 0xff, SDL_ALPHA_OPAQUE);
            SDL_RenderDrawLine(rdr, center.x, center.y, center.x+cos(TORADIAN(r))*(RAY-10), center.x+sin(TORADIAN(r))*(RAY-10));
            SDL_RenderPresent(rdr);
            SDL_Event event;
            if(SDL_PollEvent(&event))
                if(event.type==SDL_QUIT || (event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE))
                    break;
            SDL_Delay(125);
    //      while(time(NULL)-tstart<1);
    //      tstart=time(NULL);
            r+=360/60;
            if(r>=360)
                r=0;
        }
     
        SDL_DestroyTexture(minutes_point.p1);
        SDL_DestroyTexture(minutes_point.p5);
        SDL_DestroyRenderer(rdr);
        SDL_DestroyWindow(wnd);
        SDL_Quit();
     
        return(0);
    }
    D'avance merci pour votre aide,

    Edgar;

    Edit: orthographe
    On écrit "J'ai tor[B]t[/B]" ; "tor[B]d[/B]" est la conjugaison du verbre "tordre" à la 3[SUP]ème[/SUP] personne de l'indicatif présent ;)

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 026
    Billets dans le blog
    135
    Par défaut
    Bonjour,

    Sans regarder en détail le code, je ne pense pas que ce soit un problème de DisplayWatch(). Mon hypothèse serait que en réalité, les cercles que vous dessinez, sont dessiner à partir du coin haut gauche. Par conséquent, leur centre réel est décalé.
    Si j'arrive à être plus clair : le centre de l'horloge est en position 80, 80 (par exemple) et vous dessinez le cercle à droite (celui des trois heures) à la position 80, 80, alors son centre sera en 80, 80 + le rayon du cercle. Par conséquent, l'aiguille est surement bien placé, mais pas les cercles.
    Cela me semble se confirmer si on regarde le centre de l'horloge (le début de l'aiguille) par rapport au cercle des trois heures. On voit (si on trace une ligne) que cela tombe sur la première ligne (ligne haute) du cercle.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    713
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 713
    Par défaut
    @LittleWhite: je n'y avais pas pensé (la preuve, ce post). Mais oui, il faut positionner les cercles par rapport au coin supérieur gauche, pas par rapport à leur centre. Je teste et je reviens donner des nouvelles ce week-end. Un gand merci.
    On écrit "J'ai tor[B]t[/B]" ; "tor[B]d[/B]" est la conjugaison du verbre "tordre" à la 3[SUP]ème[/SUP] personne de l'indicatif présent ;)

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 139
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 139
    Billets dans le blog
    4
    Par défaut
    En voyant l'aiguille qui tend vers la gauche (l'écart à gauche et à droite entre l'aiguille et les points sont bien différents) me fait directement penser à un problème d'arrondis à cause de divisions entières.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

Discussions similaires

  1. Affichage horloge digitale durant une animation
    Par madaroums1 dans le forum ActionScript 3
    Réponses: 2
    Dernier message: 18/11/2016, 21h03
  2. Réponses: 1
    Dernier message: 21/04/2011, 14h14
  3. Affichage horloge
    Par rgdu86 dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 05/08/2008, 19h45
  4. [fieldset] Encore un affichage différent IE et FF
    Par kriekbellevue dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 28/07/2007, 18h32
  5. [Composant] Affichage d'un horloge
    Par etiennegaloup dans le forum Composants
    Réponses: 6
    Dernier message: 10/09/2005, 22h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo