рдЪрддреБрд╖реНрдХреЛрдгреАрдп рдкреЗрдбрд╝ рдФрд░ рдЯрдХрд░рд╛рд╡ рдХреА рдкрд╣рдЪрд╛рди

рдЫрд╡рд┐

рдпрд╣ рд╕рдкреНрддрд╛рд╣ рдЫреЛрдЯрд╛ рдерд╛, рд╕реЛрдорд╡рд╛рд░ рдФрд░ рдордВрдЧрд▓рд╡рд╛рд░ рдХреЛ рдореИрдВрдиреЗ 2 рдбреА рдкреНрд░рдХрд╛рд╢ рд╡реНрдпрд╡рд╕реНрдерд╛ рдкрд░ рдХрд╛рдо рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦрд╛ред рдмрд╛рдХреА рд╕рдордп рдореИрдВрдиреЗ рдХреНрд╡рд╛рдбрдЯреНрд░реА рдкреЗрдбрд╝реЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рдмрд┐рддрд╛рдпрд╛ред

рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдЕрдкрдиреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдФрд░ рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░реВрдВрдЧрд╛ рдЬреЛ рдЗрд╕рдХреЗ рдбрд┐рдЬрд╛рдЗрди рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдЙрддреНрдкрдиреНрди рд╣реБрдП рдереЗред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдореБрдЭреЗ рдпрд╣ рдХрд╣рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдПрдХ рдЪрддреБрд░реНрднреБрдЬ рд╡реГрдХреНрд╖ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рдХреНрдпреЛрдВ рд▓рд┐рдпрд╛ред

рдХреНрд╡рд╛рдбрдЯреНрд░реА рдПрдХ рдЕрдВрддрд░рд┐рдХреНрд╖ рд╡рд┐рднрд╛рдЬрди рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рд╣реИ ред рдЕрдиреНрдп рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдкрд░ рдЗрд╕рдХрд╛ рдореБрдЦреНрдп рд▓рд╛рдн рдЗрд╕рдХреА рдЕрдиреБрдХреВрд▓рдирд╢реАрд▓рддрд╛ рд╣реИред рдпрд╣ рдбрд╛рд▓рдиреЗ, рд╣рдЯрд╛рдиреЗ рдФрд░ рдЦреЛрдЬ рдХрд░рдиреЗ рдкрд░ рдЕрдЪреНрдЫрд╛ рдкреНрд░рджрд░реНрд╢рди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдпрд╣реА рд╣реИ, рд╣рдо рдЗрд╕ рдкреЗрдбрд╝ рдХреЛ рдПрдХ рдЧрддрд┐рд╢реАрд▓ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдбреЗрдЯрд╛ рдЕрдХреНрд╕рд░ рдмрджрд▓рддрд╛ рд░рд╣рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рд╕рдВрд░рдЪрдирд╛ рд╕рдордЭрдиреЗ рдФрд░ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдлреА рдЖрд╕рд╛рди рд╣реИред

рдпрджрд┐ рдЕрдВрддрд░рд┐рдХреНрд╖ рд╡рд┐рднрд╛рдЬрди рдЖрдкрдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рд╡рд┐рд╖рдп рд╣реИ, рддреЛ рдореИрдВ рд░реЙрдмрд░реНрдЯ рдирд┐рд╕реНрдЯреНрд░реЛрдо рдХреЗ рдЗрд╕ рд▓реЗрдЦ рдХреЛ рдкрдврд╝рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред рдпрджрд┐ рдЖрдк рдЪрддреБрд╖реНрдХреЛрдгреАрдп рдкреЗрдбрд╝реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЗрд╕ рдпрд╛ рдЗрд╕ рд▓реЗрдЦ рдХреЛ рдкрдврд╝реЗрдВред

рдореЗрд░реЗ рдЦреЗрд▓ рдореЗрдВ рдРрд╕реЗ рдХреНрд╖реЗрддреНрд░ рд╣реИрдВ рдЬрд┐рдирдореЗрдВ рдХреНрд╡рд╛рдбрдЯреНрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рддреБрд░рдВрдд рднреБрдЧрддрд╛рди рдХрд░рддрд╛ рд╣реИ:

  • рдЯрдХреНрдХрд░реЛрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рджреМрд░рд╛рди, рдЪрддреБрд╖реНрдХреЛрдгреАрдп рдкреЗрдбрд╝ рдЬрд╛рдирд╡рд░-рдмрд▓ рд╡рд┐рдзрд┐ (рд╕рднреА рдЬреЛрдбрд╝реЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг) рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдХреБрд╢рд▓ рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдмрд╕реЗ рдкреНрд░рднрд╛рд╡реА рджреГрд╖реНрдЯрд┐рдХреЛрдг рдирд╣реАрдВ рд╣реИ, рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рд╡рд┐рднрд┐рдиреНрди рддрдХрдиреАрдХреЛрдВ рдФрд░ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдХрд╛ рдЕрд╡рд▓реЛрдХрди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореЗрд░реЗ рднреМрддрд┐рдХреА рдЗрдВрдЬрди рдХреЗ рдкрд╣рд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП, рдореИрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред рд╢рд╛рдпрдж рдмрд╛рдж рдореЗрдВ, рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рдореИрдВ рдПрдХ рдЕрдзрд┐рдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдЪреБрдиреВрдВрдЧрд╛ред
  • рджреГрд╢реНрдп рдЧреНрд░рд╛рдл рдореЗрдВ, рдХреНрд▓рд┐рдкрд┐рдВрдЧ рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд░рддреЗ рд╕рдордп, рдореИрдВ рд╕рднреА рджреГрд╢реНрдпрдорд╛рди рдиреЛрдбреНрд╕ рдХреА рдЦреЛрдЬ рдХреЗ рд▓рд┐рдП рдХреНрд╡рд╛рдбрдЯреНрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред
  • рдкреНрд░рдХрд╛рд╢ рд╡реНрдпрд╡рд╕реНрдерд╛ рдореЗрдВ, рдЖрдк рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрдд рдХреА рджреГрд╢реНрдпрддрд╛ рдХреЗ рдмрд╣реБрднреБрдЬ рдХреЛ рднреЗрджрдиреЗ рд╡рд╛рд▓реА рджреАрд╡рд╛рд░реЛрдВ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд╡рд╛рдбрдЯреНрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
  • рдПрдЖрдИ рдкреНрд░рдгрд╛рд▓реА рдореЗрдВ, рдЖрдк рдЙрди рд╕рднреА рд╡рд╕реНрддреБрдУрдВ рдпрд╛ рджреБрд╢реНрдордиреЛрдВ рдХреА рдЦреЛрдЬ рдХреЗ рд▓рд┐рдП рдХреНрд╡рд╛рдбрдЯреНрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╕рд╛рд░ рдХреЗ рдХрд░реАрдм рд╣реИрдВред
  • рдФрд░ рдЗрд╕реА рддрд░рд╣тАж

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЪрддреБрд╖реНрдХреЛрдгреАрдп рдкреЗрдбрд╝ рдмрд╣реБрдд рдмрд╣реБрдореБрдЦреА рд╣реИрдВред рд╡реЗ рдЖрдкрдХреЗ рдЯреВрд▓рдХрд┐рдЯ рдореЗрдВ рдПрдХ рдЕрдЪреНрдЫреА рдкреБрдирдГрдкреВрд░реНрддрд┐ рд╣реЛрдЧреАред

рд▓реЗрдЦ рдореЗрдВ рджрд┐рдЦрд╛рдП рдЧрдП рд╕рднреА рдХреЛрдб GitHub рдкрд░ рдкрд╛рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдкреНрд░рд╛рд░рдВрднрд┐рдХ рддреИрдпрд╛рд░реА


рдХреНрд╡рд╛рдбрдЯреНрд░реА рдХреЛрдб рдХрд╛ рд╡рд┐рд╡рд░рдг рджреЗрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдЬреНрдпрд╛рдорд┐рддреАрдп рдЖрджрд┐рдо рдХреЗ рд▓рд┐рдП рдЫреЛрдЯреЗ рд╡рд░реНрдЧреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: рдЖрдпрддреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Vector2 рдЕрдВрдХ рдФрд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Box рд╡рд░реНрдЧред рджреЛрдиреЛрдВ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рд╣реЛрдВрдЧреЗред

Vector2


Vector2 рд╡рд░реНрдЧ рдЕрддрд┐рд╕реВрдХреНрд╖реНрдо рд╣реИред рдЗрд╕рдореЗрдВ рдХреЗрд╡рд▓ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рд╣реЛрддреЗ рд╣реИрдВ, рд╕рд╛рде рд╣реА + рдФрд░ / рдСрдкрд░реЗрдЯрд░реНрд╕ рд╣реЛрддреЗ рд╣реИрдВред рдмрд╕ рдЗрддрдирд╛ рд╣реА рдЪрд╛рд╣рд┐рдП:

 template<typename T> class Vector2 { public: T x; T y; constexpr Vector2<T>(TX = 0, TY = 0) noexcept : x(X), y(Y) { } constexpr Vector2<T>& operator+=(const Vector2<T>& other) noexcept { x += other.x; y += other.y; return *this; } constexpr Vector2<T>& operator/=(T t) noexcept { x /= t; y /= t; return *this; } }; template<typename T> constexpr Vector2<T> operator+(Vector2<T> lhs, const Vector2<T>& rhs) noexcept { lhs += rhs; return lhs; } template<typename T> constexpr Vector2<T> operator/(Vector2<T> vec, T t) noexcept { vec /= t; return vec; } 

рдбрд┐рдмреНрдмрд╛


Box рдХреНрд▓рд╛рд╕ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реИ:

 template<typename T> class Box { public: T left; T top; T width; // Must be positive T height; // Must be positive constexpr Box(T Left = 0, T Top = 0, T Width = 0, T Height = 0) noexcept : left(Left), top(Top), width(Width), height(Height) { } constexpr Box(const Vector2<T>& position, const Vector2<T>& size) noexcept : left(position.x), top(position.y), width(size.x), height(size.y) { } constexpr T getRight() const noexcept { return left + width; } constexpr T getBottom() const noexcept { return top + height; } constexpr Vector2<T> getTopLeft() const noexcept { return Vector2<T>(left, top); } constexpr Vector2<T> getCenter() const noexcept { return Vector2<T>(left + width / 2, top + height / 2); } constexpr Vector2<T> getSize() const noexcept { return Vector2<T>(width, height); } constexpr bool contains(const Box<T>& box) const noexcept { return left <= box.left && box.getRight() <= getRight() && top <= box.top && box.getBottom() <= getBottom(); } constexpr bool intersects(const Box<T>& box) const noexcept { return !(left >= box.getRight() || getRight() <= box.left || top >= box.getBottom() || getBottom() <= box.top); } }; 

рдЗрд╕рдореЗрдВ рдХреБрдЫ рдЙрдкрдпреЛрдЧреА рдЧреЗрдЯрд░реНрд╕ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред

рдЬреЛ рдЕрдзрд┐рдХ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕рдореЗрдВ рд╡рд┐рдзрд┐ рд╢рд╛рдорд┐рд▓ рд╣реИ, рдЬреЛ рдпрд╣ рдЬрд╛рдБрдЪрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЖрдпрдд рджреВрд╕рд░реЗ рдХреЗ рдЕрдВрджрд░ рд╣реИ, рдФрд░ intersects рд╡рд┐рдзрд┐, рдЬреЛ рдпрд╣ рдЬрд╛рдБрдЪрддреА рд╣реИ рдХрд┐ рдЖрдпрдд рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдЪреНрдЫреЗрдж рдХрд░рддреА рд╣реИ рдпрд╛ рдирд╣реАрдВред

рд╣рдо рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рддреЗ рд╕рдордп рдФрд░ рд╣рдЯрд╛рддреЗ рд╕рдордп рдФрд░ intersects рдХреЛ рдкрд╣рдЪрд╛рдирддреЗ рд╕рдордп intersects рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред

Quadtree


рдпрд╣рд╛рдБ Quadtree рд╡рд░реНрдЧ Quadtree :

 template<typename T, typename GetBox, typename Equal = std::equal_to<T>, typename Float = float> class Quadtree { static_assert(std::is_convertible_v<std::invoke_result_t<GetBox, const T&>, Box<Float>>, "GetBox must be a callable of signature Box<Float>(const T&)"); static_assert(std::is_convertible_v<std::invoke_result_t<Equal, const T&, const T&>, bool>, "Equal must be a callable of signature bool(const T&, const T&)"); static_assert(std::is_arithmetic_v<Float>); public: Quadtree(const Box<Float>& box, const GetBox& getBox = GetBox(), const Equal& equal = Equal()) : mBox(box), mRoot(std::make_unique<Node>()), mGetBox(getBox), mEqual(equal) { } private: static constexpr auto Threshold = std::size_t(16); static constexpr auto MaxDepth = std::size_t(8); struct Node { std::array<std::unique_ptr<Node>, 4> children; std::vector<T> values; }; Box<Float> mBox; std::unique_ptr<Node> mRoot; GetBox mGetBox; Equal mEqual; bool isLeaf(const Node* node) const { return !static_cast<bool>(node->children[0]); } }; 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, Quadtree рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреНрд▓рд╛рд╕ рд╣реИред рдпрд╣ рд╣рдореЗрдВ рд╡рд┐рднрд┐рдиреНрди рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХрдХреНрд╖рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛, рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореИрдВрдиреЗ рд╢реБрд░реБрдЖрдд рдореЗрдВ рдмрд╛рдд рдХреА рдереАред

рдЯреЗрдореНрдкрд▓реЗрдЯ рд╡рд┐рдХрд▓реНрдк:

  • T : рдорд╛рдиреЛрдВ рдХрд╛ рдкреНрд░рдХрд╛рд░ рдЬреЛ рдЪрддреБрд╖реНрдХреЛрдг рдореЗрдВ рд╕рдорд╛рд╣рд┐рдд рд╣реЛрдЧрд╛ред T рдПрдХ рдЖрд╕рд╛рди рд╡рд░реНрдЧ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдПрдХ рдХреНрд╡рд╛рдбрдЯреНрд░реА рдХреЗ рдЕрдВрджрд░ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ, рдпрд╣ рдПрдХ рд╕реВрдЪрдХ рдпрд╛ рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рд╕рд░рд▓ рдбреЗрдЯрд╛ рд╕реНрдЯреНрд░рдХреНрдЪрд░ (POD) рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
  • GetBox : рдЙрд╕ рддрдерд╛рдХрдерд┐рдд рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдкреНрд░рдХрд╛рд░ рдЬреЛ рдЗрдирдкреБрдЯ рдкрд░ рдореВрд▓реНрдп рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдЧрд╛ рдФрд░ рдПрдХ рдЖрдпрдд рд▓реМрдЯрд╛рдПрдЧрд╛ред
  • Equal : рджреЛ рдорд╛рди рд╕рдорд╛рди рд╣реЛрдиреЗ рдкрд░ рдЬрд╛рдБрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рддрдерд╛рдХрдерд┐рдд рд╡рд╕реНрддреБ рдХрд╛ рдкреНрд░рдХрд╛рд░ред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рд╣рдо рдорд╛рдирдХ рд╕рдорд╛рдирддрд╛ рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
  • Float : рдЧрдгрдирд╛ рдореЗрдВ рдкреНрд░рдпреБрдХреНрдд рдЕрдВрдХрдЧрдгрд┐рдд рдкреНрд░рдХрд╛рд░ред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рд╣рдо float рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред

рдХрдХреНрд╖рд╛ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ, рдЯреЗрдореНрдкрд▓реЗрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рд╡реИрдзрддрд╛ рдХреА рдЬрд╛рдВрдЪ рдХреЗ рд▓рд┐рдП рддреАрди рд╕реНрдерд┐рд░ рджрд╛рд╡реЗ рд╣реИрдВред

рдЖрдЗрдП рдПрдХ рдиреЛрдб рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред рдПрдХ рдиреЛрдб рдмрд╕ рдЕрдкрдиреЗ рдЪрд╛рд░ рдмрдЪреНрдЪреЗ рдиреЛрдбреНрд╕ рдФрд░ рдЙрд╕рдореЗрдВ рдирд┐рд╣рд┐рдд рдореВрд▓реНрдпреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдХреЗ рд▓рд┐рдП рд╕рдВрдХреЗрдд рджреЗрддрд╛ рд╣реИред рд╣рдо рдЗрд╕рдореЗрдВ рдЕрдкрдиреЗ рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рдпрд╛ рдЧрд╣рд░рд╛рдИ рдореЗрдВ рд╕реНрдЯреЛрд░ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рд╡реЗ рдордХреНрдЦреА рдкрд░ рдЧрдгрдирд╛ рдХрд░реЗрдВрдЧреЗред

рдореИрдВрдиреЗ рджреЛрдиреЛрдВ рджреГрд╖реНрдЯрд┐рдХреЛрдгреЛрдВ рдХреЗ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдХрд╛ рд╕рдВрдЪрд╛рд▓рди рдХрд┐рдпрд╛ (рдПрдХ рдЖрдпрдд рдХреЛ рдЧрд╣рд░рд╛рдИ рд╕реЗ рдФрд░ рдмрд┐рдирд╛ рдмрдЪрдд рдХреЗ рд╕рдВрд░рдХреНрд╖рдг рдХреЗ рд╕рд╛рде) рдФрд░ рдЙрдиреНрд╣реЗрдВ рдордХреНрдЦреА рдкрд░ рдЧрдгрдирд╛ рдХрд░рддреЗ рд╕рдордп рдХреЛрдИ рдкреНрд░рджрд░реНрд╢рди рдЧрд┐рд░рд╛рд╡рдЯ рдирд╣реАрдВ рдорд┐рд▓реАред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рдереЛрдбрд╝реА рдореЗрдореЛрд░реА рдмрдЪрд╛рддрд╛ рд╣реИред

рдПрдХ рд╢реАрдЯ рд╕реЗ рдПрдХ рдЖрдВрддрд░рд┐рдХ рдиреЛрдб рдХреЛ рднреЗрдж рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, isLeaf рд╡рд┐рдзрд┐ isLeaf ред рдпрд╣ рд╕рд┐рд░реНрдл рдпрд╣ рдЬрд╛рдБрдЪрддрд╛ рд╣реИ рдХрд┐ рдкрд╣рд▓рд╛ рдмрдЪреНрдЪрд╛ рдЕрд╢рдХреНрдд рдирд╣реАрдВ рд╣реИред рдЪреВрдВрдХрд┐ рдЕрд╢рдХреНрдд рдпрд╛ рддреЛ рд╕рднреА рдмрдЪреНрдЪреЗ рдиреЛрдбреНрд╕ рд╣реИрдВ, рдпрд╛ рдЙрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рдирд╣реАрдВ рд╣реИ, рдпрд╣ рдХреЗрд╡рд▓ рдкрд╣рд▓реЗ рдПрдХ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред

рдЕрдм рд╣рдо Quadtree рд╕рджрд╕реНрдп Quadtree рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ:

  • mBox рдПрдХ рдЧреНрд▓реЛрдмрд▓ рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рд╣реИред рдХреНрд╡рд╛рдбрдЯреНрд░реА рдореЗрдВ рдбрд╛рд▓реЗ рдЧрдП рд╕рднреА рдореВрд▓реНрдпреЛрдВ рдХреЛ рдЗрд╕рдХреЗ рднреАрддрд░ рд╕рдорд╛рд╣рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
  • mRoot quadtree рдХрд╛ рдореВрд▓ рд╣реИред
  • mGetBox рдХреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдо рдЖрдпрдд рдХреЛ рдорд╛рди рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реЗрдВрдЧреЗред
  • mEqual рдЙрд╕ рд╡рд╕реНрддреБ рдХреЛ рдХрд╣рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдо рджреЛ рдореВрд▓реНрдпреЛрдВ рдХреА рд╕рдорд╛рдирддрд╛ рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реЗрдВрдЧреЗред

рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдмрд╕ mGetBox , mGetBox рдФрд░ mEqual рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдПрдХ рд░реВрдЯ рдиреЛрдб рднреА рдмрдирд╛рддрд╛ рд╣реИред

рдкрд┐рдЫрд▓реЗ рджреЛ рдорд╛рдкрджрдВрдбреЛрдВ, рдЬрд┐рдирдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣рдордиреЗ рдЕрднреА рддрдХ рдмрд╛рдд рдирд╣реАрдВ рдХреА рд╣реИ, рд╡реЗ рд╣реИрдВ Threshold рдФрд░ MaxDepth ред Threshold рдЙрди рдорд╛рдиреЛрдВ рдХреА рдЕрдзрд┐рдХрддрдо рд╕рдВрдЦреНрдпрд╛ рд╣реИ рдЬреЛ рдиреЛрдб рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред MaxDepth рдПрдХ рдиреЛрдб рдХреА рдЕрдзрд┐рдХрддрдо рдЧрд╣рд░рд╛рдИ рд╣реИ, рд╣рдо MaxDepth рдкрд░ рдореМрдЬреВрдж рдиреЛрдбреНрд╕ рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдирд╛ рдмрдВрдж рдХрд░ рджреЗрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрджрд┐ рдЖрдк рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдмрд╛рдзрд╛ рдбрд╛рд▓ рд╕рдХрддрд╛ рд╣реИред рдореИрдВрдиреЗ рдЗрди рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреЛ рдЕрдзрд┐рдХрддрд░ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдЪрд┐рдд рдорд╛рди рджрд┐рдпрд╛ред рдЖрдк рдЙрдиреНрд╣реЗрдВ рдЕрдкрдиреЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЕрдм рд╣рдо рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рдСрдкрд░реЗрд╢рди рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВред

рдбрд╛рд▓реЗрдВ рдФрд░ рд╣рдЯрд╛рдПрдБ


рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдореИрдВ рд╕рдореНрдорд┐рд▓рд┐рдд рдХреЛрдб рджрд┐рдЦрд╛рдКрдВ, рд╣рдореЗрдВ рдЪрд░реНрдЪрд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдХрд┐рди рдиреЛрдбреНрд╕ рдореЗрдВ рдорд╛рди рд╢рд╛рдорд┐рд▓ рд╣реЛрдВрдЧреЗред рджреЛ рд░рдгрдиреАрддрд┐рдпрд╛рдБ рд╣реИрдВ:

  • рдореВрд▓реНрдпреЛрдВ рдХреЛ рдХреЗрд╡рд▓ рдкрддреНрддрд┐рдпреЛрдВ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рдПрдХ рдорд╛рди рдХрд╛ рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рдХрдИ рдкрддреНрддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрди рд╕рднреА рдкрддреНрддрд┐рдпреЛрдВ рдореЗрдВ рдореВрд▓реНрдп рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
  • рдорд╛рди рд╕рднреА рдиреЛрдбреНрд╕ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдо рдореВрд▓реНрдп рдХреЛ рд╕рдмрд╕реЗ рдЫреЛрдЯреЗ рдиреЛрдб рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЗрд╕рдХрд╛ рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рд╣реЛрддрд╛ рд╣реИред

рдпрджрд┐ рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдЖрдпрдд рдЫреЛрдЯреЗ рдФрд░ рд▓рдЧрднрдЧ рд╕рдорд╛рди рдЖрдХрд╛рд░ рдХреЗ рд╣реИрдВ, рддреЛ рдЪреМрд░рд╛рд╣реЛрдВ рдХреА рддрд▓рд╛рд╢ рдХрд░рддреЗ рд╕рдордп рдкрд╣рд▓реА рд░рдгрдиреАрддрд┐ рдЕрдзрд┐рдХ рдкреНрд░рднрд╛рд╡реА рд╣реЛрддреА рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрджрд┐ рдмрдбрд╝реА рдЖрдпрддреЗрдВ рдореМрдЬреВрдж рд╣реИрдВ, рддреЛ рдкрддрд┐рдд рдорд╛рдорд▓реЗ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдкреНрд░рджрд░реНрд╢рди рдмрд╣реБрдд рдЦрд░рд╛рдм рд╣реЛрдЧрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рд╣рдо рдПрдХ рдорд╛рди рдбрд╛рд▓реЗрдВ рдЬрд┐рд╕рдХрд╛ рдЖрдпрдд рд╡реИрд╢реНрд╡рд┐рдХ рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рдореЗрдВ рд╣реИ, рддреЛ рдЗрд╕реЗ рд╕рднреА рдкрддреНрддрд┐рдпреЛрдВ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛ред рдФрд░ рдЕрдЧрд░ рд╣рдо рдРрд╕реЗ рдореВрд▓реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП Threshold рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕рднреА рдиреЛрдбреНрд╕ рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдЬрдм рддрдХ рдХрд┐ MaxDepth рдирд╣реАрдВ рдкрд╣реБрдВрдЪ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдорд╛рди рд╕рднреА рдкрддреНрддрд┐рдпреЛрдВ рдореЗрдВ рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдЪрддреБрд░реНрднреБрдЬ рд╕рдореНтАНрдорд┐рд▓рд┐рдд рд╣реЛрдЧрд╛  рдЯреАрдИрдПрдХреНрд╕рдЯреАрдЯреАрдЯреАрдереНрд░реЗрд╢реЛрд▓реНрдб 4 рдЯреАрдИрдПрдХреНрд╕рдЯреАрдЯреАрдЯреАрдПрдордПрдХрдПрдХреНрд╕рдбреАрдИрдкреАрдЯреАрдЬрдорд╛рди, рдФрд░ рд╡рд╣ ... рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╣реИрдВред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкрд╣рд▓реА рд░рдгрдиреАрддрд┐ рдХреЗ рд╕рд╛рде, рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рдирд╛ рдФрд░ рд╣рдЯрд╛рдирд╛ рдереЛрдбрд╝рд╛ рдзреАрдорд╛ рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╣рдореЗрдВ рдореВрд▓реНрдп рдХреЛ рдкреНрд░рддрд┐рдЪреНрдЫреЗрдж рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рдиреЛрдбреНрд╕ рдХреЛ рд╕рдореНрдорд┐рд▓рд┐рдд (рдпрд╛ рд╣рдЯрд╛рдирд╛) рдХрд░рдирд╛ рд╣реИред

рдЗрд╕рд▓рд┐рдП, рдореИрдВ рджреВрд╕рд░реА рд░рдгрдиреАрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛, рдЬрд┐рд╕рдореЗрдВ рдкрддрд┐рдд рдорд╛рдорд▓реЗ рдирд╣реАрдВ рд╣реИрдВред рдЪреВрдВрдХрд┐ рдореИрдВ рд╡рд┐рднрд┐рдиреНрди рд╕рдВрджрд░реНрднреЛрдВ рдореЗрдВ рдХреНрд╡рд╛рдбрдЯреНрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛ рд░рд╣рд╛ рд╣реВрдВ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрдЧрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рд░рдгрдиреАрддрд┐ рдЧрддрд┐рд╢реАрд▓ рд╕рдВрджрд░реНрднреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рдЙрдкрдпреБрдХреНрдд рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдЕрджреНрдпрддрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╕рдореНрдорд┐рд▓рди рдФрд░ рд╡рд┐рд▓реЛрдкрди рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рднреМрддрд┐рдХ рдЗрдВрдЬрди рдореЗрдВ рдЬрд╣рд╛рдВ рд╕рдВрд╕реНрдерд╛рдУрдВ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд╣рдо рдХрд┐рд╕ рдиреЛрдб рдореЗрдВ рдПрдХ рдорд╛рди рдбрд╛рд▓реЗрдВрдЧреЗ рдпрд╛ рд╣рдЯрд╛рдПрдВрдЧреЗ, рд╣рдо рджреЛ рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред

рдкрд╣рд▓рд╛, computeBox , рдореВрд▓ рдиреЛрдб рдХреЗ рдЖрдпрдд рдФрд░ рдЙрд╕рдХреЗ рдЪрддреБрд░реНрднреБрдЬ рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХ рджреНрд╡рд╛рд░рд╛ рдмрдЪреНрдЪреЗ рдХреЗ рдиреЛрдб рдХреА рдЖрдпрдд рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред

 Box<Float> computeBox(const Box<Float>& box, int i) const { auto origin = box.getTopLeft(); auto childSize = box.getSize() / static_cast<Float>(2); switch (i) { // North West case 0: return Box<Float>(origin, childSize); // Norst East case 1: return Box<Float>(Vector2<Float>(origin.x + childSize.x, origin.y), childSize); // South West case 2: return Box<Float>(Vector2<Float>(origin.x, origin.y + childSize.y), childSize); // South East case 3: return Box<Float>(origin + childSize, childSize); default: assert(false && "Invalid child index"); return Box<Float>(); } } 

рджреВрд╕рд░рд╛, getQuadrant , рд╡рд╣ рдХреНрд╡рд╛рдбреНрд░рдВрдЯ рд▓реМрдЯрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдорд╛рди рд╕реНрдерд┐рдд рд╣реИ:

 int getQuadrant(const Box<Float>& nodeBox, const Box<Float>& valueBox) const { auto center = nodeBox.getCenter(); // West if (valueBox.getRight() < center.x) { // North West if (valueBox.getBottom() < center.y) return 0; // South West else if (valueBox.top >= center.y) return 2; // Not contained in any quadrant else return -1; } // East else if (valueBox.left >= center.x) { // North East if (valueBox.getBottom() < center.y) return 1; // South East else if (valueBox.top >= center.y) return 3; // Not contained in any quadrant else return -1; } // Not contained in any quadrant else return -1; } 

рдпрд╣ -1 рд░рд┐рдЯрд░реНрди рдХрд░рддрд╛ рд╣реИ рдЕрдЧрд░ рдпрд╣ рдХрд┐рд╕реА рднреА рдХреНрд╡реИрдбреЗрдВрдЯ рдореЗрдВ рд╕рдорд╛рд╣рд┐рдд рдирд╣реАрдВ рд╣реИ

рдЕрдм рд╣рдо рдбрд╛рд▓рдиреЗ рдФрд░ рд╣рдЯрд╛рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВред

рдбрд╛рд▓рдиреЗ


add рд╡рд┐рдзрд┐ рдмрд╕ рдПрдХ рдирд┐рдЬреА рд╕рд╣рд╛рдпрдХ рд╡рд┐рдзрд┐ рдХрд╣рддреА рд╣реИ:

 void add(const T& value) { add(mRoot.get(), 0, mBox, value); } 

рдпрд╣рд╛рдБ рд╕рд╣рд╛рдпрдХ рд╡рд┐рдзрд┐ рдХреЛрдб рд╣реИ:

 void add(Node* node, std::size_t depth, const Box<Float>& box, const T& value) { assert(node != nullptr); assert(box.contains(mGetBox(value))); if (isLeaf(node)) { // Insert the value in this node if possible if (depth >= MaxDepth || node->values.size() < Threshold) node->values.push_back(value); // Otherwise, we split and we try again else { split(node, box); add(node, depth, box, value); } } else { auto i = getQuadrant(box, mGetBox(value)); // Add the value in a child if the value is entirely contained in it if (i != -1) add(node->children[static_cast<std::size_t>(i)].get(), depth + 1, computeBox(box, i), value); // Otherwise, we add the value in the current node else node->values.push_back(value); } } 

рд╢реБрд░реБрдЖрдд рдореЗрдВ рдХреБрдЫ рдзрд╛рд░рдгрд╛рдПрдБ рд╣реИрдВ рдЬреЛ рдпрд╣ рдкреНрд░рдорд╛рдгрд┐рдд рдХрд░рддреА рд╣реИрдВ рдХрд┐ рд╣рдо рдХреБрдЫ рднреА рдЕрддрд╛рд░реНрдХрд┐рдХ рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдРрд╕реЗ рдиреЛрдб рдореЗрдВ рдорд╛рди рдирд╣реАрдВ рдбрд╛рд▓ рд░рд╣реЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдЙрд╕рдХрд╛ рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рди рд╣реЛред

рдлрд┐рд░, рдпрджрд┐ рдиреЛрдб рдПрдХ рд╢реАрдЯ рд╣реИ, рдФрд░ рд╣рдо рдЗрд╕рдореЗрдВ рдПрдХ рдирдпрд╛ рдорд╛рди рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрд░реНрдерд╛рддреНред рд╣рдо MaxDepth рдпрд╛ Threshold рддрдХ рдирд╣реАрдВ рдкрд╣реБрдВрдЪреЗ рд╣реИрдВ, рдЗрдВрд╕рд░реНрдЯ рдХрд░реЗрдВред рдЕрдиреНрдпрдерд╛, рд╣рдо рдЗрд╕ рдиреЛрдб рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдлрд┐рд░ рд╕реЗ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред

рдпрджрд┐ рдиреЛрдб рдЖрдВрддрд░рд┐рдХ рд╣реИ, рддреЛ рд╣рдо рдЙрд╕ рдХреНрд╡рд╛рдбреНрд░рдВрдЯ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдорд╛рди рдХрд╛ рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рд╣реЛрддрд╛ рд╣реИред рдпрджрд┐ рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдмрдЪреНрдЪреЗ рдХреЗ рдиреЛрдб рдореЗрдВ рдирд┐рд╣рд┐рдд рд╣реИ, рддреЛ рд╣рдо рдПрдХ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВред рдЕрдиреНрдпрдерд╛, рдЗрд╕ рдиреЛрдб рдореЗрдВ рдбрд╛рд▓реЗрдВред

рдпрд╣рд╛рдБ рдЬреБрджрд╛рдИ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реИ:

 void split(Node* node, const Box<Float>& box) { assert(node != nullptr); assert(isLeaf(node) && "Only leaves can be split"); // Create children for (auto& child : node->children) child = std::make_unique<Node>(); // Assign values to children auto newValues = std::vector<T>(); // New values for this node for (const auto& value : node->values) { auto i = getQuadrant(box, mGetBox(value)); if (i != -1) node->children[static_cast<std::size_t>(i)]->values.push_back(value); else newValues.push_back(value); } node->values = std::move(newValues); } 

рд╣рдо рдЪрд╛рд░ рдмрдЪреНрдЪреЗ рдиреЛрдб рдмрдирд╛рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдореВрд▓ рдиреЛрдб рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдореВрд▓реНрдп рдХреЗ рд▓рд┐рдП, рд╣рдо рддрдп рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдХрд┐рд╕ рдиреЛрдб (рдмрдЪреНрдЪреЗ рдпрд╛ рдорд╛рддрд╛-рдкрд┐рддрд╛) рдореЗрдВ рдореВрд▓реНрдп рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдирд┐рд╖реНрдХрд╛рд╕рди


remove рддрд░реАрдХрд╛ рднреА рдмрд╕ рдПрдХ рд╕рд╣рд╛рдпрдХ рд╡рд┐рдзрд┐ рдХрд╣рддрд╛ рд╣реИ:

 void remove(const T& value) { remove(mRoot.get(), nullptr, mBox, value); } 

рдпрд╣рд╛рдБ рд╕рд╣рд╛рдпрдХ рд╡рд┐рдзрд┐ рдХреЛрдб рд╣реИ, рдпрд╣ рд╕рдореНрдорд┐рд▓рд┐рдд рдХреЛрдб рдХреЗ рд╕рдорд╛рди рд╣реИ:

 void remove(Node* node, Node* parent, const Box<Float>& box, const T& value) { assert(node != nullptr); assert(box.contains(mGetBox(value))); if (isLeaf(node)) { // Remove the value from node removeValue(node, value); // Try to merge the parent if (parent != nullptr) tryMerge(parent); } else { // Remove the value in a child if the value is entirely contained in it auto i = getQuadrant(box, mGetBox(value)); if (i != -1) remove(node->children[static_cast<std::size_t>(i)].get(), node, computeBox(box, i), value); // Otherwise, we remove the value from the current node else removeValue(node, value); } } 

рдпрджрд┐ рд╡рд░реНрддрдорд╛рди рдиреЛрдб рдПрдХ рд╢реАрдЯ рд╣реИ, рддреЛ рд╣рдо рдореВрд▓реНрдп рдХреЛ рд╡рд░реНрддрдорд╛рди рдиреЛрдб рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреА рд╕реВрдЪреА рд╕реЗ рд╣рдЯрд╛ рджреЗрддреЗ рд╣реИрдВ
рдФрд░ рдмрд╣рди рдиреЛрдб рдФрд░ рдЙрд╕рдХреЗ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЗ рд╕рд╛рде рдЗрд╕ рдиреЛрдб рдХреЛ рдорд░реНрдЬ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред рдЕрдиреНрдпрдерд╛, рд╣рдо рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдХрд┐рд╕ рдореВрд▓реНрдп рдХрд╛ рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рд╕реНрдерд┐рдд рд╣реИред рдпрджрд┐ рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдмрдЪреНрдЪреЗ рдХреЗ рдиреЛрдб рдореЗрдВ рдирд┐рд╣рд┐рдд рд╣реИ, рддреЛ рд╣рдо рдПрдХ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВред рдЕрдиреНрдпрдерд╛, рд╡рд░реНрддрдорд╛рди рдиреЛрдб рдХреЗ рдореВрд▓реНрдпреЛрдВ рд╕реЗ рд╣рдЯрд╛ рджреЗрдВред

рдЪреВрдВрдХрд┐ рд╣рдо рдиреЛрдб рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдореВрд▓реНрдпреЛрдВ рдХреЗ рдЖрджреЗрд╢ рдХреА рдкрд░рд╡рд╛рд╣ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдЬрдм рдореИрдВ рдорд┐рдЯрд╛рддрд╛ рд╣реВрдВ, рддреЛ рдореИрдВ рдереЛрдбрд╝рд╛ рдЕрдиреБрдХреВрд▓рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ: рдореИрдВ рдкрд┐рдЫрд▓реЗ рдорд┐рдЯрд╛рдП рдЧрдП рдореВрд▓реНрдп рдХреЛ рдХреЗрд╡рд▓ рдПрдХ рдХреЗ рд╕рд╛рде рдмрджрд▓ рджреЗрддрд╛ рд╣реВрдВ рдФрд░ рдЗрд╕реЗ рд╣рдЯрд╛ рджреЗрддрд╛ рд╣реВрдВ:

 void removeValue(Node* node, const T& value) { // Find the value in node->values auto it = std::find_if(std::begin(node->values), std::end(node->values), [this, &value](const auto& rhs){ return mEqual(value, rhs); }); assert(it != std::end(node->values) && "Trying to remove a value that is not present in the node"); // Swap with the last element and pop back *it = std::move(node->values.back()); node->values.pop_back(); } 

рд╣рдореЗрдВ tryMerge рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓рдиреЗ рдХреА tryMerge :

 void tryMerge(Node* node) { assert(node != nullptr); assert(!isLeaf(node) && "Only interior nodes can be merged"); auto nbValues = node->values.size(); for (const auto& child : node->children) { if (!isLeaf(child.get())) return; nbValues += child->values.size(); } if (nbValues <= Threshold) { node->values.reserve(nbValues); // Merge the values of all the children for (const auto& child : node->children) { for (const auto& value : child->values) node->values.push_back(value); } // Remove the children for (auto& child : node->children) child.reset(); } } 

tryMerge рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╕рднреА рдЪрд╛рдЗрд▓реНрдб рдиреЛрдбреНрд╕ рдкрддреНрддрд┐рдпрд╛рдВ рд╣реИрдВ рдФрд░ рдЗрд╕рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рдФрд░ рдЪрд╛рдЗрд▓реНрдб рдиреЛрдбреНрд╕ рдХреЗ рдорд╛рди рдереНрд░реЗрд╢реЛрд▓реНрдб рд╕реЗ рдХрдо рд╣реИрдВред рдпрджрд┐ рдРрд╕рд╛ рд╣реИ, рддреЛ рд╣рдо рдмрдЪреНрдЪреЗ рдХреЗ рдиреЛрдбреНрд╕ рд╕реЗ рд╡рд░реНрддрдорд╛рди рдиреЛрдб рддрдХ рд╕рднреА рдорд╛рдиреЛрдВ рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдмрдЪреНрдЪреЗ рдХреЗ рдиреЛрдбреНрд╕ рдХреЛ рд╣рдЯрд╛рддреЗ рд╣реИрдВред

рдЕрдВрддрд░реНрдореБрдЦреА рдЦреЛрдЬ


рдЖрдпрдд рдХреЗ рд╕рд╛рде рдЕрдВрддрд░рд╡рд┐рд░реЛрдз


рдЕрдВрдд рдореЗрдВ, рд╣рдореЗрдВ рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рдорд┐рд▓рд╛: рдЪреМрд░рд╛рд╣реЛрдВ рдХреА рдЦреЛрдЬ рдХреЗ рд▓рд┐рдПред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкрд╣рд▓рд╛ рддрд░реАрдХрд╛ рдХрд┐рд╕реА рджрд┐рдП рдЧрдП рдЖрдпрдд рдХреЛ рдкрд╛рд░ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рдореВрд▓реНрдпреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреНрд▓рд┐рдкрд┐рдВрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИред

рдпрд╣ query рдЬрд╛рдПрдЧрд╛:

 std::vector<T> query(const Box<Float>& box) const { auto values = std::vector<T>(); query(mRoot.get(), mBox, box, values); return values; } 

рдЗрд╕ рдкрджреНрдзрддрд┐ рдореЗрдВ, рд╣рдо рдмрд╕ std::vector рдЪрдпрди рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рдорд╛рди рд╢рд╛рдорд┐рд▓ рд╣реЛрдВрдЧреЗ рдЬреЛ рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рдХреЛ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рд╣реЗрд▓реНрдкрд░ рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ:

 void query(Node* node, const Box<Float>& box, const Box<Float>& queryBox, std::vector<T>& values) const { assert(node != nullptr); assert(queryBox.intersects(box)); for (const auto& value : node->values) { if (queryBox.intersects(mGetBox(value))) values.push_back(value); } if (!isLeaf(node)) { for (auto i = std::size_t(0); i < node->children.size(); ++i) { auto childBox = computeBox(box, static_cast<int>(i)); if (queryBox.intersects(childBox)) query(node->children[i].get(), childBox, queryBox, values); } } } 

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рд╡рд░реНрддрдорд╛рди рдиреЛрдб рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╕рднреА рдореВрд▓реНрдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдЬреЛ рдЕрдиреБрд░реЛрдзрд┐рдд рдЖрдпрдд рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдЪреНрдЫреЗрдж рдХрд░рддреЗ рд╣реИрдВред рдлрд┐рд░, рдпрджрд┐ рд╡рд░реНрддрдорд╛рди рдиреЛрдб рдЖрдВрддрд░рд┐рдХ рд╣реИ, рддреЛ рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдмрдЪреНрдЪреЗ рдХреЗ рдиреЛрдб рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХрд╛ рдмрд╛рдЙрдВрдб рдЖрдпрдд рдЕрдиреБрд░реЛрдзрд┐рдд рдЖрдпрдд рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдЪреНрдЫреЗрдж рдХрд░рддрд╛ рд╣реИред

рд╕рднреА рдЬреЛрдбрд╝реАрджрд╛рд░ рдЪреМрд░рд╛рд╣реЛрдВ


рджреВрд╕рд░рд╛ рд╕рдорд░реНрдерд┐рдд рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓рд╛ рдЙрди рд╕рднреА рдЬреЛрдбрд╝реЗ рдХреЗ рдорд╛рдиреЛрдВ рдХреЛ рдЦреЛрдЬрдирд╛ рд╣реИ, рдЬреЛ рдкреНрд░рддрд┐рдЪреНрдЫреЗрджрди рдкреЗрдбрд╝ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИрдВред рд╢рд╛рд░реАрд░рд┐рдХ рдЗрдВрдЬрди рдмрдирд╛рддреЗ рд╕рдордп рдпрд╣ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧреА рд╣реИред query рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╣рдо рд╕рднреА рдореВрд▓реНрдпреЛрдВ рдХреЗ рдмрд╛рдЙрдВрдбрд┐рдВрдЧ рдмреЙрдХреНрд╕ рдкрд░ query рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рдПрдХ рдЬреЛрдбрд╝реА рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдПрдХ рдЪреМрд░рд╛рд╣реЗ рдХреЛ рдЬреЛрдбрд╝рдХрд░ рдЕрдзрд┐рдХ рдХреБрд╢рд▓рддрд╛ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ( query рд╕рд╛рде рд╣рдо рдЙрдиреНрд╣реЗрдВ рджреЛ рдмрд╛рд░ рдорд┐рд▓реЗрдВрдЧреЗ)ред

рдЗрд╕реЗ рдорд╣рд╕реВрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдпрд╣ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдЪреМрд░рд╛рд╣рд╛ рдХреЗрд╡рд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ

  • рдПрдХ рдиреЛрдб рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рджреЛ рдорд╛рдиреЛрдВ рдХреЗ рдмреАрдЪ

рдпрд╛

  • рдиреЛрдб рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдореВрд▓реНрдп рдФрд░ рдЗрд╕ рдиреЛрдб рдХреЗ рд╡рдВрд╢рдЬ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдПрдХ рдФрд░ рдореВрд▓реНрдп рдХреЗ рдмреАрдЪред

рдЗрд╕ рд╡рдЬрд╣ рд╕реЗ, рд╣рдореЗрдВ рдХреЗрд╡рд▓ рдмреАрдЪ рдХреЗ рдЪреМрд░рд╛рд╣реЗ рдХреА рдЬрд╛рдБрдЪ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП:

  • рдорд╛рди рдФрд░ рдирд┐рдореНрди рдорд╛рди рдПрдХ рд╣реА рдиреЛрдб рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИрдВ

рдФрд░

  • рдореВрд▓реНрдп рдФрд░ рдореВрд▓реНрдп рд╡рдВрд╢ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрддред

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдПрдХ рд╣реА рдЪреМрд░рд╛рд╣реЗ рдХреЛ рджреЛ рдмрд╛рд░ рд░рд┐рдкреЛрд░реНрдЯ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред

рдпрд╣рд╛рдБ findAllIntersections code рд╣реИ:

 std::vector<std::pair<T, T>> findAllIntersections() const { auto intersections = std::vector<std::pair<T, T>>(); findAllIntersections(mRoot.get(), intersections); return intersections; } 

рдлрд┐рд░, рд╣рдо рдмрд╕ std::vector рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддреЗ рд╣реИрдВ std::vector рдЪреМрд░рд╛рд╣реЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдФрд░ рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП std::vector :

 void findAllIntersections(Node* node, std::vector<std::pair<T, T>>& intersections) const { // Find intersections between values stored in this node // Make sure to not report the same intersection twice for (auto i = std::size_t(0); i < node->values.size(); ++i) { for (auto j = std::size_t(0); j < i; ++j) { if (mGetBox(node->values[i]).intersects(mGetBox(node->values[j]))) intersections.emplace_back(node->values[i], node->values[j]); } } if (!isLeaf(node)) { // Values in this node can intersect values in descendants for (const auto& child : node->children) { for (const auto& value : node->values) findIntersectionsInDescendants(child.get(), value, intersections); } // Find intersections in children for (const auto& child : node->children) findAllIntersections(child.get(), intersections); } } 

рдкрд╣рд▓реЗ рдЪрд░рдг рдореЗрдВ, рд╡рд░реНрддрдорд╛рди рдиреЛрдб рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдорд╛рдиреЛрдВ рдХреЗ рдмреАрдЪ рдХреЗ рдЪреМрд░рд╛рд╣реЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХреА рдЬрд╛рддреА рд╣реИред рдлрд┐рд░, рдпрджрд┐ рд╡рд░реНрддрдорд╛рди рдиреЛрдб рдЖрдВрддрд░рд┐рдХ рд╣реИ, рддреЛ рдЗрд╕ рдиреЛрдб рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдорд╛рдиреЛрдВ рдФрд░ рдЗрд╕рдХреЗ рд╡рдВрд╢рдЬреЛрдВ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдорд╛рдиреЛрдВ рдХреЗ рдмреАрдЪ рдЪреМрд░рд╛рд╣реЛрдВ рдХреЗ рд▓рд┐рдП findIntersectionInDescendants рдЬрд╛рдБрдЪ рдХрд░реЗрдВред рдЕрдВрдд рдореЗрдВ, рд╣рдо рдкреБрдирд░рд╛рд╡рд░реНрддреА рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВред

findIntersectionsInDescendants рдЖрд╡рд░реНрддреА рд░реВрдк рд╕реЗ рджрд┐рдП рдЧрдП рдорд╛рди рдФрд░ рд╕рдмрдЯреНрд░реА рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╕рднреА рдорд╛рдиреЛрдВ рдХреЗ рдмреАрдЪ рдХреЗ рдЕрдВрддрд░ рдХреЛ рдкрд╛рддрд╛ рд╣реИ:

 void findIntersectionsInDescendants(Node* node, const T& value, std::vector<std::pair<T, T>>& intersections) const { // Test against the values stored in this node for (const auto& other : node->values) { if (mGetBox(value).intersects(mGetBox(other))) intersections.emplace_back(value, other); } // Test against values stored into descendants of this node if (!isLeaf(node)) { for (const auto& child : node->children) findIntersectionsInDescendants(child.get(), value, intersections); } } 

рд╡рд╣ рд╕рдм рд╣реИ! рдореИрдВ рджреЛрд╣рд░рд╛рддрд╛ рд╣реВрдВ, рд╕рднреА рдХреЛрдб GitHub рдкрд░ рдкреЛрд╕реНрдЯ рдХрд┐рдП рдЧрдП рд╣реИрдВред

рдЙрдкрдпреЛрдЧреА рд╕рдВрд╕рд╛рдзрди


рдпрджрд┐ рдЖрдк рдЯрдХрд░рд╛рд╡ рдХреА рдкрд╣рдЪрд╛рди рдФрд░ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рд╡рд┐рднрд╛рдЬрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдореИрдВ рдХреНрд░рд┐рд╕реНрдЯрд░ рдПрд░рд┐рдХрд╕рди рд░рд┐рдпрд▓-рдЯрд╛рдЗрдо рдЯрдХрд░рд╛рд╡ рдЬрд╛рдВрдЪ рджреНрд╡рд╛рд░рд╛ рдкреБрд╕реНрддрдХ рдкрдврд╝рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред рдЗрд╕рдореЗрдВ рдХрдИ рд╡рд┐рд╖рдпреЛрдВ рдХрд╛ рдЧрд╣рд░рд╛рдИ рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдФрд░ рд╕рд╛рде рд╣реА рд╕рд╛рде рдпрд╣ рдкреБрд╕реНрддрдХ рдмрд╣реБрдд рд╣реА рд╕рдордЭрджрд╛рд░ рднрд╛рд╖рд╛ рдореЗрдВ рд▓рд┐рдЦреА рдЧрдИ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрдзреНрдпрд╛рдпреЛрдВ рдХреЛ рдЕрд▓рдЧ рд╕реЗ рдкрдврд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдПрдХ рдорд╣рд╛рди рд╕рдВрджрд░реНрдн рд╕реНрд░реЛрдд рд╣реИред

рдирд┐рд╖реНрдХрд░реНрд╖


рдпрд╣ рдЯрдХрд░рд╛рд╡ рдХреА рдорд╛рдиреНрдпрддрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣ рдХреЗрд╡рд▓ рдЖрдзрд╛ рднреМрддрд┐рдХ рдЗрдВрдЬрди рд╣реИред рджреВрд╕рд░реА рдЫрдорд╛рд╣реА рдЯрдХреНрдХрд░реЛрдВ рдХрд╛ рд╕рдВрдХрд▓реНрдк рд╣реИ ред

Source: https://habr.com/ru/post/hi473066/


All Articles