Теорема о разделяющей оси на C++

348
15 июля 2022, 22:40

Я пытаюсь реализовать обработку столкновений с помощью SAT, но в интернете встречается лишь теория о отрывки практики. У меня появилось два вопроса:

  1. Как узнать, какие стороны фигур проверять на столкновения?
  2. Как получить ось для проверки?
  3. Как спроецировать стороны на ось?

У меня есть фигура(массив вершин), а также метод(getEdges()), который возвращает вектор объектов класса Edge. класс Edge имеет координаты начала стороны и координаты конца стороны.

class Edge
{
public: 
    Vector2f p1;
    Vector2f p2;
    Edge(){}
    Edge(Vector2f p1, Vector2f p2)
    {
        this->p1 = p1;
        this->p2 = p2;
    }
};

Заранее спасибо с:

Answer 1

Вот и теория, и чудный краткий код: Intersection of Convex Objects: The Method of Separating Axes

int WhichSide(PointSet S, Point D, Point P)
{
    // S vertices are projected to the form P+t*D.
    //Return value is + 1 if all t > 0,
    // -1 if all t < 0, 0 otherwise, in which case the line splits the polygon.
    positive = 0;
    negative = 0;
    for (i = 0; i < C.N; i++) {
        t = Dot(D, S.V(i) - P);
        if (t > 0)
            positive++;
        else if (t < 0)
            negative++;
        if (positive && negative)
            return 0;
    }
    return (positive ? +1 : -1);
}
bool TestIntersection2D(ConvexPolygon C0, ConvexPolygon C1)
{
    // Test edges of C0 for separation.  Because of the counterclockwise ordering,
    // the projection interval for C0 is [m,0] where m <= 0.  Only try  to determine
    // if C1 is on the ‘positive’ side of the line.
            for (i0 = 0, i1 = C0.N - 1; i0 < C0.N; i1 = i0, i0++)
        {
            D = Perp(C0.V(i0) - C0.V(i1));
            if (WhichSide(C1.V, D, C0.V(i0)) > 0) {
                // C1 is entirely on ‘positive’ side of line C0.V(i0)+t*D
                return false;
            }
        }
    // Test edges of C1 for separation. Because of the counterclockwise ordering,
    // the projection interval for C1 is [m,0] where m <= 0. Only try to determine
    // if C0 is on the ‘positive’ side of the line.
            for (i0 = 0, i1 = C1.N - 1; i0 < C1.N; i1 = i0, i0++)
        {
            D = Perp(C1.V(i0) - C1.V(i1));
            if (WhichSide(C0.V, D, C1.V(i0)) > 0) {
                // C0 is entirely on ‘positive’ side of line C1.V(i0)+t*D
                return false;
            }
        }
    return true;
}
READ ALSO
Ошибка разыменования указателя в С++

Ошибка разыменования указателя в С++

ЗдравствуйтеПочему когда я разыменовываю pointer вылетает ошибка?

286
что возвращает decltype и как он работает?

что возвращает decltype и как он работает?

Всем здравствуйтеЯ начал недавно изучать c++ и столкнулся с оператором decltype

338
Создание М-мерного дерева на языке Си

Создание М-мерного дерева на языке Си

Здравствуйтe, Хочу написать собственное дерево на языке си, каждый узел которого имеет более двух потомковЯ создал структуру, в которую входит...

258
Ввод переменной типа enum с клавиатуры

Ввод переменной типа enum с клавиатуры

У меня есть класс HealthyFood и enum Fruits{ apple, pear, peach, orange}Я создаю в ранее сказанном классе переменную fruit типа данных Fruits и хочу создать сеттер для...

285