LINUX.ORG.RU

Вспоминаю школьный курс геометрии

 , , ,


1

1

Решил порисовать прямоугольники. Голубые статичные, розовый можно двигать. У каждого прямоугольника 4 параметра: координаты центра, длина, ширина.
Сравнивать положение таким образом не очень удобно, потому я использую север-юг, запад-восток для каждого. Вот проверка попадания розового (p) в голубой (o):

if (o.getW() < p.getE() && o.getE() > p.getW() &&
    o.getN() < p.getS() && o.getS() > p.getN())
Проверка срабатывает правильно. А теперь мне нужно как-то не дать розовому прямоугольнику попасть в голубой. Даже не могу представить, как это можно сделать (скоростей-то нет, только координаты и размеры).
Нужно при попадании розового прямоугольника в голубой (при выполнении условия выше) изменить его координату так, чтобы он оказался вне голубого, будто бы и не входил в него.

★★★★★

Последнее исправление: CYB3R (всего исправлений: 1)

пересечение двух прямоугольников дает прямоугольник меньше или равного размера, от центра этого прямоугольника вычисляешь длины перпендикуляров ко всем сторонам голубого прямоугольника, затем розовый прямоугольник сдвигаешь на минимальный перпендикуляр.

anonymous
()
Ответ на: комментарий от anonymous

Собственно, /thread.

//Другой анонимус.

anonymous
()
Ответ на: комментарий от CYB3R

если какая-нибудь вершина «входит» в голубой прямоугольник, то смотри, насколько по Х и по У перекрывается (дельты) и от каждой вершины розового эти дельты отнимай/прибавляй. Т.е. смотри, насколько залез, и возвращай в самый край, когда «не залез».

bvn13 ★★★★★
()
Ответ на: комментарий от anonymous

О, классное решение, спасибо!

CYB3R ★★★★★
() автор топика

Вещества, алкоголь, шизофрения или просто низкий IQ? Или все вместе?

anonymous
()
Ответ на: комментарий от CYB3R

Ну, и шизофрения, наверное.

CYB3R ★★★★★
() автор топика

У каждого прямоугольника 4 параметра: координаты центра, длина, ширина.

Тогда лучше сравнивать так:

struct sRect
{
    int x;
    int y;
    int width;
    int height;
}; // rc1 and rc2

const int w2 = (rc1.width + rc2.width) / 2;
const int h2 = (rc1.height + rc2.height) / 2;
const int dx = abs(rc1.x - rc2.x);
const int dy = abs(rc1.y - rc2.y);
if(dx < w2 && dy < h2)
{
    // collide detected
}

andreyu ★★★★★
()
Ответ на: комментарий от nickionn

Это было бы идеальным решением, если бы за кадр любой объект мог сдвинуться только на один пиксель. Если за кадр он делает скачок в 30 пикселей, а до препятствия осталось 29, то будет большой зазор.

CYB3R ★★★★★
() автор топика
Ответ на: комментарий от CYB3R

Да. С моим вариантом он будет «отпрыгивать». Тебе надо как уже сказали, при столкновении перемещать розовый прямоугольник, к краю голубого.

nickionn ★☆
()

Реализуем функцию из оффтоп-апи IsRectIntersect и пляшем от неё. Маленький хинт - ваш прямоугольник, с параллельными осям сторонами - ни что иное, как декартово произведение одномерных отрезков, а для проверки пересечения отрезков прямой можно, (и нужно) использовать следующий код:

int segment_intersects ( segment const& lhs, segment const& rhs ) throw()
{
  return lhs.left() <= rhs.right() && rhs.left() <= lhs.right();
}

nikitos ★★★
()
Ответ на: комментарий от CYB3R

Чем лучше? Разве там не столько же расчётов?

Можно сделать условие вложенным и сократить количество расчетов.

const int w2 = (rc1.width + rc2.width) / 2;
const int dx = abs(rc1.x - rc2.x);
if(dx < w2)
{
    const int h2 = (rc1.height + rc2.height) / 2;
    const int dy = abs(rc1.y - rc2.y);
    if(dy < h2)
    {
        // collide detected
    }
}

Опять же этот код хорошо оптимизируется при тестировании одного прямоугольника с большом количестве других прямоугольников (можно рассчитать полуширину и полувысоту вне цикла).

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

А если отсортировать по координатам, то можно избавиться и от abs().

andreyu ★★★★★
()

А теперь мне нужно как-то не дать розовому прямоугольнику попасть в голубой.

ну так и проверяешь:

1. по оси x.

2. по оси y.

если есть (было по дороге) пересечение, меняешь скорость на противоположную. (оно IRL так и получается, потому что если объект отпрыгивает, то она «входит» в стенку. Точнее упруго деформируется) Обычно считается, что объект «стенка» намного массивнее объекта «мячик», и её(стенки) скорость не меняется.

С такой «физикой» угол падения очевидно равен углу отражения, что IRL и бывает.

emulek
()
Ответ на: комментарий от Bad_ptr

Возьми сразу box2d

Идея хорошая, только не сложнее ли мне будет дружить мою отрисовку с физикой, которую будет считать Box2D?

CYB3R ★★★★★
() автор топика
Ответ на: комментарий от CYB3R

Идея хорошая, только не сложнее ли мне будет дружить мою отрисовку с физикой, которую будет считать Box2D?

Нет там ничего сложного - пробежался по миру, получил координаты и угол, привел их к экранным координатам, отрисовал.

Вопрос в другом - не будет ли это стрельбой из пушки по воробьям.

andreyu ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.