Zderzenie ukośne kulek w oknie graficznym nie działa prawidłowo – prośba o pomoc

0

Probuje napisac grę w kręgle i od dluzszego czasu utknalem w jednym miejscu. Nie moge zrobic zderzenia ukosnego doskonale sprezystego kulek. Oto jeden z moich pomyslow w ktorym kulki raz odbijaja sie prawidlowo a innym razem nie, czasami zas znikaja.

Moj kod:


void collideBall (double *x, double *y, double *Vx, double *Vy)
{
    double alfa1=0, alfa2, alfa3, d=40;     //alfa2-kat miedzy wypadkowa predkosci a pozioma
    for (int i=1;i<16;i++)                  //alfa3-kat miedzyskladowa w strone odbijanej kulki 
    {                                       //alfa1 kat miedzy skladowa w kierunku odbijanej kulki a wypadkowa predkoscia
        for (int j=0; j<i;j++)
        {
            if (sqrt((pow(x[i]-x[j],2)+pow(y[i]-y[j],2)))<=40.0)        //x[i] oraz y[i] wspolrzedne kulek
            {                                                           //Vx[i] i Vy[i] predkosci skladowe
                double V=sqrt(Vx[i]*Vx[i]+Vy[i]*Vy[i]);
                alfa2=atan(fabs(Vy[i]/Vx[i])); 
                alfa3=atan(fabs(x[i]-x[j])/fabs(y[i]-y[j]));
                if ((alfa2>=0)&&(alfa2<=1.57)) alfa1=1.57-alfa2-alfa3;
                if ((alfa2<0)||(alfa2>1.57)) alfa1=1.57-alfa3;
                if (Vx[i]>0)
                {
                    Vx[i]-=V*cos(alfa1)*cos(alfa1+alfa2);
                    Vx[j]+=V*cos(alfa1)*cos(alfa1+alfa2);
                }
                else
                {
                    Vx[i]+=V*cos(alfa1)*cos(alfa1+alfa2);
                    Vx[j]-=V*cos(alfa1)*cos(alfa1+alfa2);
                }
                if (Vy[i]<0)
                {
                    Vy[i]+=V*cos(alfa1)*sin(alfa1+alfa2);
                    Vy[j]-=V*cos(alfa1)*sin(alfa1+alfa2);
                }
                else
                {
                    Vy[i]-=V*cos(alfa1)*sin(alfa1+alfa2);
                    Vy[j]+=V*cos(alfa1)*sin(alfa1+alfa2);
                }

                printf ("%lf\n %lf\n %lf\n", alfa1, alfa2, alfa3);
            }
        }
    }
}
2

Na początek bym zamienił atan na atan2 (on zajmuje się ćwiartkami za Ciebie).

0

Troche poczytalem o tym ale nadal nie bardzo rozumiem dzialania tej funkcji. Bylbym bardzo wdzieczny gdyby ktos mogl napisac ta funkcje albo chociaz mnie jakos nakierowac. Dobijajace sa te wszystie bezskuteczne proby wyprowadzania tych wzorow a podejrzewam ze z zastosowaniem tej funkcji program znacznie sie skroci i uprosci.

1

atan2(y, x) podaje w radianach kąt wektora [x, y]. Na górze układu współrzędnych (kolejno I i II ćwiartka) masz kąt od 0 do 180 stopni. Na dole (kolejno IV i III ćwiartka) masz kąt od 0 do -180 stopni.

0

Niestety nadal nie potrafie tego podzielic w zaden logiczny sposob na przypadki i napisac dzialajacej funkcji. Jakby ktos mial chwile to mogłby chociaz napisac mi jakis pomyslowy i nie przesadnie skomplikowany zarys?

1

Czy musisz to sam zaprogramować? Bo jak nie to skorzystaj z silnika fizycznego, który całą symulację odwali za Ciebie ;)

Poszukaj: Box2D

0

Niestety ten projekt mam oddac wykladowcy a watpie zeby chcial instalowac dodatkowa biblioteke zeby sprawdzić dzialanie programu. Ale ogolnie to pomysł dobry, na nastepnych cwiczeniach spytam sie czy moge zastosowac takie rozwiazanie.

0

Zrobilem to zderzenie na podstawie instrukcji jaka mielismy na laboratoriach z informatyki na studiach.
Czy moglby ktos przejrzec ta moja funkcje i podpowiedziec mi gdzie mam blad?

link do instrukcji ze wzorami: https://www.meil.pw.edu.pl/za/ZA/Courses/Informatyka-1
Instrukcja 5.2

Moja funkcja:

void collideBall (double x, double y, double Vx, double Vy)
{

for (int i=1;i<16;i++)
{
    for (int j=0; j<i;j++)
    {
        if (sqrt((pow(x[i]-x[j],2)+pow(y[i]-y[j],2)))<=40.0)
        {
            double v1x=Vx[i]-Vx[j];
            double v1y=Vy[i]-Vy[j];
            double L=sqrt( (Vx[i]-Vx[j])*(Vx[i]-Vx[j]) + (Vy[i]-Vy[j])*(Vy[i]-Vy[j]) );
            double nx=(x[i]-x[j])/L;
            double ny=(y[i]-y[j])/L;
            double Vnx=(v1x*nx+v1y*ny)*nx;
            double Vny=(v1x*nx+v1y*ny)*ny;
            double v1xnew=v1x-Vnx;
            double v1ynew=v1y-Vny;
            double v2xnew=Vnx;
            double v2ynew=Vny;

            Vx[i]=Vx[i]+v1xnew;
            Vy[i]=Vy[i]+v1ynew;
            Vx[j]=Vx[j]+v2xnew;
            Vy[j]=Vy[j]+v2ynew;

        }
    }
}

}

0

Przeanalizuj zachowanie symulatora przy większej ilości kul/kręgli.
Przykład: kołyska Newtona

0

Rozumiem jak dzialaja zderzenia i potrafie obliczyc predkosci na podstawie zasady zachowania energii i pedu, niestety nie potrafie tego przelozyc na uklad wspolrzednych. Po kazdej probie program zachowywal sie w nieprzewidywalny i dziwny sposob. Dlatego postanowilem sobie troche ulatwic i zastosowac wzory podane w instrukcji ktore byly podane w instrukcji na cwiczenia lecz to tez nie dziala prawidlowo (kulki zaczynaja przyspieszac i po chwili poruszaja sie bardzo szybko pojawiajac sie w losowych miejscach).
Siedzialem przy tym juz kilka dni i naprawde nie wiem co jest nie tak :(

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0