Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Ruch planety wokół osi obrotu

Ostatnio zmodyfikowano 2014-11-11 00:58
Autor Wiadomość
Uzumaki
Temat założony przez niniejszego użytkownika
Ruch planety wokół osi obrotu
» 2014-11-09 11:31:43
Mam dokonań animacji ruchu planety wokół osi obrotu przechodzącej przez środek ekranu.
Mój kod na ruch obiegowy planety wygląda tak, i nie jest to ruch jakiego bym oczekiwał- tzn. po okręgu. Ktoś wie, co tu trzeba poprawić ?

C/C++
void przesunXY() {
    float dfi = 0;
   
    for( dfi; dfi <= 2 * M_PI; dfi += 0.1 )
   
         _x += 20 * cos( dfi );
   
    for( dfi; dfi <= 2 * M_PI; dfi += 0.1 )
   
         _y += 20 * sin( dfi );
   
}

P-120209
Piastlis
» 2014-11-09 22:02:33
Niby wszystko jest ale nie tam gdzie trzeba i jak trzeba.
Zmienna
float dfi = 0;
nie jest ani potrzebna ani konieczna.
Używane jest to dfi wewnątrz pętli ale ono nie ma zadeklarowanej wartości początkowej.
I po drugie pętla powinna być wykonana tylko raz i dla każdej wartości dfi x i y ma być za jednym razem.
P-120254
Uzumaki
Temat założony przez niniejszego użytkownika
» 2014-11-10 18:39:11
Nie bardzo rozumiem o co Ci chodzi. Generalnie chodzi chyba o to, aby te współrzędne się nie dodawały, tylko po prostu płynnie zmieniały swoją wartość w zależności od kąta dfi. Nie wiem jak to zaimplementować.
P-120322
Piastlis
» 2014-11-10 21:03:57
Powiem to inaczej czyli przetłumaczę ci co ta funkcja robi.
Rozumiem że _x , _y i M_PI to zmienne globalne.
Nie rozumiem dlaczego dfi jest zmienną lokalną.
Pierwsza pętla dodaje kilkanaście razy kolejne wartości 20*cos(dfi).
Wychodzi jakaś egzotyczna wartość _x a dfi osiąga wartość 6.3.
Druga pętla nie jest już wcale wywoływana.
Nie wiem jak ten program ma wyglądać bo to jest tylko fantazja programisty ale tak ogólnie to może on wyglądać tak:
C/C++
{
    for( float dfi = 0; <= 2 * M_PI; dfi += 0.1 )
    {
        _x = 20 * cos( dfi );
        _y = 20 * sin( dfi );
        // Tutaj zrób malunki:)
    }
}
P-120340
Uzumaki
Temat założony przez niniejszego użytkownika
» 2014-11-11 00:23:47
No rozumiem, już to miałem tak robione jak pokazujesz, ale z tym  Twoim kodem nie dostaniesz animacji, tzn. kulka zastygnie w jednym miejscu, tzn. w takim, dla którego środek kuli będzie się pokrywał  wyliczoną w pętli wartością _x oraz _y.

Cały kod wygląda tak, a program ma po prostu obrazować ruch obrotowy kulki wokół środku ekranu.

C/C++
#define _USE_MATH_DEFINES
#include <allegro.h>
#include <cmath>


class Kula {
public:
   
    Kula( int x, int y, int r ) {
        _x = x;
        _y = y;
        _r = r;
    }
   
    void przesunXY() {
        for( float dfi = 0; dfi <= 2 * M_PI; dfi += 0.1 )
        {
            _x = 20 * cos( dfi );
            _y = 20 * sin( dfi );
           
        }
    }
   
   
   
   
   
   
   
   
   
    void rysuj( BITMAP * bufor ) {
        circlefill( bufor, _x, _y, _r, makecol( 255, 0, 0 ) );
    }
   
private:
    int _x;
    int _y;
    int _r;
};


volatile int ticks = 0;
void ticker()
{
    ticks++;
}
END_OF_FUNCTION( ticker )

const int updates_per_second = 60;

const int W = 640;
const int H = 320;

int main()
{
   
    allegro_init();
    install_keyboard();
    set_color_depth( 32 );
    set_gfx_mode( GFX_AUTODETECT_WINDOWED, W, H, 0, 0 );
    BITMAP * bufor = NULL;
    bufor = create_bitmap( W, H );
    Kula k1( 300, 500, 20 );
   
    install_timer();
   
   
    LOCK_VARIABLE( ticks );
    LOCK_FUNCTION( ticker );
    install_int_ex( ticker, BPS_TO_TIMER( updates_per_second ) );
   
    bool quit = false;
   
    while( !quit )
    {
        while( ticks == 0 )
        {
            rest( 1 );
        }
       
        while( ticks > 0 )
        {
            int old_ticks = ticks;
           
            k1.przesunXY();
           
            ticks--;
            if( old_ticks <= ticks ) //logic is taking too long: abort and draw a frame
                 break;
           
        }
       
       
        clear_bitmap( bufor );
        k1.rysuj( bufor );
       
        blit( bufor, screen, 0, 0, 0, 0, W, H );
       
        if( keypressed() ) quit = true;
       
       
    }
   
    destroy_bitmap( bufor );
    return 0;
}
END_OF_MAIN()
P-120350
Piastlis
» 2014-11-11 00:58:19
To miała być tylko podpowiedź:). Kolejne pary pozycji są widziane wewnątrz tej pętli.Na zewnątrz widać tylko pozycję dla dfi=6.3.Jeżeli te pary mają być widziane na zewnątrz musi to być zrobione inaczej.
dfi ma być globalne:
C/C++
{
    dfi += 0.1;
    if( dfi >= 2 * M_PI )
         dfi = 0;
   
    _x = 20 * cos( dfi );
    _y = 20 * sin( dfi );
}
Tak jak mówiłem dfi nie jest konieczna. _x i _y można policzyć korzystając z zasad trygonometrii.
C/C++
{
    float x, y;
    y = _x * sin( 0.1 ) + _y * cos( 0.1 );
    x = _x * cos( 0.1 ) - _y * sin( 0.1 );
    _x = x;
    _y = y;
}
W tym przypadku trzeba zadeklarować jakąś pozycję początkową.
Czyli:
C/C++
class Kula {
public:
   
    Kula( int x, int y, int r, float fi ) {
        _x = x;
        _y = y;
        _r = r;
        dfi = fi;
    }
   
    void przesunXY() {
       
        dfi += 0.1;
        if( dfi >= 2 * M_PI )
             dfi = 0;
       
        _x = 20 * cos( dfi );
        _y = 20 * sin( dfi );
    }
   
    void rysuj( BITMAP * bufor ) {
        circlefill( bufor, _x, _y, _r, makecol( 255, 0, 0 ) );
    }
   
private:
    int _x;
    int _y;
    int _r;
    float dfi;
};
Postać trygonometryczna jest dla mnie wygodniejsza do obracania dużych obiektów w 3 wymiarach z uwzględnieniem perspektywy.Różnica jest tylko taka że musisz zachować x i y do następnego wywołania w jakiejś postaci rzeczywistej ponieważ int będzie za każdym razem będzie obcinało ułamek i te błędy będą się kumulować.

Ty zrobiłeś tyko taki bląd że nie zachowałeś dfi.
P-120354
« 1 »
  Strona 1 z 1