Rust四叉树实现

jljoyd4f  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(108)

我试图在rust中实现一个四叉树,它以Array2作为输入。任何包含所有相同值的节点都应该成为叶子。问题是,它只是不断划分无论如何,并在运行时给出一个错误,我在如何解决它的损失。有什么想法吗?我不明白为什么它只是不断递归,即使我正在使节点是空的ie。一个也没有
这是我的想法:

use noise::{Perlin, NoiseFn};
use ndarray::prelude::*;
use cgmath::{vec2, Vector2};

struct Node {
    grid: ndarray::Array2<u8>,
    nodes: [Option<Box<Node>>; 4],
    pos: Vector2<u8>,
}

impl Node {
    pub fn new(grid: ndarray::Array2<u8>, pos: Vector2<u8>) -> Self {
        // println!("{}", grid.dim().0);

        if grid.dim().0 > 1 {
            let half_size = (grid.dim().0 / 2) as u8;

            let bl: Node = Node::new(
                grid.slice(s![
                    pos.x as usize..(pos.x + half_size) as usize,
                    pos.y as usize..(pos.y + half_size) as usize
                ])
                .to_owned(),
                vec2(pos.x, pos.y),
            );
            let tl: Node = Node::new(
                grid.slice(s![
                    pos.x as usize..(pos.x + half_size) as usize,
                    (pos.y + half_size) as usize..(pos.y + half_size * 2) as usize
                ])
                .to_owned(),
                vec2(pos.x, pos.y + half_size),
            );
            let tr: Node = Node::new(
                grid.slice(s![
                    (pos.x + half_size) as usize..(pos.x + half_size * 2) as usize,
                    (pos.y + half_size) as usize..(pos.y + half_size * 2) as usize
                ])
                .to_owned(),
                vec2(pos.x + half_size, pos.y + half_size),
            );
            let br: Node = Node::new(
                grid.slice(s![
                    (pos.x + half_size) as usize..(pos.x + half_size * 2) as usize,
                    pos.y as usize..(pos.y + half_size) as usize
                ])
                .to_owned(),
                vec2(pos.x + half_size, pos.y),
            );
            let nodes = [Some(Box::new(bl)), Some(Box::new(tl)), Some(Box::new(tr)), Some(Box::new(br))];

            Self {
                grid: grid,
                nodes: nodes,
                pos: pos,
            }
        } else {
            print!("unsplitable ");
            Self {
                grid: Array::from_elem((1, 1), grid[[0, 0]]),
                nodes: [None, None, None, None],
                pos: pos,
            }
        }
    }
}

fn main() {
    let perlin = Perlin::new(1);
    let mut grid: Array2<u8> = Array::zeros((8, 8));

    for x in 0..8 {
        for y in 0..8 {
            grid[[x, y]] = ((perlin.get([x as f64 / 12.0, y as f64 / 12.0]) + 1.0) * 1.5) as u8;
        }
    }

    let quadtree: Node = Node::new(grid, vec2(0, 0));
}
mgdq6dx1

mgdq6dx11#

代码生成越界访问死机。我想你误解了ndarray的切片返回的是什么。它返回一个行为类似于新数组的东西。如果它的长度为2,则可以将其索引为0或1,而不是原始索引点。这与Rust中切片的一般工作方式是一致的。
因此,当你计算子数组的切片索引时,你不需要添加当前四叉树位置。您已经有了一个从索引0开始的视图(我认为实际上是一个副本,因为.to_owned())。

相关问题