Занятие 13
Это надо знать
В программе, которую мы написали на прошлом занятии, шарики при столкновении пролетают сквозь друг друг друга. Напишем программу. чтобы шарики при столкновении отталкивались и разлетались в разные стороны.Рассмотрим случай, когда пересекаются две окружности с центрами в точках (х1, у1) , (х2, у2) и радиусами r1, r2.
Окружности пересекаются, если (x2 - x1)² + (y1 - y2)² < (r1 + r2)²
Найдем расстояние между центрами окружностей. Для этого нам понадобится функция возведения в степень.
Функция pow (a, n) возводит число а в n-ую степень.
distance = pow (x2 - x1, 2) + pow (y1 - y2, 2)
Если distance < pow (r1 + r2, 2), то шарики столкнулись.
При столкновении шарики должны оттолкнуться, для этого обменяем скорости vx и vy мячиков, для этого воспользуемся функцией swap.
Функция swap (a, b) обменивает значения переменных a и b, т.е в перемененной а будет находиться значение переменной b, а в переменной b - значение переменной а.
Функцию контроля столкновений можно записать следующим образом:
void Collision (Subject* ball1, Subject* ball2)
{
double distance = pow (ball1->x - ball2->x, 2) + pow (ball1->y - ball2->y, 2);
if (distance < pow (ball1->r + ball2->r, 2))
{
std :: swap (ball1->vx, ball2->vx);
std :: swap (ball1->vy, ball2->vy);
}
}
В функции MoveBalls вызываем функцию Collision для каждой пары шариков (для 4 шариков):
Collision (&ball1, &ball2);
Collision (&ball1, &ball3);
Collision (&ball2, &ball3);
Collision (&ball2, &ball4);
Collision (&ball3, &ball4);
Если предположить, что героев можно поместить в круги, то можно рассчитать, когда герои столкнутся, т.е. пересекутся круги, описанные около героев.
Функция Collision проверяет ситуацию столкновения героев Чебурашки (cheb) и Цыпленка (chik), описанных с помощью структуры Hero.
cheb->x, cheb->y - координаты центра окружности, описанной около Чебурашки.
chik->x, chik->y - координаты центра окружности, описанной около Цыпленка.
cheb->r - радиус окружности, описанной около Чебурашки.
chik->r - радиус окружности, описанной около Цыпленка.
void Collision (Hero* cheb, Hero* chik, int* lives)
{
distance = pow (cheb->x - chik->x, 2) + pow (cheb->y - chik->y, 2);
if distance < pow (cheb->r + chik->r, 2)
{
std :: swap (cheb->vx, chik->vx);
std :: swap (cheb->vy, chik->vy);
}
}
Рассмотрим случай, когда около героев точнее будет описать прямоугольники.
Рассмотрим случаи пересечения прямоугольников:
В условии, которое проверяет столкновение героев, записываем все возможные варианты:
int chek = (x1 < x3 && x3 <x2 && y2 < y3 && y3 < y2) ||
(x1 < x3 && x3 <x2 && y2 < y4 && y4 < y2) ||
(x1 < x4 && x4 <x2 && y2 < y3 && y3 < y2) ||
(x1 < x3 && x3 <x2 && y2 < y3 && y3 < y2);
Пример
Движение лягушки и четырех комаров. Комары и лягушка при столкновении "разлетаются".Посмотреть текст программы
Результат выполнения программы
Домашнее задание
Внести изменения в программу предыдущего домашнего задания: герой должен "реагировать" на столкновение с другими объектами (шариками, другими героями).