Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Funktio piirtäminen ja pyörittäminen

Sivun loppuun

codeheaven7 [12.09.2012 16:38:17]

#

Eli terveppä terve. Olen luonut funktion jolle annetaan parametreiksi x, y, leveys, korkeus. Näiden mukaan piirretään sitten kuva. Esim:
DrawPhoto(10, 10, 20, 100);

Ongelma on siinä, että olen tehnyt 8 kuvaa tuon funktion avulla. Miten voin pyörittää kaikkia? Eli siis tarkoitan sitä, että jos painaa oikeasta nuolesta niin kaikki kahdeksan kuvaa olisi yksi kiinteä ja pyörisi.

Kuva havainnollistaa enemmän kuin tuhat sanaa:
Aloitus tilanne

Tilanne kun on 45 astetta menty


Kiitos hyvin paljon jos joku pystyy auttamaan.

User137 [12.09.2012 20:42:44]

#

Miten nämä sun kuvat liittyy seiniin? Onko ongelma 3D-vektorigrafiikkaa vai etsitkö funktiota jolla voi piirtää yhden kuvan pyöritettynä? Käytätkö grafiikkakirjastoja?

codeheaven7 [13.09.2012 00:00:48]

#

Mustat rajat ovat seiniä. Seinät ovat erillisiä kuvia. ns. palasia. Jotka kootaan yhteen. Jokainen seinä on oma objectinsa.

Kyseessä 2D. SDL ja SDL_rotozoom käytössä.

User137 [13.09.2012 00:08:19]

#

Ongelma on siis kai matematiikkaa. Itse saattasin käyttää omaa rotate()-funktiota. Koodi on pascalia mutta ymmärtänet pointin:
http://code.google.com/p/nxpascal/source/browse/trunk/src/nxMath.pas#306

Mikäli tuota ei ole matikkakirjastossa niin:

hypot(x, y) = neliöjuuri(x^2 + y^2)

nxTypes.pas:sta löytyy vielä vakiot:

const ToRad = 0.0174532925199433;  //  PI / 180 = Deg To Rad
      ToDeg = 57.295779513082321;  //  180 / PI = Rad To Deg

Jaska [13.09.2012 09:32:01]

#

Taustalla oleva matematiikka ei ole vaikeaa. Kiinnitetään koordinaatisto siten, että kiertopiste on origo. Jos kiertokulma on a, niin alkuperäisen pisteen (x,y) koordinaatit saadaan laskemalla e^{ia}*(x+iy). Ei siinä tarvita arkustangenttia. Pelkkä sini ja kosini riittää.

User137 [13.09.2012 13:26:54]

#

Hmm, ei ole tullu mieleen optimoida tuota.
Wikistä löytyi toivottavasti lopullinen kaava.

codeheaven7 [13.09.2012 19:15:26]

#

Noniin. Tein vielä toisen selvennys kuvan jos asia kävisi paremmin ilmi mitä yritän tehdä. :)

Kuva

Eli siis noin. Mielestäni ainakin on järkevintä tehdä kuvan keskelle tyhjä objecti joka pyörittää koko pakkaa. Onnistuin tekemään niin, että objectit pysyvät paikallaan, mutta jostain syystä paketti ei pyöri vaan se liikkuu ja nimenomaa se ei saisi liikkua vaan pitäisi pyöriä.

User137 [14.09.2012 07:45:19]

#

Laita jotain koodia näkyviin. Se missä pakalle annetaan alkusijainnit, ja oma yritys pyörittämisestä. Edelleen nuo ylläolevat pyöritys-kaavat tuntuu olevan ratkasu ongelmaan.

Metabolix [14.09.2012 14:02:13]

#

Pyörittämisessä pitää kääntää kuvan sijaintia suhteessa pyörityskohtaan, kääntää kuvaa ja lisäksi huomioida, että rotozoom-funktion tuottama pinta on edelleenkin vaakasuora suorakulmio, jonka kulmaan on ilmestynyt tyhjää.

Seuraava funktio piirtää ruudulle kuvan pyöritettynä pisteen ympäri. Kulma annetaan radiaaneina. Pyörityskaavassa on vaihdettu sinin etumerkkiä Wikipedian kaavaan nähden, jotta pyörimissuunta saadaan samaksi kuin rotozoom-funktiossa.

struct piste {
	double x, y;
};
void piirra(SDL_Surface* ruutu, SDL_Surface* kuva, piste kohta, piste pyoritys, double kulma) {
	// Pyörityslaskuja varten lasketaan, missä kuvan keskipiste sijaitsee.
	piste keski = {
		kohta.x + kuva->w / 2,
		kohta.y + kuva->h / 2
	};

	// Pyöritetään kuvan sijaintia pyörityskohdan ympäri.
	double s = std::sin(kulma), c = std::cos(kulma);
	piste uusi_keski = {
		pyoritys.x + c * (keski.x - pyoritys.x) + s * (keski.y - pyoritys.y),
		pyoritys.y + c * (keski.y - pyoritys.y) - s * (keski.x - pyoritys.x)
	};

	// Pyöritetään kuvaa.
	SDL_Surface* uusi_kuva = rotozoomSurface(kuva, kulma * 180 / 3.14159, 1, 1);

	// Lasketaan, mihin kohti käännetyn kuvan vasen yläkulma kuuluu.
	piste uusi_kohta = {
		uusi_keski.x - uusi_kuva->w / 2,
		uusi_keski.y - uusi_kuva->h / 2
	};

	// Piirretään kuva ja vapautetaan muisti.
	SDL_Rect rect = {(Sint16) uusi_kohta.x, (Sint16) uusi_kohta.y};
	SDL_BlitSurface(uusi_kuva, 0, ruutu, &rect);
	SDL_FreeSurface(uusi_kuva);
}

DumTom [25.09.2012 10:49:09]

#

Jos haluat nopeutta piirtämiseen niin kannattaa ohjelman alussa piirtää kaikki eri asennot .png kuvaan ja Blitata sitten sieltä.


Sivun alkuun

Vastaus

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

Tietoa sivustosta