Cześć.
Próbuje napisać prosty silnik fizyczny w Javie. Kiedyś zrobiłem coś podobnego
w CPP, także szkielet miałem gotowy i teraz tylko przerabiam na Jave.
Jednak coś mi tu nie działa tak jak trzeba. Prędkość nie oblicza się poprawnie,
cały czas jest stała. Myślę, że kaszani się gdzieś przy rozwiązywaniu równania
Eulerem (metoda symuluj() w klasie Obiekt), ale pewności nie mam. Nie wiem
czy dobrze wywołuje metody na wektorach. Źle mi to wygląda, no ale operatorów
przeciążyć nie można, także nie ma wyboru. Nie za dobrze znam jeszcze Jave,
dlatego przydałoby się jakieś wprawne oko ;)
Oto kod:
import javax.vecmath.*;
import javax.vecmath.Vector3d.*;
class Obiekt
{
double masa; // Masa obiektu
Vector3d pozycja = new Vector3d(0.0d, 0.0d, 0.0d); // Pozycja w ukladzie
Vector3d v = new Vector3d(0.0d, 0.0d, 0.0d); // Predkosc
Vector3d sila = new Vector3d(0.0d, 0.0d, 0.0d); // Sila dzialajaca na obiekt
Obiekt(double m)
{
masa = m;
}
/* Metoda void przyloz_sile(Vector3D force) jest uzywana do dodania sily dzialajacej na mase.
W ciagu danego czasu, na mase(klasa Obiekt) moze działać kilka sił zewnetrznych. Metoda
zwraca sile wypadkowa sil przylozonych do masy.
*/
void przyloz_sile(Vector3d force)
{
sila.set(force);
}
void odbij(Vector3d v1) // Zmienia wektor predkosci na wektor predkosci odbity
{
v = v1;
}
void zeruj_sile() // Zerowanie siły
{
sila = new Vector3d(0.0d, 0.0d, 0.0d);
}
/* metoda void symuluj() oblicza nowa predkosc i nowa pozycje
masy (obiektu) w stosunku do zmiany w czasie (dt). Używamy tutaj
"Metody Eulera". */
void symuluj(double dt)
{
sila.scale(1/masa); // v += (sila / masa) * dt
sila.scale(dt);
v.add(sila);
v.scale(dt); // pozycja += v * dt
pozycja.add(v);
}
}
class Symulacja
{
Obiekt pilka;
Vector3d grawitacja = new Vector3d(0.0d, -8.0d, 0.0d);;
void oblicz_sile_grawitacji() // Oblicz sile grawitacji F = g*m
{
grawitacja.scale(pilka.masa);
}
Symulacja(double m) // Kontruktor tworzacy mase o wartosci m
{
pilka = new Obiekt(m);
}
void init() // Metoda wywolujaca metode init() dla masy
{
pilka.zeruj_sile();
}
void solve()
{
oblicz_sile_grawitacji();
pilka.przyloz_sile(grawitacja);
}
void simulate(double dt) // Iteruj masy pod wplywem czasu
{
pilka.symuluj(dt); // Iteruj masy i uzyskuj nowa pozycje i predkosc
}
void operate(double dt) // Kompletna procedura symulacji
{
init(); // Krok 1: Resetuj sily
solve(); // Krok 2: Przyloz sily
simulate(dt); // Krok 3: Iteruj masy pod wplywem czasu
}
}