C ++ 11 — C ++ Прямоугольник в прямоугольник Столкновение

У меня действительно плохое время, когда я ищу ошибку в своем коде.

Мое обнаружение столкновений здесь не сработает, даже алгоритм, который я искал в Google.

void PollEvents()
{

for (int i = 0;i < NUMBER_OF_BLOCKS; ++i)
{

Rectangle& a = blocks[i];

if (mouse.state == GLFW_PRESS)
{
//look for any block to grab
if (mouse.leftClick && !blocks[selectedBlock].Grab() &&
a.Hover(mouse.pos.x, mouse.pos.y))
{
//prevent grabbing another block
if (i != selectedBlock) {
selectedBlock = i;
}

a.Grab() = true;

if (a.IsTypeHorizontal()) {
diff = mouse.pos.x - a.Left();
} else {
diff = mouse.pos.y - a.Top();
}
}

if (a.Grab())
{

for (int j = 0;j < NUMBER_OF_BLOCKS; ++j)
{
//skip for any self-checking
if (i == j) continue;

Rectangle& b = blocks[j];

//check for rectangle collision
if (!a.Collide(b) || b.Collide(a)) {
//j++;
//how does this block will move.

if (a.IsTypeVertical()) {
a.SetY(mouse.pos.y - diff);
} else {
a.SetX(mouse.pos.x - diff);
}

} else {

switch (a.sideHit)
{
case UP:
//a.SetY(b.Bottom());
printf("UP\n");
break;
case DOWN:
//a.SetY(b.Top() + a.GetHeight());
printf("DOWN\n");
break;
case LEFT:
//a.SetX(b.Right());
printf("LEFT\n");
break;
case RIGHT:
//a.SetX(b.Left() - a.GetWidth());
printf("RIGHT\n");
break;
}
}

//check for bound collision
a.BoundCheck(1.f);
}

}

} else {
a.Grab() = false;
}
}
}

Обнаружение столкновения:

bool Rectangle::Collide(const Rectangle& r) {

if (IsTypeHorizontal()) {
if (r.Hover(Left(), Top()) && r.Hover(Right(), Top())) {
sideHit = UP;
return true;
} else if (r.Hover(Right(), Bottom()) && r.Hover(Left(), Bottom())) {
sideHit = DOWN;
return true;
}
// } else if (r.Hover(Left(), Top())) {
// sideHit = UP;
// return true;
// } else if (r.Hover(Right(), Top())) {
// sideHit = UP;
// return true;
// } else if (r.Hover(Right(), Bottom())) {
// sideHit = DOWN;
// return true;
// } else if (r.Hover(Left(), Bottom())) {
// sideHit = DOWN;
// return true;
// }
} else {
if (r.Hover(Left(), Top()) && r.Hover(Left(), Bottom())) {
sideHit = LEFT;
return true;
} else if (r.Hover(Right(), Top()) && r.Hover(Right(), Bottom())) {
sideHit = RIGHT;
return true;
}
// } else if (r.Hover(Left(), Top())) {
// sideHit = LEFT;
// return true;
// } else if (r.Hover(Left(), Bottom())) {
// sideHit = LEFT;
// return true;
// } else if (r.Hover(Right(), Top())) {
// sideHit = RIGHT;
// return true;
// } else if (r.Hover(Right(), Bottom())) {
// sideHit = RIGHT;
// return true;
// }
}

return false;

}

Код для Hover:

inline float Hover(float X, float Y) const {
return  X >= Left() &&
X <= Right() &&
Y >= Bottom() &&
Y <= Top();
}

Я пытаюсь сделать свой собственный разблокируй меня.

Пожалуйста, помогите мне в моем обнаружении столкновений. Прошло 3 дня с тех пор, как я застрял в этой проблеме.

ОБНОВИТЬ

Я обнаружил проблему, почему все обнаружение столкновений с прямоугольником не работает в моей программе.

ошибка:

if (!a.Collide(b)) {

//Move()

} else {

//Resolve collision
}

Этот должен быть

if (!Rectangle::Collide(a, b)) {

//Move()

} else {

//Resolve collision

}

Делая Collide() static член Rectangle потому что, как вы можете видеть в моей реализации Collide(), оно основывает свое решение на своем собственном члене, так a.Hover(b.x, b.y) не имеет никакого смысла.

Надеюсь, это поможет немного всем новичкам, как я.

0

Решение

Чтобы выполнить обнаружение столкновения прямоугольника / прямоугольника, если любая из четырех точек (ребра, параллельные оси x и y) находятся внутри другого прямоугольника, мы имеем столкновение.

Более простой способ, чем проверка каждой из четырех точек, состоит в том, чтобы проверить, находится ли один край X между обоими краями X другого прямоугольника, и если один край Y находится между обоими краями Y другого прямоугольника — если оба они истинны, мы имеем столкновение (потому что два ребра должны встретиться в точке внутри другого прямоугольника). Поэтому мы просто проверяем это в обоих направлениях:

bool isclamped(float mid, float A, float B)
{
if (A > B)
{
return mid >= B && mid <= A;
}
return mid >= A && mid <= B;
}

bool checkcollisiononeway(rect rectA, rect rectB)
{
if (isclamped(rectA.left, rectB.left, rectB.right)
|| isclamped(rectA.right, rectB.left, rectB.right))
&& (isclamped(rectA.bottom, rectB.bottom, rectB.top)
|| isclamped(rectA.top, rectB.bottom, rectB.top))
{
return true;
}
return false;
}

bool checkcollisionbothways(rect rectA, rect rectB)
{
return checkcollisiononeway(rectA, rectB) || checkcollisiononeway(rectB, rectA);
}

Чтобы определить угол столкновения после обнаружения столкновения, найдите угол между их двумя центрами, используя atan2(rectA.y - rectB.y, rectA.x - rectB.x) (угол возвращается в радианах, а не в градусах)

3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector