Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Rotaation laskeminen

kayttaja-3842 [10.05.2010 20:04:52]

#

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;

}

Metabolix [10.05.2010 20:42:30]

#

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. :)

kayttaja-3842 [11.05.2010 00:32:59]

#

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? :)

User137 [11.05.2010 00:40:24]

#

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.).

Metabolix [11.05.2010 01:08:22]

#

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).

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta