Ohjelma siis piirtää ns. Bezier-käyrän. Tietääkseni tätä ei ole ennen näkynyt vinkeissä, joten nyt olisi aika sille.
Bezier-käyrää käytetään monenlaisissa ohjelmissa kuvankäsittelyohjelmista 3d-työkaluihin (ainakin Blender). Idea on melko yksinkertainen:
http://en.wikipedia.org/wiki/Bézier_curve
Siellä on myös jonkinlaista koodia, mutta ajattelin laittaa sen SDL:lle. Sivulla on animaatioita jotka selventävät mukavasti koodissa olevaa alkukommenttia.
Sanokaa jos jokin on pielessä tai on toivomisen varaa, tämä on ensimmäinen koodivinkkini... Ja muistakaa SDL-linkkeri :)
#include "SDL/SDL.h" /* Bezier-kurvi. Tätä koodia saa käyttää aivan vapaasti jos tarvitsee. Ohjelma laskee käyrän kolmen pisteen avulla: 1.Aloituspiste 2."taivutuspiste" 3.lopetuspiste. Niiden väliin voisi kuvitella kaksi suoraa. Kummastakin otetaan jokin kohta, esim. puoliväli. Niiden pisteiden väliin piirretään viiva, jonka puoliväliin piirretään jälleen piste. Kyseinen piste on käyrän keskipiste. Kun valitaan tarpeeksi kohtia, esim. 1/1000,2/1000 jne. aina täyteen 1000/1000 asti, saadaan käyrä näkyviin.*/ /* Käyttöohje. Jos mitään näppäintä ei ole pohjassa, "taivutuspiste" seuraa hiirtä. Vasen näppäin pohjass alkupiste seuraa hiirtä. Oikea näppäin ja loppupiste seuraa. Rullasta lisätään ja vähennetään tarkkuutta. Punainen=alkupiste Vihreä="taivutuspiste" Sininen=loppupiste*/ const int SCREEN_WIDTH = 800; const int SCREEN_HEIGHT = 600; const int SCREEN_BPP = 32; SDL_Surface *screen = NULL; int p1x,p2x,p3x,p1y,p2y,p3y,am; //Käyrän pää,"taivutuspiste",toinen pää ja viivan tarkkuus. SDL_Surface* CLS(SDL_Surface *scr){ //CLS int ul; for(ul=0;ul<800*600;ul++) { ((unsigned int*)scr->pixels)[ul]=0x000000; } return scr; } void bezier(int xs,int ys,int x,int y,int xe,int ye,int amount) //bezier-funktio { double tempx1,tempy1,tempx2,tempy2,tempx3,tempy3; //Muutama väliaikainen. tempx1=xs; //Käyrän piirrossa tarvittavan tempy1=ys; //viivan tekoon. tempx3=xs; //Piste mihin piirretään. tempy3=ys; tempx2=x; //Viivan toinen pää. tempy2=y; int xx; for (xx=0; xx<amount; xx++) //Jaetaan käyrä amount-määrään pisteitä { ((unsigned int*)screen->pixels)[int(tempx3)+int(tempy3)*800]=0xffffff; //piirretään tempx1+=double(x-xs)/amount; //viivan päätä liikutetaan tempy1+=double(y-ys)/amount; tempx2+=double(xe-x)/amount; //toista päätä liikutetaan tempy2+=double(ye-y)/amount; tempx3=(tempx1*(amount-xx)+(tempx2*xx))/amount; //Piste piirretään viivalle tempy3=(tempy1*(amount-xx)+(tempy2*xx))/amount; } } void cursor(int x, int y, int col) //ei liity kurviin...piirtää bezierissä käytetyt pisteet. { ((unsigned int*)screen->pixels)[x+y*800]=col; if(x>0){((unsigned int*)screen->pixels)[x-1+y*800]=col;} if(x<799){((unsigned int*)screen->pixels)[x+1+y*800]=col;} if(y>0){((unsigned int*)screen->pixels)[x+y*800-800]=col;} if(y<599){((unsigned int*)screen->pixels)[x+y*800+800]=col;} } int main(int argc, char* args[]) { if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 ) { return 1; } screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE ); int mouse,mx,my,ml,mr,ms; p1x=100; p1y=100; //pistetään nyt jotkin aloituskoordinaatit... p2x=400; p2y=300; p3x=700; p3y=500; am=500; //ja viivan tarkkuus. while(1) { SDL_Event event; while (SDL_PollEvent(&event)) { mouse=SDL_GetMouseState(&mx, &my); switch (event.type) { case SDL_KEYDOWN: break; case SDL_KEYUP: // If escape is pressed, return (and thus, quit) if (event.key.keysym.sym == SDLK_ESCAPE) return 0; break; case SDL_MOUSEBUTTONDOWN: if (event.button.button==SDL_BUTTON_LEFT) ml=1; if (event.button.button==SDL_BUTTON_RIGHT) mr=1; if (event.button.button==SDL_BUTTON_WHEELUP){ ms=1;} else if (event.button.button==SDL_BUTTON_WHEELDOWN){ ms=-1;} else{ ms=0;} break; case SDL_MOUSEBUTTONUP: if (event.button.button==SDL_BUTTON_LEFT) ml=0; if (event.button.button==SDL_BUTTON_RIGHT) mr=0; break; case SDL_QUIT: return(0); } } if (ml==1) //säädöt ohjelman sisällä {p1x=mx;p1y=my;} else if (mr==1) {p3x=mx;p3y=my;} else {p2x=mx;p2y=my;} am+=ms*50; ms=0; CLS(screen); bezier(p1x,p1y,p2x,p2y,p3x,p3y,am); //funktiokutsut cursor(p1x,p1y,0xff0000); cursor(p2x,p2y,0x00ff00); cursor(p3x,p3y,0x0000ff); if (SDL_Flip(screen)==-1){return 1;} } SDL_Quit(); return 0; }
Sanoisinko, että ainakin toteutus on perseestä. Koodi on kauheaa ja pitäisikö tuon olla C:tä? Miksi CLS on SDL_Surface? Kauheasti muuttujia ja niistä iso osa on jopa määritelty jokaiselle funktiolle! Mikset käyttänyt bezier-funktiossa taulukkoja tempeille? Miksi noin monta erinimistä muuttujaa?
Aihe on jo aika vanha, joten et voi enää vastata siihen.