SFML и C++ Уроки \ Разработка игр › Форумы › Логика игр › Как реализовать коллизию между двумя окружностями? › Ответ в теме: Как реализовать коллизию между двумя окружностями?
Помоему в разы проще чем делать коллизию на SAT. Берёшь вектора цетров окружностей и проверяешь дистанцию между ними – если дистанция меньше чем сумма радиусов – выталкивай вектора центров в противоположных направлениях на велечину пересечения.
Будет примерно так
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
struct Circle { float r = 10; sf::Vector2f center = sf::Vector2f(0,0); } //Угол между двумя векторами //Возвращает градусы! float getAngle(sf::Vector2f start, sf::Vector2f end) { return atan2((start - end).y, (start - end).x) * 180 / 3.14159265; } //Длинна вектора float getVDistance(sf::Vector2f start, sf::Vector2f end) { return std::sqrt((abs((start - end).x)*abs((start - end).x)) + (abs((start - end).y)*abs((start - end).y))); } //Поворот вектора sf::Vector2f vectorRotate(sf::Vector2f& vec, const double deg) { double theta = deg * mRad; auto cs = cos(theta); auto sn = sin(theta); sf::Vector2f p = vec; return vec = Vector2f(cs * p.x - sn * p.y, sn * p.x + cs * p.y); } void foo(Circle fi, Circle se) { float dist = getVDistance(fi.center, se.center); if ( dist < (fi.r + se.r)) { float angle = getAngle(fi.center, se.center); float delta = (fi.r + se.r) + dist; delta /= 2; sf::Vector2f vec = vectorRotate(sf::Vector2f(1, 0), angle) vec.x *= delta; vec.y *= delta; fi.center += vec; vec = vectorRotate(sf::Vector2f(1, 0),360 - angle) vec.x *= delta; vec.y *= delta; se.center += vec; } //Код набросан на вскидку ибо давно уже (больше 2 лет ибо мне хватает SAT) не задумывался о движке коллизии. } |