Pas de dépendances
#include <math.h> #include <sdl/sdl.h> #define XRES 800 #define YRES 600 #define MINX -2.0 #define MINY -3.0 #define MAXX 5.0 #define MAXY 4.0 #define NBCONTROL 4 #ifdef WIN32 #pragma comment(lib,"sdl.lib") #pragma comment(lib,"sdlmain.lib") #endif typedef struct { double x,y; } ControlPoint; ControlPoint Clist[NBCONTROL]; 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); } int Re_to_EcrX(double r) { return (int)(XRES*(r-MINX)/(MAXX-MINX)); } int Re_to_EcrY(double r) { int y = (int)(YRES*(r-MINY)/(MAXY-MINY)); y = YRES - y - 1; return y; } double Ecr_to_ReX(int i) { return MINX + i*(MAXX-MINX)/XRES; } double Ecr_to_ReY(int i) { return MAXY - i*(MAXY-MINY)/YRES; } void ShowAxis(SDL_Surface* screen) { int centreX = Re_to_EcrX(0.0); int centreY = Re_to_EcrY(0.0); Line(screen,centreX,0,centreX,YRES-1,0xFFFFFF); // axe vertical Line(screen,0,centreY,XRES-1,centreY,0xFFFFFF); // axe horizontal } void ShowControlPoints(SDL_Surface* screen) { int i; for(i=0;i<NBCONTROL;i++) { int x = Re_to_EcrX(Clist[i].x); int y = Re_to_EcrY(Clist[i].y); Line(screen,x-5,y-5,x+5,y+5,0xFF0000); Line(screen,x+5,y-5,x-5,y+5,0xFF0000); } } void InitCpoints() // je place les points de controle arbitrairement autour d'un cercle fictif { int i; for(i=0;i<NBCONTROL;i++) { double t = 0.15 + (i*3.0/NBCONTROL); Clist[i].x = cos(t); Clist[i].y = sin(t); } } void Casteljau(double t,ControlPoint* tab,int nbpoints,double* rx,double* ry) { ControlPoint subtab[NBCONTROL]; int i; if (nbpoints == 1) { *rx = tab[0].x; *ry = tab[0].y; return; } for(i=0;i<nbpoints-1;i++) { subtab[i].x = t*tab[i].x + (1-t)*tab[i+1].x; subtab[i].y = t*tab[i].y + (1-t)*tab[i+1].y; } Casteljau(t,subtab,nbpoints-1,rx,ry); } void ShowBezier(SDL_Surface* screen,double tstep,unsigned long couleur) { double t = 0.0; int lastx = 0; int lasty = 0; int x,y; double rx = 0.0; double ry = 0.0; int i = 0; while(t<=1.0) { Casteljau(t,Clist,NBCONTROL,&rx,&ry); x = Re_to_EcrX(rx); y = Re_to_EcrY(ry); if (i!=0) Line(screen,x,y,lastx,lasty,couleur); lastx = x; lasty = y; t+=tstep; i++; } } void CheckMouseDeplace(Sint32 mousex,Sint32 mousey,char boutons[8]) { int i; if (boutons[SDL_BUTTON_LEFT]==0) return; for(i=0;i<NBCONTROL;i++) { int x = Re_to_EcrX(Clist[i].x); int y = Re_to_EcrY(Clist[i].y); if (abs(mousex-x)<=10 && abs(mousey-y)<=10) { Clist[i].x = Ecr_to_ReX(mousex); Clist[i].y = Ecr_to_ReY(mousey); return; } } } int main(int argc,char** argv) { Sint32 mousex = 0; Sint32 mousey = 0; char boutons[8] = {0}; char key[SDLK_LAST] = {0}; SDL_Surface* screen; SDL_Init(SDL_INIT_VIDEO); screen=SDL_SetVideoMode(XRES,YRES,32,SDL_SWSURFACE|SDL_DOUBLEBUF); SDL_ShowCursor(1); InitCpoints(); while(!key[SDLK_ESCAPE]) { SDL_FillRect(screen,NULL,0); UpdateEvents(&mousex,&mousey,boutons,key); if (SDL_MUSTLOCK(screen)) SDL_LockSurface(screen); CheckMouseDeplace(mousex,mousey,boutons); ShowAxis(screen); ShowControlPoints(screen); ShowBezier(screen,0.002,0x00FF00); if (SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen); SDL_Flip(screen); } return 0; }
No explanations yet.