[ Обновленные темы · Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Пишем QuadTree (C++)
Fire-RunДата: Среда, 19.12.2018, 12:29 | Сообщение # 1
Генералиссимус
Группа: Администраторы
Сообщений: 43
Награды: 0
Репутация: 10
Статус: Оффлайн
Quad TreeЧетыре дерева - это деревья, используемые для эффективного хранения данных точек в двумерном пространстве. В этом дереве каждый узел имеет не более четырех дочерних элементов.
Мы можем построить квадродерево из двумерной области, используя следующие шаги:
  • Разделите текущее двухмерное пространство на четыре поля.
  • Если в блоке содержится одна или несколько точек, создайте дочерний объект, сохранив в нем двухмерное пространство блока.
  • Если поле не содержит точек, не создавайте для него дочерний элемент
  • Рекурс для каждого из детей.
    Четыре дерева используются в сжатии изображений, где каждый узел содержит средний цвет каждого из его дочерних элементов. Чем глубже вы проходите по дереву, тем больше деталей изображения.
    Четыре дерева также используются при поиске узлов в двумерной области. Например, если вы хотите найти ближайшую точку к заданным координатам, вы можете сделать это с помощью четырех деревьев.
    Функция вставки Функции
    вставки используются для вставки узла в существующее дерево квадов. Эта функция сначала проверяет, находится ли данный узел в границах текущего четырехугольника. Если это не так, то мы немедленно прекращаем вставку. Если он находится в пределах границ, мы выбираем соответствующий дочерний элемент для размещения этого узла в зависимости от его местоположения.
    Эта функция - O (Log N), где N - размер расстояния.
    Функция поиска Функция
    поиска используется для определения местоположения узла в данном квадре. Его также можно изменить, чтобы он возвращал ближайший узел к заданной точке. Эта функция реализуется путем взятия заданной точки, сравнения с границами дочерних квадратов и рекурсии.
    Эта функция - O (Log N), где N - размер расстояния.
    Рекомендуется: Пожалуйста, сначала попробуйте подход {IDE} , прежде чем переходить к решению.

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

    
    Код
    // C++ Implementation of Quad Tree #include <iostream> #include <cmath> using namespace std;   // Used to hold details of a point struct Point {     int x;     int y;     Point(int _x, int _y)     {         x = _x;         y = _y;     }     Point()     {         x = 0;         y = 0;     } };   // The objects that we want stored in the quadtree struct Node {     Point pos;     int data;     Node(Point _pos, int _data)     {         pos = _pos;         data = _data;     }     Node()     {         data = 0;     } };   // The main quadtree class class Quad {     // Hold details of the boundary of this node     Point topLeft;     Point botRight;       // Contains details of node     Node *n;       // Children of this tree     Quad *topLeftTree;     Quad *topRightTree;     Quad *botLeftTree;     Quad *botRightTree;   public:     Quad()     {         topLeft = Point(0, 0);         botRight = Point(0, 0);         n = NULL;         topLeftTree  = NULL;         topRightTree = NULL;         botLeftTree  = NULL;         botRightTree = NULL;     }     Quad(Point topL, Point botR)     {         n = NULL;         topLeftTree  = NULL;         topRightTree = NULL;         botLeftTree  = NULL;         botRightTree = NULL;         topLeft = topL;         botRight = botR;     }     void insert(Node*);     Node* search(Point);     bool inBoundary(Point); };   // Insert a node into the quadtree void Quad::insert(Node *node) {     if (node == NULL)         return;       // Current quad cannot contain it     if (!inBoundary(node->pos))         return;       // We are at a quad of unit area     // We cannot subdivide this quad further     if (abs(topLeft.x - botRight.x) <= 1 &&         abs(topLeft.y - botRight.y) <= 1)     {         if (n == NULL)             n = node;         return;     }       if ((topLeft.x + botRight.x) / 2 >= node->pos.x)     {         // Indicates topLeftTree         if ((topLeft.y + botRight.y) / 2 >= node->pos.y)         {             if (topLeftTree == NULL)                 topLeftTree = new Quad(                     Point(topLeft.x, topLeft.y),                     Point((topLeft.x + botRight.x) / 2,                         (topLeft.y + botRight.y) / 2));             topLeftTree->insert(node);         }           // Indicates botLeftTree         else        {             if (botLeftTree == NULL)                 botLeftTree = new Quad(                     Point(topLeft.x,                         (topLeft.y + botRight.y) / 2),                     Point((topLeft.x + botRight.x) / 2,                         botRight.y));             botLeftTree->insert(node);         }     }     else    {         // Indicates topRightTree         if ((topLeft.y + botRight.y) / 2 >= node->pos.y)         {             if (topRightTree == NULL)                 topRightTree = new Quad(                     Point((topLeft.x + botRight.x) / 2,                         topLeft.y),                     Point(botRight.x,                         (topLeft.y + botRight.y) / 2));             topRightTree->insert(node);         }           // Indicates botRightTree         else        {             if (botRightTree == NULL)                 botRightTree = new Quad(                     Point((topLeft.x + botRight.x) / 2,                         (topLeft.y + botRight.y) / 2),                     Point(botRight.x, botRight.y));             botRightTree->insert(node);         }     } }   // Find a node in a quadtree Node* Quad::search(Point p) {     // Current quad cannot contain it     if (!inBoundary(p))         return NULL;       // We are at a quad of unit length     // We cannot subdivide this quad further     if (n != NULL)         return n;       if ((topLeft.x + botRight.x) / 2 >= p.x)     {         // Indicates topLeftTree         if ((topLeft.y + botRight.y) / 2 >= p.y)         {             if (topLeftTree == NULL)                 return NULL;             return topLeftTree->search(p);         }           // Indicates botLeftTree         else        {             if (botLeftTree == NULL)                 return NULL;             return botLeftTree->search(p);         }     }     else    {         // Indicates topRightTree         if ((topLeft.y + botRight.y) / 2 >= p.y)         {             if (topRightTree == NULL)                 return NULL;             return topRightTree->search(p);         }           // Indicates botRightTree         else        {             if (botRightTree == NULL)                 return NULL;             return botRightTree->search(p);         }     } };   // Check if current quadtree contains the point bool Quad::inBoundary(Point p) {     return (p.x >= topLeft.x &&         p.x <= botRight.x &&         p.y >= topLeft.y &&         p.y <= botRight.y); }   // Driver program int main() {     Quad center(Point(0, 0), Point(8, 8));     Node a(Point(1, 1), 1);     Node b(Point(2, 5), 2);     Node c(Point(7, 6), 3);     center.insert(&a);     center.insert(&b);     center.insert(&c);     cout << "Node a: " <<         center.search(Point(1, 1))->data << "\n";     cout << "Node b: " <<         center.search(Point(2, 5))->data << "\n";     cout << "Node c: " <<         center.search(Point(7, 6))->data << "\n";     cout << "Non-existing node: "        << center.search(Point(5, 5));     return 0; }

    Вывод:
    Узел А: 1
    Узел б: 2
    Узел с: 3
    Несуществующий узел: 0

    Упражнение:
    реализовать дерево квадов, которое возвращает 4 ближайших узла к заданной точке.
    Прикрепления: quadtree.cpp (5.6 Kb)
  •  
    • Страница 1 из 1
    • 1
    Поиск: