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

Symulacja rzutu ukośnego

Ostatnio zmodyfikowano 2016-11-10 19:05
Autor Wiadomość
wiktorze
Temat założony przez niniejszego użytkownika
Symulacja rzutu ukośnego
» 2016-11-05 19:52:01
Cześć, mam problem z moim programem, a mianowicie nie wiem co jest w nim nie tak. Jest to program, który prowadzi symulację rzutu ukośnego z uwzględnieniem oporu powietrza (wzorki tutaj https://drive.google.com/file​/d/0B2Q-eA4uAWHhczByZHZRSVVYbUU​/view). Nie rysuje w ogóle wykresu, nie wiem co mam źle. Siedzę nad tym bardzo długo, pomóżcie! Dzięki z góry ;)
C/C++
#include <iostream>;
#include <stdio.h>
#include <allegro5/allegro.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_color.h>
#include <cmath>
using namespace std;

int v0, vx, vy, alfa;
float beta, t;

int main()
{
    cout << "Podaj v0, alfa, stala beta" << endl;
    cin >> v0;
    cin >> alfa;
    cin >> beta;
   
   
   
    ALLEGRO_DISPLAY * display = NULL;
    printf( "inicjacja Allegro" );
    if( !al_init() ) {
        printf( "blad inicjacji allegro!\n" );
        return - 1;
    }
    //określenie i utworzenie okna
    display = al_create_display( 640, 480 );
    if( !display ) {
        printf( "blad tworzenia tla!\n" );
        return - 1;
    }
    //inicjacja prymitywów
    if( !al_init_primitives_addon() ) {
        printf( "prymitywy nie zainicjowane!\n" );
        return - 1;
    }
   
    al_clear_to_color( al_map_rgb( 255, 255, 255 ) );
    //oś OX
    al_draw_line( 100, 400, 600, 400, al_map_rgb( 0, 0, 255 ), 1 );
    //oś OY
    al_draw_line( 100, 400, 100, 40, al_map_rgb( 0, 0, 255 ), 1 );
   
    float y = 0;
   
    for( int t = 0; t < 300; t++ )
    {
        vx = v0 * exp((( - 1 ) * beta ) * x ) * cos( alfa );
        vy =( v0 * sin( alfa ) +( 10 / beta ) ) * exp(( - 1 ) * beta * x ) -( 10 / beta );
       
        x =( vx / beta ) *( 1 - exp(( - 1 ) * beta * t ) );
       
       
       
       
        y =(( vy / beta ) +( 10 / beta ) ) *(( beta * x ) / vx ) -( 10 *((( - 1 ) / beta ) *(( vx / beta ) - x ) ) ) / beta * 100;
       
       
       
        al_draw_pixel( x, y, al_map_rgb( 0, 0, 0 ) );
       
       
        al_flip_display();
        al_rest( 0.03 );
       
    }
   
    al_rest( 5.0 );
   
    al_destroy_display( display );
   
    return 0;
}


EDIT: Dowiedziałem, że niektóre z tych wzorów się nie zgadzają i należy użyć innych wzorów, lecz jednak jakby ktoś wypatrzył jakiś błąd tutaj i mi napisał byłbym wdzięczny, może robię coś nie tak całkowicie i po prostu tego nie widzę. Pozdrawiam!
P-153399
mateczek
» 2016-11-06 13:10:58
kolego. Napisz z czym masz problem dokładniej. Czy z wykresem i  biblioteką allegro ?? czy z wzorami, i z opisem fizyki ??
Zobacz pod debuggerem czy program Ci prawidłowo liczy punkty (X,Y). Jeśli dokładniej opiszesz problem to większa szansa na pomoc. Ktoś kto mógłby sprawdzić wzory nie musi znać się na allegro :) więc jeśli dokładnie sprecyzujesz problem większa będzie szansa na odpowiedź :)

podejście do rozwiązania mogą być 2

1. Analogowo skorzystać ze wzorów wyprowadzonych tak jak ty to próbujesz zrobić i właściwie wszystko sprowadza się wyrysowania wykresu funkcji x(t), y(t)

2. cyfrowo czyli liczyć poszczególne iteracje. Jest to prawdziwa symulacja i jako taka obarczona błędem wynikłym z czegoś co nazywamy dyskretyzacją. Ale mimo wszystko ja wolę cyfrowe pojejście. Bo nie wymaga rozwiązywania równań różniczkowych, a te równania symuluje.
C/C++
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
   
    double vo, katRzutu;
    cout << "Podaj v0, katRzutu" << endl;
    cin >> vo >> katRzutu;
    katRzutu = katRzutu / 90 * 1.570796327; //zamiana stopni na radiany
    double x = 0, y = 0, dt = 0.01;
    constexpr double g = 9.81; //przyspieszenie ziemskie
   
    double v_x = vo * cos( katRzutu ); //wartości początkowe
    double v_y = vo * sin( katRzutu );
    while( y >= 0 ) { //puki kamyk nie spadnie
        x += v_x * dt; // do drogi doaję kolejny odcinek pokonany w czasie dt
        y += v_y * dt;
        v_y = v_y - g * dt; // prędkość w kolejnej iteracji jest pomniejszona o przyspieszenie ziemskie
        cout << fixed << "x: " << x << " y: " << y << endl;
    }
    return 0;
}

przykład jak uwzględnić opór powietrza w osi x.
C/C++
while( y >= 0 ) {
    v_x = v_x -(( v_x * B ) / m ) * dt // prędkość pomniejszona o przyspieszenie wynikłe z oporu powietrza. B- współczynnik oporu powietrza
    //Vx*B to siła oporu
    //podzielone przez m(masę) daje przyspieszenie
    //pomnożone przez dt daje różnicę prędkości wynikłą z przyspieszenia
    x += v_x * dt;
}



Jeśli chcesz zrozumieć podejście cyfrowe zapraszam do obejrzenia trzech filmików mojego autorstwa. (że tak zażartuje "karierę" na yt zacząłem niedawno a filmiki były jednymi z pierwszych więc za jakość przepraszam)
https://www.youtube.com/watch​?v=McPk7S3o_G0
https://www.youtube.com/watch​?v=W8OXQhgQuz0
https://www.youtube.com/watch​?v=nip4VsaLU00

PS. podejście analogowe sprawdź sobie najpierw w Excelu (wyrysuj wykres) a potem weź się za c++. Co do cyfrowego też można w excelu. Ale jak kto woli .
PSS. Wynik symulacji nawet się zgadza z tym ze strony http:visual.icse.us.edu.plwizu​alizacjemechanika-teoretycznaz​obaczRzutUkosn​y (przy zaznaczeniu oporu powietrza na 0). Zarówno u nich jak i u mnie wynik dla danych wejściowych Vo=200 kąt= 45 dt=0.01 jest 4080 -1.12.  Zastosowali tą samą metodę


P-153417
wiktorze
Temat założony przez niniejszego użytkownika
» 2016-11-10 19:05:12
Nadal mam problem z samym wyrysowaniem wykresu. Pytanie, jak w cyfrowym podejściu wyrysować wykres? To na nim mi najbardziej zależy. Dzięki za linki i porady :)
C/C++
while( y >= 0 )
{
   
    vox = v0 * cos( alfa );
    voy = v0 * sin( alfa ) - 9.81 * t;
    x =( vox / k ) *( 1 - exp( - k * t ) );
    y =( h +( voy / k ) +( 9.81 /( k * k ) ) -(( 9.81 * t ) / k ) -(( k * voy + 9.81 ) /( k * k ) ) * exp( - k * t ) );
    t += 0.01;
   
   
    al_draw_pixel( x, y, al_map_rgb( 0, 0, 0 ) );
   
   
    al_flip_display();
    al_rest( 0.03 );
   
}
EDIT: Wszystko pięknie działa w podejściu analogowym. Miałem problem po prostu ze skalowaniem ;) Dziękuję za pomoc!
P-153546
« 1 »
  Strona 1 z 1