Hej wszystkim, to moje wcześniejsze pytanie w tym temacie:
https://forum.pasja-informatyki.pl/444587/symulacja-odbicia-scian-roznych-nachyleniach-prosba-matematyczna-chodzi-arkanoid#c444902
oto mój obecny kod źródłowy: https://github.com/Jakub1010/Particles
Projekt wykorzystuje bibliotekę SFML, by zrozumieć w czym jest problem polecam po prostu odpalić kod ( dodałem też plik *.exe skompilowany pod systemem windows ).
Pracuje nad prostym symulatorem grawitacji, aktualnie napisałem symulację odbijania się cząsteczek od ścian, nie było by w tym nic trudnego gdyby to była jakaś forma prostokąta, mi jednak zależało na stworzeniu systemu odbijania się "piłek" od nawierzchni pod różnymi kątami. Tak jak to widać na screenie poniżej:
Same obliczenia się sprawdzają i cząstki odbijane są pod odpowiednim nachyleniem. Jednak nie brakuje tu problemów, często piłki wypadają z wnętrza struktury albo "zatrzymują się w połowie ściany". Próbowałem te problemy rozwiązać np. blokując możliwość podwójnego odbicia się cząstki od tej samej powierzchni:
void Particle::update(float deltaTime, const Area& walls) {
static bool reflectionEnable = true; // czy odbicie się cząski jest możliwe
static std::size_t lastEdge = 0; // ostatnia ściana od jakiej nastąpiło osbicie
sf::Vector2f particlePosition = m_particle.getPosition();
m_particle.move(sf::Vector2f(m_velocity.x, m_velocity.y) * Speed * deltaTime);
const std::size_t size = walls.getEdgesSize();
const sf::Vector2f s = m_particle.getPosition();
const float radius = m_particle.getRadius();
float reflectionDetect = false; // czy nastąpiło jakiekolwiek odbicie
for (std::size_t i = 0; i < size; ++i) {
float distance = walls.getDistanceToEdge(i, s);
if (distance <= m_particle.getRadius()) { // kolizja ze ścianą
reflectionDetect = true;
if (i == lastEdge) {
if (reflectionEnable) {
m_velocity = walls.getReflectionVectorFromEdge(i, m_velocity);
reflectionEnable = false; // nie ma możliwości powtórnego odbicia się od tej ściany
}
}
else {
m_velocity = walls.getReflectionVectorFromEdge(i, m_velocity);
lastEdge = i;
reflectionEnable = false;
}
break;
}
}
if (!reflectionDetect)
reflectionEnable = true;
}
Powyższa metoda ma chyba najważniejszą rolę w tym pytaniu, to ona wykrywa kolizje cząstki ze ścianą i wykonuje odpowiednie akcje.
Tak samo problemem jest nadawanie prędkości cząstkom, jeżeli będą one zmieniały swoją pozycje o dużą wartość to kolizja ze ścianą może w ogóle nie nastąpić:
być może trzeba totalnie inaczej zaprogramować prędkość, np. cząsteczki zawsze będą poruszały się tylko o jeden piksel a częstotliwość ich uaktualniania na ekranie będzie stanowić prędkość...
Nie wiem już sam jak do tego wszystkiego podejść :(
Liczę więc na waszą pomoc ( pomoc a nie gotowy kod ). Być może znacie jakiś algorytmy lub sami takie coś kiedyś robiliście?
Z góry bardzo wam dziękuje i serdecznie pozdrawiam :)