Elikks, kokeilen tehä testinä omaa rotaatio funktioa, jolla pääasiassa tarvisi voida kääntää pelaajaa 90 asteen kulmissa. Elikkäs en halua käyttää rotozoomia vaan ajattelin kokeilla tehdä oman funktio. Noh jostain syystä laskenta kaava kusee ja kyseinen kuva saa tuloksekseen vain sinisiä ja vihreitä viivoja.
Elikkäs tässä olisi tekemäni funktio, mutta en vaan saa pähäni mistä kiikastaa.
SDL_Surface *Draw::rotateImage( SDL_Surface *image, int angle ){ SDL_Surface *rotImg = SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA, 32, 32, 32, 0, 0, 0, 0); float x_r,y_r; for( int x = 0; x < 32; x++ ){ for( int y = 0; y < 32;y++ ){ x_r = cos(degTorad(angle)) * (x - 32/2) - sin(degTorad(angle))*(y - 32/2) + 32/2; y_r = sin(degTorad(angle)) * (x - 32/2) + cos(degTorad(angle))*(y - 32/2) + 32/2; putPixel( rotImg, x_r, y_r, getPixel( image, x, y ) ); } } return rotImg; }
Jos haluat kääntää vain 90 asteen kulmissa, ota sinit ja kosinit pois ja laske suoraan todellisilla kertoimilla. Matemaattisessa koordinaatistossa pistettä voi kääntää 90 astetta positiiviseen kiertosuuntaan origon ympäri seuraavasti:
y1 = x0 x1 = -y0
Koska x muuttuu negatiiviseksi, siihen täytyy lisätä sopivan verran.
Järkevä lähestymistapa on pyöritellä sopivat kaavat jokaiselle kolmesta mahdollisesta kääntömäärästä (soveltamalla koordinaatteihin (x1, y1) uudestaan samaa kaavaa). Kaavat voi tarkistaa yksinkertaisesti laskemalla kuvan neljän kulmapikselin uudet koordinaatit, jotka pitäisi helposti pystyä päässä laskemaan oikein ilmankin kaavoja. :)
Joo, mutta ajattelin kumminki, että jos sais väsättyä sellaseen jolla pystyy kääntää 0 - 360 väliltä, koska voin tarvita sen tyypistä funktioo joskus toistenkin. Olisiko kellään tarjota mitään hyvää algorythmiä jolla onnistuisi kääntää kuvia? :)
Sinun pitää laskea myös etäisyys kiertopisteen keskeltä pikseliin ja kertoa sinin ja cosinin arvot sillä. Kulma molemmissa on ensinnäkin nykyinen kulma keskeltä pikseliin (arccos?) ja sitä kasvatetaan kierrettävällä kulmalla.
Freepascalilla koodi menee jotenkin näin (joka pikselille):
procedure Rotate(var px,py: single; const _angle,cx,cy: single); var d,a: single; begin d:=hypot(py-cy,px-cx); // Hypot on sama kun sqrt(x*x+y*y) a:=arctan2(py-cy,px-cx)+_angle*ToRad; px:=cx+cos(a)*d; py:=cy+sin(a)*d; end;
Edit: Tällä tyylillä tosin voi tulla ongelma että pikseleiden väleihin tulee rakoja. Järkevää tapaa ei nyt heti tule mieleen sen korjaamiseen. Periaatteessa kuvaa pitäisi kai lähteä piirtämään pikseli kerrallaan kohdekuvan koordinaateista ja lukea käänteisen kierron lähin väri, tai niiden sekoitus (linear filtering tms.).
Muihin kulmiin kääntämisen ongelmana on tosiaan tuo kuvan muoto, eli jonkinlaista interpolointia (painotetun keskiarvon laskemista) täytyisi käyttää. Kuvan kokokaan ei säily samana, vaan esimerkiksi 32x32-kuvan kääntyessä 45 astetta syntyykin sivultaan √2-kertainen kuva (noin 45x45).
Aihe on jo aika vanha, joten et voi enää vastata siihen.