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')
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')
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)
| File | Reset | |||
|---|---|---|---|---|
| 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 |