Tracer des formes.

Cercles, disques, boites...

Bresenham

Voir version :

Pas de dépendances

Télécharger :

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <sdl/sdl.h>

#ifdef WIN32
#pragma comment(lib,"sdl.lib")
#pragma comment(lib,"sdlmain.lib")
#endif

void UpdateEvents(Sint32* mousex,Sint32* mousey,char boutons[8],char key[SDLK_LAST])
{
    SDL_Event event;
    while(SDL_PollEvent(&event))
    {
        switch (event.type)
        {
        case SDL_KEYDOWN:
            key[event.key.keysym.sym]=1;
            break;
        case SDL_KEYUP:
            key[event.key.keysym.sym]=0;
            break;
        case SDL_MOUSEMOTION:
            *mousex=event.motion.x;
            *mousey=event.motion.y;
            break;
        case SDL_MOUSEBUTTONDOWN:
            boutons[event.button.button]=1;
            break;
        case SDL_MOUSEBUTTONUP:
            boutons[event.button.button]=0;
            break;
        }
    }
}

void SDL_PutPixel32(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
    Uint8 *p = (Uint8*)surface->pixels + y * surface->pitch + x * 4;
    *(Uint32*)p = pixel;
}

Uint32 SDL_GetPixel32(SDL_Surface *surface, int x, int y)
{
    Uint8 *p = (Uint8*)surface->pixels + y * surface->pitch + x * 4;
    return *(Uint32*)p;
}

void Line(SDL_Surface* surf,int x1,int y1, int x2,int y2,Uint32 couleur)  // Bresenham
{
    int x,y;
    int Dx,Dy;
    int xincr,yincr;
    int erreur;
    int i;

    Dx = abs(x2-x1);
    Dy = abs(y2-y1);
    if(x1<x2)
        xincr = 1;
    else
        xincr = -1;
    if(y1<y2)
        yincr = 1;
    else
        yincr = -1;

    x = x1;
    y = y1;
    if(Dx>Dy)
    {
        erreur = Dx/2;
        for(i=0;i<Dx;i++)
        {
            x += xincr;
            erreur += Dy;
            if(erreur>Dx)
            {
                erreur -= Dx;
                y += yincr;
            }
            SDL_PutPixel32(surf,x, y,couleur);
        }
    }
    else
    {
        erreur = Dy/2;
        for(i=0;i<Dy;i++)
        {
            y += yincr;
            erreur += Dx;
            if(erreur>Dy)
            {
                erreur -= Dy;
                x += xincr;
            }
            SDL_PutPixel32(surf,x, y,couleur);
        }
    }
    SDL_PutPixel32(surf,x1,y1,couleur);
    SDL_PutPixel32(surf,x2,y2,couleur);
}

void HorizLine(SDL_Surface* surf,int x1,int y1, int x2,Uint32 couleur)  // a noter que Line gere ça aussi
{
    int i;
    for(i=x1;i<=x2;i++)
        SDL_PutPixel32(surf,i,y1,couleur);
}

void VertLine(SDL_Surface* surf,int x1,int y1, int y2,Uint32 couleur)  // a noter que Line gere ça aussi
{
    int i;
    for(i=y1;i<=y2;i++)
        SDL_PutPixel32(surf,x1,i,couleur);
}

void Box(SDL_Surface* surf,int x1,int y1, int x2,int y2,Uint32 couleur)
{
    HorizLine(surf,x1,y1,x2,couleur);
    HorizLine(surf,x1,y2,x2,couleur);
    VertLine(surf,x1,y1,y2,couleur);
    VertLine(surf,x2,y1,y2,couleur);
}

void Bar(SDL_Surface* surf,int x1,int y1, int x2,int y2,Uint32 couleur)
{
    int i,j;
    for(i=x1;i<=x2;i++)
        for(j=y1;j<=y2;j++)
            SDL_PutPixel32(surf,i,j,couleur);
}


void Circle(SDL_Surface* surf,int x1,int y1, int radius,Uint32 couleur)
{
    // inspiré de http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/bresenham.html
    int d,x,y,x2m1,max;
    y=radius;
    d= -radius;
    x2m1= -1;
    max = (int)(radius/sqrt(2.0));
    for(x=0;x<=max;x++)
    {  
        x2m1 += 2;
        d+= x2m1;
        if (d>=0) 
        {
            y--;
            d -= (y<<1);
        }
        SDL_PutPixel32(surf,x1+x,y1+y,couleur);
        SDL_PutPixel32(surf,x1-x,y1+y,couleur);
        SDL_PutPixel32(surf,x1+x,y1-y,couleur);
        SDL_PutPixel32(surf,x1-x,y1-y,couleur);
        SDL_PutPixel32(surf,x1+y,y1+x,couleur);
        SDL_PutPixel32(surf,x1-y,y1+x,couleur);
        SDL_PutPixel32(surf,x1+y,y1-x,couleur);
        SDL_PutPixel32(surf,x1-y,y1-x,couleur);
    }
    
}

void Disc(SDL_Surface* surf,int x1,int y1, int radius,Uint32 couleur)
{
    int x,y,d,stepd,max;
    y=radius;
    d= -radius;
    stepd= -1;
    max = (int)(radius/sqrt(2.0));
    for(x=0;x<=max;x++)
    {  
        stepd += 2;
        d+= stepd;
        if (d>=0) 
        {
            y--;
            d -= (y<<1);  /* Must do this AFTER y-- */
        }
        HorizLine(surf,x1-x,y1+y,x1+x,couleur);
        HorizLine(surf,x1-x,y1-y,x1+x,couleur);        
        HorizLine(surf,x1-y,y1+x,x1+y,couleur);
        HorizLine(surf,x1-y,y1-x,x1+y,couleur);        
    }
    
}


int main(int argc,char** argv)
{
    Sint32 mousex = 0;
    Sint32 mousey = 0;
    char boutons[8] = {0};
    char key[SDLK_LAST] = {0};
    SDL_Surface* screen;
    int choix,X,Y;
    Uint32 pixel;
    X = 800;
    Y = 600;
    srand(time(NULL));
    SDL_Init(SDL_INIT_VIDEO);
    screen=SDL_SetVideoMode(X,Y,32,SDL_SWSURFACE|SDL_DOUBLEBUF);  
    SDL_ShowCursor(1);
    choix=0;
    while(!key[SDLK_ESCAPE])
    {
        UpdateEvents(&mousex,&mousey,boutons,key);
        if (SDL_MUSTLOCK(screen))
            SDL_LockSurface(screen);
        if (boutons[SDL_BUTTON_LEFT])
        {
            boutons[SDL_BUTTON_LEFT] = 0;
            choix++;
            if (choix>7)
                choix=0;
        }
        pixel = SDL_MapRGBA(screen->format,rand()%256,rand()%256,rand()%256,0);
        switch (choix)
        {
        case 0:
            SDL_PutPixel32(screen,rand()%X,rand()%Y,pixel);
            break;
        case 1:
            Line(screen,rand()%X,rand()%Y,rand()%X,rand()%Y,pixel);
            break;
        case 2:
            HorizLine(screen,rand()%X,rand()%Y,rand()%X,pixel);
            break;
        case 3:
            VertLine(screen,rand()%X,rand()%Y,rand()%Y,pixel);
            break;
        case 4:
            Box(screen,rand()%X,rand()%Y,rand()%X,rand()%Y,pixel);
            break;
        case 5:
            Bar(screen,rand()%X,rand()%Y,rand()%X,rand()%Y,pixel);
            break;
        case 6:
            Circle(screen,rand()%(X-100)+50,rand()%(Y-100)+50,rand()%50,pixel);
            break;
        case 7:
            Disc(screen,rand()%(X-100)+50,rand()%(Y-100)+50,rand()%50,pixel);
            break;

        default:
            break;

        }
        if (SDL_MUSTLOCK(screen))
            SDL_UnlockSurface(screen);        
        SDL_Flip(screen);
    }
    return 0;
}





Commentaires


  Cliquez pour faire afficher de nouvelles formes.

  Rien de spécial a ajouter : j'utilise beaucoup de Random.

  Le cerle (et le disque) utilisent un algo de Bresenham pour les cercles. J'ai mis un lien dessus.


Laissez un commentaire / post a comment