Skip to main content
File added late

1 file was added to this release more than 14 days after its initial publication. Inspect the release files before installing.

Quadtrees iterating on pairs of neighbouring items

A quadtree is a tree data structure in which each node has exactly four children. It is a particularly efficient way to store elements when you need to quickly find them according to their x-y coordinates.

A common problem with elements in quadtrees is to detect pairs of elements which are closer than a definite threshold.

The proposed implementation efficiently addresses this problem.

from smartquadtree import Quadtree

Creation & insertion of elements

As you instantiate your quadtree, you must specify the center of your space then the height and width.

q = Quadtree(0, 0, 10, 10)

The output of a quadtree on the console is pretty explicit. (You can refer to next section for the meaning of “No mask set”)

q
<smartquadtree.Quadtree at 0x7fc28b93d300>
Total number of elements: 0
No mask set

You can easily insert elements from which you can naturally infer x-y coordinates (e.g. tuples or lists)

q.insert((1, 2))
q.insert((-3, 4))
q
<smartquadtree.Quadtree at 0x7fc28b93d300>
Total number of elements: 2
No mask set
First elements:
    (1, 2),
    (-3, 4),

No error is raised if the element you are trying to insert is outside the scope of the quadtree. But it won’t be stored anyway!

q.insert((-20, 0))
q
<smartquadtree.Quadtree at 0x7fc28b93d300>
Total number of elements: 2
No mask set
First elements:
    (1, 2),
    (-3, 4),

If you want to insert other Python objects, be sure to provide get_x() and get_y() methods to your class!

class Point(object):

    def __init__(self, x, y, color):
        self.x = x
        self.y = y
        self.color = color

    def __repr__(self):
        return "(%.2f, %.2f) %s" % (self.x, self.y, self.color)

    def get_x(self):
        return self.x

    def get_y(self):
        return self.y

You cannot insert elements of a different type from the first element inserted.

q.insert(Point(2, -7, "red"))

But feel free to create a new one and play with it:

point_quadtree = Quadtree(5, 5, 5, 5)
point_quadtree.insert(Point(2, 7, "red"))
point_quadtree
<smartquadtree.Quadtree at 0x7fc289797a00>
Total number of elements: 1
No mask set
First elements:
    (2.00, 7.00) red,

Simple iteration

from random import random
q = Quadtree(0, 0, 10, 10, 16)
for a in range(50):
    q.insert([random()*20-10, random()*20-10])

The print function does not display all elements and uses the __repr__() method of each element.

print(q)
<smartquadtree.Quadtree at 0x7fc28b94c0b0>
Total number of elements: 50
No mask set
First elements:
    [5.576253335483335, 2.9926458306078647],
    [2.956289387002718, 3.792134207741281],
    [3.9903269308895766, 5.492168007874362],
    ...

We can write our own iterator and print each element we encounter the way we like.

from __future__ import print_function
for p in q.elements():
    print ("[%.2f, %.2f]" % (p[0], p[1]), end=" ")
[5.58, 2.99] [2.96, 3.79] [3.99, 5.49] [3.43, 1.10] [7.73, 4.09] [9.67, 6.81] [2.95, 4.12] [0.14, 5.80] [2.77, 7.87] [0.05, 1.61] [-8.74, 7.64] [-1.22, 1.90] [-0.95, 3.91] [-3.17, 1.09] [-7.41, 4.26] [-8.25, 6.47] [-6.91, 3.80] [-3.73, 3.10] [-5.74, 8.80] [8.50, -9.31] [2.49, -9.10] [6.64, -8.61] [0.40, -2.93] [7.99, -4.08] [4.71, -6.75] [0.12, -1.84] [0.72, -2.94] [9.62, -9.90] [0.15, -9.75] [8.67, -7.19] [2.44, -3.60] [5.08, -8.63] [8.86, -1.87] [1.07, -9.43] [-7.96, -5.53] [-2.53, -5.75] [-1.31, -5.81] [-7.24, -3.55] [-8.76, -9.37] [-8.48, -1.33] [-1.28, -0.69] [-6.60, -4.65] [-4.28, -0.89] [-7.56, -7.31] [-4.72, -7.02] [-1.98, -2.33] [-3.43, -5.74] [-3.71, -1.13] [-1.01, -7.29] [-2.04, -5.90]

It is easy to filter the iteration process and apply the function only on elements inside a given polygon. Use the set_mask() method and pass a list of x-y coordinates. The polygon will be automatically closed.

q.set_mask([(-3, -7), (-3, 7), (3, 7), (3, -7)])
print(q)
<smartquadtree.Quadtree at 0x7fc28b94c0b0>
Total number of elements: 50
Total number of elements inside mask: 15
First elements inside the mask:
    [2.956289387002718, 3.792134207741281],
    [2.945472950394006, 4.1166899654293765],
    [0.14379102547949074, 5.797490949080599],
    ...

The same approach can be used to count the number of elements inside the quadtree.

print (sum (1 for x in q.elements()))
print (sum (1 for x in q.elements(ignore_mask=True)))
15
50

As a mask is set on the quadtree, we only counted the elements inside the mask. You can use the size() method to count elements and ignore the mask by default. Disabling the mask with set_mask(None) is also a possibility.

print ("%d elements (size method)" % q.size())
print ("%d elements (don't ignore the mask)" % q.size(False))

q.set_mask(None)
print ("%d elements (disable the mask)" % q.size())
50 elements (size method)
15 elements (don't ignore the mask)
50 elements (disable the mask)

Playing with plots

%matplotlib inline
from matplotlib import pyplot as plt

q = Quadtree(5, 5, 5, 5, 10)

for a in range(200):
    q.insert([random()*10, random()*10])

fig = plt.figure()
plt.axis([0, 10, 0, 10])

q.set_mask(None)
for p in q.elements():
    plt.plot([p[0]], [p[1]], 'o', color='lightgrey')

q.set_mask([(3, 3), (3, 7), (7, 7), (7, 3)])

for p in q.elements():
    plt.plot([p[0]], [p[1]], 'ro')

_ = plt.plot([3, 3, 7, 7, 3], [3, 7, 7, 3, 3], 'r')
https://raw.githubusercontent.com/xoolive/quadtree/master/tutorial_files/tutorial_31_0.png

Iteration on pairs of neighbouring elements

Iterating on pairs of neighbouring elements is possible through the neighbour_elements() function. It works as a generator and yields pair of elements, the first one being inside the mask (if specified), the second one being in the same cell or in any neighbouring cell, also in the mask.

Note that if (a, b) is yielded by neighbour_elements(), (b, a) will be omitted from future yields.

# Let's start with a new quadtree because we need
q = Quadtree(5, 5, 5, 5, 10)
q.set_limitation(2)  # do not create a new subdivision if one side of the cell is below 2

for a in range(200):
    q.insert([random()*10, random()*10])

fig = plt.figure()
plt.axis([0, 10, 0, 10])

for p in q.elements():
    plt.plot([p[0]], [p[1]], 'o', color='lightgrey')

q.set_mask([(1, 1), (4, 1), (5, 4), (2, 5), (1, 1)])

for p in q.elements():
    plt.plot([p[0]], [p[1]], 'o', color='green')

for p1, p2 in q.neighbour_elements():
    if ((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2 < 1):
        plt.plot([p1[0]], [p1[1]], 'o', color='red')
        plt.plot([p2[0]], [p2[1]], 'o', color='red')
        plt.plot([p1[0], p2[0]], [p1[1], p2[1]], 'red')

_ = plt.plot([1, 4, 5, 2, 1], [1, 1, 4, 5, 1], 'r')
https://raw.githubusercontent.com/xoolive/quadtree/master/tutorial_files/tutorial_34_0.png

Metadata

Release files for smartquadtree 1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

File added late

1 file was uploaded more than 14 days after the first file in this release.

While project maintainers occasionally add legitimate files to an existing release, late additions can also indicate a security compromise.

We recommend inspecting the release files before installing.

Built distributions (wheels)

Table of built distributions (wheels) for smartquadtree 1.0
File
smartquadtree-1.0-py3.5-win32.egg Legacy Egg format - - Details
smartquadtree-1.0-py3.4-win32.egg Legacy Egg format - - Details
smartquadtree-1.0-py3.4-macosx-10.10-x86_64.egg Legacy Egg format - - Details
smartquadtree-1.0-py2.7-win32.egg Legacy Egg format - - Details
smartquadtree-1.0-py2.7-macosx-10.10-intel.egg Legacy Egg format - - Details
smartquadtree-1.0-cp34-none-win32.whl CPython 3.4 none Windows x86-32 Details
smartquadtree-1.0-cp34-cp34m-macosx_10_10_x86_64.whl CPython 3.4 CPython 3.4 pymalloc macOS 10.10+ x86-64 Details
smartquadtree-1.0-cp27-none-win32.whl CPython 2.7 none Windows x86-32 Details
smartquadtree-1.0-cp27-none-macosx_10_10_intel.whl CPython 2.7 none macOS 10.10+ Intel (x86-64, i386) Details

Total release size: 458.2 kB

Release files / smartquadtree-1.0-py3.5-win32.egg

File added late

This file was uploaded more than 14 days after the first file in this release.

While project maintainers occasionally add legitimate files to an existing release, late additions can also indicate a security compromise.

We recommend inspecting the release file before installing.

Download URL smartquadtree-1.0-py3.5-win32.egg
Size 39.5 kB
Tags Egg
SHA-256 checksum
How to use checksums
42ab10e8a0079f4be9babbffdf2becdb41cfea62d57e1b9982f88e5e85092733
BLAKE2b-256 checksum
How to use checksums
df9f4c118e8b81445b7b2faa3cfbcce1f042f57364b36981344cf06a2fc88dd2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / smartquadtree-1.0-py3.4-win32.egg

Download URL smartquadtree-1.0-py3.4-win32.egg
Size 54.2 kB
Tags Egg
SHA-256 checksum
How to use checksums
637a3ad1404c91ef06f8ed517f98f2a7b055b8e54b88287eb37e819051cbd235
BLAKE2b-256 checksum
How to use checksums
99bb3d991eee58e5a684bd342e32a560593a7d6ee44e2aacb3eb52c6db3ca7b1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / smartquadtree-1.0-py3.4-macosx-10.10-x86_64.egg

Download URL smartquadtree-1.0-py3.4-macosx-10.10-x86_64.egg
Size 49.0 kB
Tags Egg
SHA-256 checksum
How to use checksums
c92515ec7385e0b1d4110a2b11c3279a6638ff754ed88d6306a9cc11cef6adf3
BLAKE2b-256 checksum
How to use checksums
9fc2b847e1110364c777bdb7bb167fffbde719beb2334cb6904bd59819bd053f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / smartquadtree-1.0-py2.7-win32.egg

Download URL smartquadtree-1.0-py2.7-win32.egg
Size 54.1 kB
Tags Egg
SHA-256 checksum
How to use checksums
a0db58312f606909e2f673e204277b343b087d4e7672401ff8acb1ab39fd4eaf
BLAKE2b-256 checksum
How to use checksums
f774e752e457517cb1d1dbb5991d7ec0b1371e597c9117fc1447b42671068190
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / smartquadtree-1.0-py2.7-macosx-10.10-intel.egg

Download URL smartquadtree-1.0-py2.7-macosx-10.10-intel.egg
Size 46.7 kB
Tags Egg
SHA-256 checksum
How to use checksums
74590db19105e3ce67fd6dbb16e4fb6c048ac451b303324111c0c49664fd43cd
BLAKE2b-256 checksum
How to use checksums
cddc9ea4f87d756fb9a56ce57ba68ddc0a2968b4606a919cfb5c8c6e5a86bfb6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / smartquadtree-1.0-cp34-none-win32.whl

Download URL smartquadtree-1.0-cp34-none-win32.whl
Size 56.8 kB
Tags CPython 3.4 Windows x86-32
SHA-256 checksum
How to use checksums
f996f12e6c977dd54f29168d529ed7b4822c74a0545f49f084f33a8bdae4d2dd
BLAKE2b-256 checksum
How to use checksums
95794a5edf5170ffe7f8fb13ab2e27bc7173a8abff742b83b9c391cb4428505a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / smartquadtree-1.0-cp34-cp34m-macosx_10_10_x86_64.whl

Download URL smartquadtree-1.0-cp34-cp34m-macosx_10_10_x86_64.whl
Size 51.6 kB
Tags CPython 3.4 CPython 3.4 pymalloc macOS 10.10+ x86-64
SHA-256 checksum
How to use checksums
730cf7c3db8f7812b707462415428da63e022a21d9a2e4d9aa372f8b9b18c28a
BLAKE2b-256 checksum
How to use checksums
b66720d7c96fda52783a88fc7708583c2aa6991598cd083ca55a4957b8601952
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / smartquadtree-1.0-cp27-none-win32.whl

Download URL smartquadtree-1.0-cp27-none-win32.whl
Size 56.8 kB
Tags CPython 2.7 Windows x86-32
SHA-256 checksum
How to use checksums
0ba10cdb6665569c91b49b5cb71a0fc5b848bbd1da7414ad280a0cd16dbc5c5b
BLAKE2b-256 checksum
How to use checksums
c6c45fd12b751ddb024c32d79aa33b8932c84c6ba58d9e75f7f2eaca2003c3d6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / smartquadtree-1.0-cp27-none-macosx_10_10_intel.whl

Download URL smartquadtree-1.0-cp27-none-macosx_10_10_intel.whl
Size 49.4 kB
Tags CPython 2.7 macOS 10.10+ Intel (x86-64, i386)
SHA-256 checksum
How to use checksums
bd24dc01ca7bb523ba6cd49e16eaf2773cb95bf47f6fed1e793508ed68b87273
BLAKE2b-256 checksum
How to use checksums
54492a996f7660fdad7fca569938de8a7cda8e69c6a5278a4c6ce95438c0f33f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release history Release notifications | RSS feed

This release

1.0 This release

9 release files

0.2

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page