столкновение двух кругов

0

Я тестировал столкновение между двумя кругами, используя метод:

Circle A = (x1,y1) Circle b = (x2,y2)
Radius A           Radius b

x1 - x2 = x' * x'
y1 - y2 = y' * y'

x' + y' = distance

square root of distance - Radius A + Radius B

и если полученный ответ является отрицательным числом, он пересекается.

Я использовал этот метод в тесте, но, похоже, он не очень точен.

bool circle::intersects(circle & test)
{

Vector temp;
temp.setX(centre.getX() - test.centre.getX());
temp.setY(centre.getY() - test.centre.getY());

float distance;
float temp2;
float xt;
xt = temp.getX();
temp2 = xt * xt;
temp.setX(temp2);

xt = temp.getY();
temp2 = xt * xt;
temp.setY(temp2);

xt = temp.getX() + temp.getY();
distance = sqrt(xt);
xt = radius + test.radius;

if( distance - xt < test.radius)
{
    return true;
}
else return false;

}

Это функция, использующая этот метод, возможно, я ошибаюсь. Я просто задавался вопросом, какие другие методы я могу использовать. Я знаю, что теорема о разделении оси лучше, но я не знаю, с чего начать.

  • 2
    Пожалуйста, назовите ваши переменные как-то значимые, т.е. не temp и temp2 . И, пожалуйста, прекратите неоднократно использовать xt в разных контекстах. (По сути, правильное присвоение имен вашим переменным составляет здесь половину проблемы).
  • 0
    Наименование шокирует повторное использование переменных для разных вещей, это плохо. использование вектора temp просто усложняет ситуацию. Но «ошибка» в основной математике ближе к концу.
Показать ещё 1 комментарий
Теги:
math
collision

4 ответа

1
Лучший ответ

Исходя из решения Ричарда, но сравнивая квадрат расстояния. Это уменьшает ошибки вычислений и время вычисления.

bool circle::intersects(circle & test)
{
    float x = this->centre.getX() - test.centre.getX()
    float y = this->centre.getY() - test.centre.getY()  

    float distance2 = x * x + y * y;
    float intersect_distance2 = (this->radius + test.radius) * (this->radius + test.radius);

    return distance <= intersect_distance2;
}
  • 0
    Я закончил с чем-то очень похожим это тоже. Оказалось, что это была ошибка с sfml и необходимость установить радиус, прежде чем вы сможете его использовать. Кроме того, что делает "this-> radius"? почему не просто "радиус"?
  • 0
    this-> не обязательно. Это зависит от языка и программиста.
Показать ещё 1 комментарий
5

Изображение 174551

if( distance - xt < test.radius)
{
return true;
}

distance - xt будет оцениваться до синей линии, расстояние между двумя дисками. Он также удовлетворяет условию быть меньше радиуса испытания, но не происходит столкновения.

Решение:

Изображение 174551

 if(distance <= (radius + test.radius) )
return true;

Где distance - это расстояние от центров.

  • 2
    +1 за усилие :)
4

Дано: xt = radius + test.radius;

Правильный тест: if( distance < xt)

Вот попытка перезаписать тело для вас: (нет компилятора, поэтому могут быть ошибки)

bool circle::intersects(circle & test)
{
    float x = this->centre.getX() - test.centre.getX()
    float y = this->centre.getY() - test.centre.getY()  

    float distance = sqrt(x*x+y*y);

    return distance < (this->radius + test.radius);
}
  • 0
    Кроме того, я сомневаюсь, что есть веская причина для использования чисел с плавающей точкой вместо двойных, так что подумайте об их изменении
  • 0
    Немного в стороне вопроса. Что если круги движутся, а контрольное столкновение происходит с некоторым интервалом, скажем, 50 миллис. Каков будет правильный подход, чтобы не пропустить столкновение?
Показать ещё 3 комментария
0

Используйте теорему Пифагора для вычисления расстояния между центрами

Это прямая линия

Если они столкнулись, то это расстояние короче, чем сумма двух радиусов

  • 0
    он уже делает это ..

Ещё вопросы

Сообщество Overcoder
Наверх
Меню