Мне сказали, что четырехугольное дерево является идеальной структурой данных для моей игры, но у меня возникают проблемы с пониманием того, как именно формы работают в четырехугольных деревьях.
Я делаю это в JavaScript, но я думаю, что эти вопросы могут применяться к деревьям квадратов на любом языке.
Я думаю, что в основном понимаю, как базовые (x, y) точки и вставка точек работают в четырехугольных деревьях, и что я могу сделать это на бумаге.
Вот JSfiddle из моих экспериментов с точками.
Помимо одного случая, мои тесты с баллами работают как положено.
Но мое замешательство начинается, когда фигуры, подобные прямоугольникам, задействованы. Когда вы извлекаете данные из четырехугольного дерева с фигурами, проверяет ли оно каждую точку фигуры и в какие узлы они попадают? И как же работает вставка фигур, когда она принимает (x, y, width, height) параметры для каждой фигуры? Использует ли он ширину / высоту от начальной точки для вычисления других угловых точек, которые затем распределяются по соответствующим узлам? Если вставленная фигура охватывает четыре узла, сохраняются ли данные этой фигуры во всех четырех узлах?
И когда метод поиска принимает форму в качестве параметра (x, y, width, height), что на самом деле происходит? Сначала он видит, на какие узлы распространяется форма, если ее вставить, а затем извлекает все объекты этих узлов?
У меня есть JSfiddle, работающий с фигурами , но я совершенно запутался в результатах своего тестирования. Я получаю дубликаты объектов, которые возвращаются!
Например, красный квадрат - это нарисованный эквивалент параметров, которые я ввожу в свой метод поиска. Я думаю, что, поскольку этот красный квадрат охватывает все четыре узла, он должен возвращать каждый объект в четырехугольном дереве! Но это не так, и у меня возникают проблемы с рационализацией того, что он возвращает. У меня есть ряд других тестов, которые в настоящее время закомментированы, но вы можете отменить комментирование и запустить их, чтобы увидеть более запутанные результаты!
Как сказать, если я хочу вернуть все точки в четырехугольном дереве, как бы я это сделал? Метод извлечения, использующий фигуру по всему размеру границ? Например, получить (0, 0, canvas.width, canvas.height)?
Библиотека JavaScript QuadTree, которую я использую, упоминалась в различных других источниках, поэтому я предполагаю, что фактическая реализация является правильной и заслуживающей доверия.
Я думаю, что большая часть моей путаницы может быть вызвана неправильным пониманием терминологии четырехъядерных деревьев. Например, почему они говорят о границах, а не о размерах, когда у «точки» также есть параметры ширины / высоты? Это условность / сокращение или это совершенно разные понятия?
Спасибо за ваше время!
источник
_stuckChildren
поля в коде. Вы также можете увидеть это в примере «извлечение элементов с границами» - он всегда выделяет красным узлы, которые пересекают границы узлов, по которым вы щелкнули, вплоть до корневого узла.Ответы:
Quadtree обычно хранят и получают прямоугольники. Точка - это особый случай, когда ширина и высота равны нулю. Следующая логика используется, чтобы найти дом для новых прямоугольников в дереве, начиная с корневого узла:
Обратите внимание, что прямоугольники могут храниться на любой глубине, это не обязательно должен быть четырехугольник листа. Если прямоугольник пересекает границу прямо на корневом уровне, корневой квад будет хранить прямоугольник.
При запросе quadtree он будет возвращать только те прямоугольники, которые содержатся в запросе. В вашем примере вы заставляете смотреть каждый из 4 дочерних квадов более детально, потому что красный прямоугольник запроса пересекает каждый дочерний квад. Поскольку у детей больше нет детей, каждый из прямоугольников в этих дочерних квадратах будет сравниваться с красным прямоугольником. Поскольку ни один из прямоугольников в дереве не сталкивается с красным прямоугольником запроса, ничего не должно быть возвращено.
Вы действительно начинаете видеть преимущества дерева квадрантов, когда у вас много объектов и много места для объектов по сравнению с областями запросов. В этих случаях небольшая область запросов может быстро исключить из рассмотрения обширные куски четырехугольного дерева. Только квадраты, которые пересекаются с прямоугольником запроса, будут рассмотрены более подробно.
РЕДАКТИРОВАТЬ
Извлечение обычно выполняется следующим образом:
Однако в вашей библиотеке, похоже, не проверяется, пересекаются ли возвращаемые прямоугольники с запросом, поэтому вам нужно добавить это самостоятельно.
источник
retrieve
метод для сокращения списка. Здесь вы можете увидеть, что он делает, более четко: mikechambers.com/html5/javascript/QuadTree/examples/…