Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 0
Регистрация: 17.02.2023
Сообщений: 13

Неправильная работа алгоритма обнаружения столкновений GJK

08.04.2024, 18:41. Показов 2418. Ответов 0

Студворк — интернет-сервис помощи студентам
У меня есть ошибка с алгоритмом GJK. Я использую библиотеку glm и столкнулся с проблемой, что когда я увеличиваю размер модели с помощью матрицы, алгоритм GJK не находит столкновения (часть объекта может быть погружена в другой объект, но столкновения не происходит) Вот код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
struct Vertex
{
    glm::vec3 pos;
    glm::vec3 color;
    glm::vec2 texCoord;
};
 
struct Mesh
{
    std::vector<Vertex> vertices;
    std::vector<uint32_t> indices;
    std::vector<glm::dvec3> hitBox;
    glm::dmat4 model;
    glm::dmat4 invModel;
 
    void setModel(const glm::dmat4 &model)
    {
        this->model = model;
        this->invModel = glm::inverse(model);
    }
};
 
enum class SimplexType 
{
    Zero,
    Point,
    Line,
    Triangle,
    Tetrahedron
};
 
struct Simplex
{
    std::list<glm::dvec3> points{};
 
    Simplex() = default;
 
    Simplex(std::initializer_list<glm::dvec3> list) 
    {
        for (const auto& v : list) 
        {
            points.push_back(v);
            if (points.size() > 4) 
            {
                points.pop_front();
            }
        }
    }
 
    void push_front(const glm::dvec3 &point) 
    {
        points.push_front(point);
        if (points.size() > 4) 
        {
            points.pop_back();
        }
    }
 
    glm::dvec3 operator[](size_t i) const 
    {
        auto it = points.begin();
        for (size_t k = 0; k < i; k++) 
        {
            ++it;
        }
        return *it;
 
    }
 
    [[nodiscard]] size_t size() const { return points.size(); }
 
    [[nodiscard]] auto begin() const { return points.begin(); }
 
    [[nodiscard]] auto end() const { return points.end(); }
 
    [[nodiscard]] SimplexType type() const { return static_cast<SimplexType>(points.size()); }
};
 
struct NextSimplex
{
    const Simplex newSimplex;
    const glm::dvec3 newDirection;
    const bool finishSearching;
};
 
class RigidBody
{
public:
    Mesh mesh;
 
    glm::dvec3 findFurthestPoint(const glm::dvec3 &direction)
    {
        glm::dvec3 maxPoint = glm::dvec3(0.0, 0.0, 0.0);
        double maxDistance = 0.0;
 
        glm::dvec3 transformedDirection = glm::normalize(this->mesh.invModel * glm::dvec4(direction, 0.0));
 
        for (auto &it : mesh.hitBox)
        {
            double distance = glm::dot(it, transformedDirection);
 
            if (distance > maxDistance)
            {
                maxDistance = distance;
                maxPoint = it;
            }
        }
 
        return mesh.model * glm::dvec4(maxPoint, 1.0);
    }
 
    glm::dvec3 support(RigidBody &obj, const glm::dvec3 &direction)
    {
        glm::dvec3 p1 = findFurthestPoint(direction);
        glm::dvec3 p2 = obj.findFurthestPoint(-direction);
 
        return p1 - p2;
    }
 
    NextSimplex lineCase(const Simplex &points)
    {
        Simplex newPoints(points);
        glm::dvec3 newDirection;
 
        glm::dvec3 a = points[0];
        glm::dvec3 b = points[1];
 
        glm::dvec3 ab = b - a;
        glm::dvec3 ao = -a;
 
        if (glm::dot(ab, ao) > 0)
        {
            newDirection = glm::cross(glm::cross(ab, ao), ab);
        }
        else
        {
            newPoints = Simplex{ a };
            newDirection = ao;
        }
 
        return NextSimplex{ newPoints, newDirection, false };
    }
 
    NextSimplex triangleCase(const Simplex &points)
    {
        Simplex newPoints(points);
        glm::dvec3 newDirection{};
 
        glm::dvec3 a = points[0];
        glm::dvec3 b = points[1];
        glm::dvec3 c = points[2];
 
        glm::dvec3 ab = b - a;
        glm::dvec3 ac = c - a;
        glm::dvec3 ao = -a;
 
        glm::dvec3 abc = glm::cross(ab, ac);
 
        if (glm::dot(glm::cross(abc, ac), ao) > 0)
        {
            if (glm::dot(ac, ao) > 0)
            {
                newPoints = Simplex{ a, c };
                newDirection = glm::cross(glm::cross(ac, ao), ac);
            }
            else
            {
                return lineCase(Simplex{ a, b });
            }
        }
        else
        {
            if (glm::dot(glm::cross(ab, abc), ao) > 0)
            {
                return lineCase(Simplex{ a, b });
            }
            else
            {
                if (glm::dot(abc, ao) > 0)
                {
                    newDirection = abc;
                }
                else
                {
                    newDirection = -abc;
                    newPoints = Simplex{ a, c, b };
                }
            }
        }
 
        return NextSimplex{ newPoints, newDirection, false };
    }
 
    NextSimplex tetrahedronCase(const Simplex &points)
    {
        glm::dvec3 a = points[0];
        glm::dvec3 b = points[1];
        glm::dvec3 c = points[2];
        glm::dvec3 d = points[3];
 
        glm::dvec3 ab = b - a;
        glm::dvec3 ac = c - a;
        glm::dvec3 ad = d - a;
        glm::dvec3 ao = -a;
 
        glm::dvec3 abc = glm::cross(ab, ac);
        glm::dvec3 acd = glm::cross(ac, ad);
        glm::dvec3 adb = glm::cross(ad, ab);
 
        if (glm::dot(abc, ao) > 0)
        {
            return triangleCase(Simplex{ a, b, c });
        }
 
        if (glm::dot(acd, ao) > 0)
        {
            return triangleCase(Simplex{ a, c, d });
        }
 
        if (glm::dot(adb, ao) > 0)
        {
            return triangleCase(Simplex{ a, d, b });
        }
 
        return NextSimplex(points, glm::dvec3(), true);
    }
 
    NextSimplex nextSimplex(const Simplex &points)
    {
        switch (points.type())
        {
        case SimplexType::Line:
            return lineCase(points);
        case SimplexType::Triangle:
            return triangleCase(points);
        case SimplexType::Tetrahedron:
            return tetrahedronCase(points);
 
        default:
            throw std::logic_error("Simplex is not line, triangle or tetrahedron");
        }
    }
 
    std::pair<bool, Simplex> checkGJKCollision(RigidBody &obj)
    {
        glm::dvec3 support = this->support(obj, glm::dvec3(1.0, 0.0, 0.0));
 
        Simplex points{};
        points.push_front(support);
 
        glm::dvec3 direction = -support;
 
        size_t iters = 0;
        while (++iters < mesh.vertices.size() + obj.mesh.vertices.size())
        {
            support = this->support(obj, direction);
 
            if (glm::dot(support, direction) <= 0)
                return std::make_pair(false, points);
 
            points.push_front(support);
 
            NextSimplex nextSimplex = this->nextSimplex(points);
            direction = nextSimplex.newDirection;
            points = nextSimplex.newSimplex;
 
            if (nextSimplex.finishSearching)
            {
                return std::make_pair(true, points);
            }
        }
 
        return std::make_pair(false, points);
    }
};
Конец кода

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
glm::dvec3 findFurthestPoint(const glm::dvec3 &direction)
{
    glm::dvec3 maxPoint = glm::dvec3(0.0, 0.0, 0.0);
    double maxDistance = 0.0;
 
    glm::dvec3 transformedDirection = glm::normalize(this->mesh.invModel * glm::dvec4(direction, 0.0));
 
    for (auto &it : mesh.hitBox)
    {
        double distance = glm::dot(it, transformedDirection);
 
        if (distance > maxDistance)
        {
            maxDistance = distance;
            maxPoint = it;
        }
    }
 
    return mesh.model * glm::dvec4(maxPoint, 1.0);
}
Следует отметить, что если умножать it каждую итерацию цикла на матрицу модели, то ошибок не возникает. Возможно, проблема в матрице invModel, но я не понимаю, в чем она заключается. Где я допустил ошибку?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.04.2024, 18:41
Ответы с готовыми решениями:

Лагнутость игры в графике и неправильная работа правильного алгоритма
Извините, что задаю две темы в одной, но я думаю, что они связаны между собой неким образом... Весь код представлен в конце темы. ...

Неправильная работа алгоритма в некоторых тестах
Написал программу, которая должна выводить количество гласных букв в каждом слове из введённого предложения. Код рабочий, но иногда на...

Моделирование алгоритма обнаружения радиосигналов
Привет всем. Нужна помощь в решении следующей задачи. Необходимо промоделировать алгоритм обнаружения радиосигналов в Матлаб или в GNU...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.04.2024, 18:41
Помогаю со студенческими работами здесь

Полиморфизм столкновений/Система обработки столкновений
Код: https://github.com/clasher113/space-shooter Файл src/windows/Game.cpp В файле происходит проверка на столкновение объектов друг...

Неправильная работа if
Привет! Задали по лабараторки сделать программу, обрабатывающию 2 уровнения. Задание: y=f1 если C, в противном случае y=f2 (сами функции...

Неправильная работа
Почему на неправильно работает? #include&lt;iostream&gt; using namespace std; int main() { int b; for (int i=0; i&lt;=14;...

Неправильная работа if
import random, os Numbers = while True: comp = random.choice(Numbers) player = input('Введите число от 1 до 5 ') ...

Неправильная работа БД
Добрый вечер. Проблема такова: Есть вот такой код: private void InitializeDataGridView() { List&lt;string&gt; data =...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru