【问题标题】:How to determine a useful center in a 2D range of points如何在二维点范围内确定有用的中心
【发布时间】:2023-03-27 22:20:02
【问题描述】:

如何在一系列点中找到中心以创建四叉树节点并有效地做到这一点?

class point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
}
//range = [] of points, (they get sorted into quarters in the tree node)

一个范围代表一个点数组,代表一个棋盘。

以下是相关代码:

class quadtreeNode {
    constructor(range, parent, depth) {
        const centerPoint = findCenter(range);
        this.center = centerPoint; 
        this.parent = parent;
        if (range.length <= 1) {
            this.leaf = true;
            this.value = this.center;
        } else {
            this.TL = new quadtreeNode(
                range.filter(x => x.x < this.center.x && x.y < this.center.y), 
                this, 
                depth + 1
            );
            this.TR = new quadtreeNode(
                range.filter(x => x.x > this.center.x && x.y < this.center.y),
                this, 
                depth + 1
            );
            this.BL = new quadtreeNode(
                range.filter(x => x.x < this.center.x && x.y > this.center.y),
                this,
                depth+1
            );
            this.BR = new quadtreeNode(
                range.filter(x => x.x > this.center.x && x.y > this.center.y),
                this,
                depth + 1
            );
        }
    }
}

还有:

findCenter(array){
    let centerPoint = null;
    if (array.length <= 1) {
       centerPoint = array[0];
    } else {
        let minX = array.sort((x, y) => x.x < y.x)[0];
        let minY = array.sort((x, y) => x.y < y.y)[0];
        let maxX = array.sort((x, y) => x.x > y.x)[0];
        let maxY = array.sort((x, y) => x.y > y.y)[0];
        const targetX = maxX-minX;
        const targetY = maxY-minY;
        const target = array.find(x => x.x == targetX && x.y == targetY);
        if (!target) {
            return array[(Math.floor(array.length / 2))];
        } else {
            centerPoint = target;
        }
    }
    return centerPoint;  
}

我对如何找到中心有点困惑,我是否需要每次都找到确切的中心,或者是否有四叉树的估计,或者范围是否应该是一个特定长度可被...整除4?

【问题讨论】:

    标签: javascript tree quadtree


    【解决方案1】:

    这取决于您要优化什么。大多数情况下,您会希望最小化四叉树的深度。因此,理想情况下,您希望选择一个节点,使得其后的四个子范围每个都有大约四分之一的范围内的点,即均匀分布。如果你能在每个节点上实现这一点,那么当 n 是总数时,树的深度将接近 log4n节点数。

    但是,并不总是可以选择这样的中心节点。想象一下这个范围内的点分布:

                                             *
                                      *
    
                                     *
    
                                    *
    
                                 *
    
                       *
             *
    *
    

    无论您选择哪个点,您总是会产生四个子范围,其中两个是空的,因此在 4 个子范围内均匀分布的“梦想场景”是不可行的。

    您需要选择中心点,以使获得最多点的象限的大小最小化。这可能计算成本很高,但一个很好的启发式方法如下:

    • 收集每个点的 x 坐标 (sx) 排序顺序和 y 坐标 (sy) 排序顺序。这可以通过执行两个排序操作轻松获得
    • 考虑到最佳中心将具有 (sx, sy) = (n/2, n/2),您将选择 (sx, sy) 到 (n/2, n/2) 的距离的点) 被最小化。

    所以建议的代码是:

    findCenter(array) {
        const mid = array.length >> 1;
        if (!mid) {
            return array[0];
        }
        return array.sort((p, q) => p.x - q.x) // NB: sort callback should return signed number
                    .map((p, sx) => [p, sx]))
                    .sort(([p], [q]) => p.y - q.y)
                    .map(([p, sx], sy) => [(sx - mid) ** 2 + (sy - mid) ** 2, p])
                    .sort(([a], [b]) => a - b)[0][1];
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      • 2021-02-11
      相关资源
      最近更新 更多