Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

search & collides support custom intersects & contains #135

Open
sakitam-fdd opened this issue Nov 15, 2023 · 0 comments
Open

search & collides support custom intersects & contains #135

sakitam-fdd opened this issue Nov 15, 2023 · 0 comments

Comments

@sakitam-fdd
Copy link

sakitam-fdd commented Nov 15, 2023

Motivation

I used this in the implementation of a patch mapbox tilt view tile, where we invert the missing tiles under this tier based on the row and column numbers of the TileID, who probably looks like this:

function intersects(a, b) {
    return b.minX < a.maxX &&
        b.minY < a.maxY &&
        b.maxX > a.minX &&
        b.maxY > a.minY;
}

for (let x = 0; x < xd; x++) {
    for (let y = 0; y < yd; y++) {
        const tile = neighbor(baseTileID, x, y);
        if (!tiles.find(t => t.key === tile.key)) {
            const result = tree.collides({
                minX: tile.bbox[0],
                minY: tile.bbox[1],
                maxX: tile.bbox[2],
                maxY: tile.bbox[3],
            }, { intersects });

            if (!result) {
                addTiles.push(tile);
            }
            console.log(tile, result);
        }
    }
}

But the computed tiles always return true when tested for collision with existing tiles, and in fact mathematically the co-edged tiles do intersect, but implementation-wise we might expect to reserve a certain amount of buffer.
An implementation that doesn't interfere with the existing logic is to support user-defined intersection and containment test functions, which is easy to implement, but requires some discussion.

Design Alternatives

  1. search
search(bbox, options) {
    let node = this.data;
    const result = [];
    const intersectsFn = options && options.intersects ? options.intersects : intersects;
    const containsFn = options && options.contains ? options.contains : contains;

    if (!intersectsFn(bbox, node)) return result;

    const toBBox = this.toBBox;
    const nodesToSearch = [];

    while (node) {
        for (let i = 0; i < node.children.length; i++) {
            const child = node.children[i];
            const childBBox = node.leaf ? toBBox(child) : child;

            if (intersectsFn(bbox, childBBox)) {
                if (node.leaf) result.push(child);
                else if (containsFn(bbox, childBBox)) this._all(child, result);
                else nodesToSearch.push(child);
            }
        }
        node = nodesToSearch.pop();
    }

    return result;
}
  1. collides
collides(bbox, options) {
    let node = this.data;
    const intersectsFn = options && options.intersects ? options.intersects : intersects;
    const containsFn = options && options.contains ? options.contains : contains;

    if (!intersectsFn(bbox, node)) return false;

    const nodesToSearch = [];
    while (node) {
        for (let i = 0; i < node.children.length; i++) {
            const child = node.children[i];
            const childBBox = node.leaf ? this.toBBox(child) : child;

            if (intersectsFn(bbox, childBBox)) {
                if (node.leaf || containsFn(bbox, childBBox)) return true;
                nodesToSearch.push(child);
            }
        }
        node = nodesToSearch.pop();
    }

    return false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants