Find the smallest rectangle of the area covering the query point

I am working on a personal project related to computational geometry. The question in the name is an abstraction of one of the small subtasks that I am trying, but struggling to solve effectively. Hopefully it's generic enough to possibly use more than just me!


Problem

Suppose that we have a set S of rectangles in the plane, all of which have edges parallel to the coordinate axes (without turns). For my problem, we will assume that rectangle intersections are very common . But they are also very nice: if two rectangles intersect, we can assume that one of them always completely contains the other. Therefore, there are no "partial" overlappings.

I want to save these rectangles so that:

  • We can effectively add new rectangles.
  • Given the query point (x, y), we can efficiently report the rectangle of the smallest region containing the point.

The illustration provides motivation for the latter. We always want to find the deepest nested rectangle that contains the query point, so always one of the smallest areas.

.


My thoughts

Therefore, I know that both R-trees and Square trees are often used for spatial indexing problems, and in any case both of them can work well. The problem with R-Trees is that they can degrade to worse linear performance.

. node r , r. , r. .

, ? O (n) 1 , -, , .


, ? . ( , )

, . , , .

!

+4
4

. , , , , , , , , .

O (n), , , : , (), (), - . ( ), , .

three-dimensional spatial tree

, / / , , .

, , .


:

rectangle numbering

:

three-dimensional spatial tree

+4

xMin xMax yMin yMax . (2n - 1) ^ 2 . , () . (, x y, node... ). , O (log n ^ 2), . O (n ^ 2) .

, - O (log n) , :

private int[] x, y;
private Rectangle[][] r;

public RectangleFinder(Rectangle[] rectangles) {
    Set<Integer> xPartition = new HashSet<>(), yPartition = new HashSet<>();
    for (int i = 0; i < rectangles.length; i++) {
        xPartition.add(rectangles[i].getX());
        yPartition.add(rectangles[i].getY());
        xPartition.add(rectangles[i].getX() + rectangles[i].getWidth());
        yPartition.add(rectangles[i].getY() + rectangles[i].getHeight());
    }
    x = new int[xPartition.size()];
    y = new int[yPartition.size()];
    r = new Rectangle[x.length][y.length];
    int c = 0;
    for (Iterator<Integer> itr = xPartition.iterator(); itr.hasNext();)
        x[c++] = itr.next();
    c = 0;
    for (Iterator<Integer> itr = yPartition.iterator(); itr.hasNext();)
        y[c++] = itr.next();
    Arrays.sort(x);
    Arrays.sort(y);
    for (int i = 0; i < x.length; i++)
        for (int j = 0; j < y.length; j++)
            r[i][j] = rectangleOnTop(x[i], y[j]);
}

public Rectangle find(int x, int y) {
    return r[getIndex(x, this.x, 0, this.x.length)][getIndex(y, this.y, 0, this.y.length)];
}

private int getIndex(int n, int[] arr, int start, int len) {
    if (len <= 1)
        return start;
    int mid = start + len / 2;
    if (n < arr[mid])
        return getIndex(n, arr, start, len / 2);
    else
        return getIndex(n, arr, mid, len - len / 2);
}
+1

O (n).

, - , .

n , ... .

R- - . .

, , . R- . R, , .

+1

PH-tree? PH-Tree , , , , , , .

:

  • PH-Tree - , , . , 64- 64.
  • z-
  • R * Tree STR-Tree, , . .
  • / , STR-, , R-, .
  • , . , . , , ( "/" ).

: PH-Tree , .. . , " " " " , . , 2D- (2,2) - (4,5) 4- (2,2,4,5). , - , , . .

. "". "n" , , .

. , PH-Tree ( ) , (, . 16). , . , , .

: - , , () node, . z-, . , , PH-Tree k- . kNN node , , . , , , , , .

The full (Java) PH-Tree code is available at the link above. For comparison, you can check out my other index implementations here (R * Tree, quadtrees, STR-Tree).

+1
source

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


All Articles