Flutter空间划分与数据管理插件expandable_quadtree的使用

发布于 1周前 作者 nodeper 来自 Flutter

Flutter空间划分与数据管理插件expandable_quadtree的使用

概述

Expandable Quadtree 是一个用于 Flutter 和 Dart 的灵活且高效的四叉树实现。它非常适合用于空间索引、碰撞检测和组织大量二维数据。该插件支持多种四叉树配置,包括可扩展的四叉树、水平可扩展的四叉树和垂直可扩展的四叉树。

特性

  • 多种四叉树配置

    • 单根四叉树
    • 多根四叉树
    • 可扩展四叉树
    • 水平/垂直可扩展四叉树
  • 高效的空间查询:检索给定矩形区域内的项目。

  • 自定义深度和项目限制:控制你的四叉树可以达到的最大深度和容量。

  • 动态分割:当节点容量超出时自动分割节点。

  • 递归遍历:遍历并检索四叉树中存储的所有象限或项目。

  • 项目管理:轻松插入、删除和检索项目。

  • 处理大数据集:四叉树通过将空间划分为更小的区域来高效地管理大量项目。

安装

pubspec.yaml 文件中添加以下依赖:

dependencies:
  expandable_quadtree: ^0.1.1

然后运行:

flutter pub get

或者直接使用 Flutter CLI 安装:

flutter pub add expandable_quadtree

入门指南

基本用法

以下是一个简单的示例,展示如何使用四叉树管理二维对象在一个矩形空间内。

import 'dart:ui'; // For Rect

import 'package:expandable_quadtree/expandable_quadtree.dart';

void main() {
  final quadtree = Quadtree<Rect>(
    Rect.fromLTWH(0, 0, 100, 100),
    maxItems: 10,
    maxDepth: 4,
    getBounds: (item) => item,
  );

  // 插入项目
  quadtree.insert(Rect.fromLTWH(10, 10, 4.99, 4.99));
  quadtree.insert(Rect.fromLTWH(10, 10, 5, 5));
  quadtree.insert(Rect.fromLTWH(20, 20, 1, 1));
  quadtree.insert(Rect.fromLTWH(35, 35, 1, 1));
  quadtree.insert(Rect.fromLTWH(35.1, 35.1, 1, 1));
  quadtree.insert(Rect.fromLTWH(40, 40, 5, 5));

  // 在特定区域内检索项目
  final items = quadtree.retrieve(Rect.fromLTWH(15, 15, 20, 20));
  print(items);
  // 输出:
  // [
  //   Rect.fromLTWH(10.0, 10.0, 5.0, 5.0),
  //   Rect.fromLTWH(20.0, 20.0, 1.0, 1.0),
  //   Rect.fromLTWH(35.0, 35.0, 1.0, 1.0)
  // ]

  // 递归删除所有四叉树中的项目
  // 推荐用于小四叉树
  quadtree.remove(Rect.fromLTWH(10, 10, 5, 5));

  // 仅递归遍历相交的节点删除项目
  // 推荐用于大四叉树
  quadtree.localizedRemove(Rect.fromLTWH(20, 20, 1, 1));

  // 获取四叉树中的所有象限
  quadtree.getAllQuadrants();

  // 如果只想获取叶子象限,使用:
  quadtree.getAllQuadrants(includeNonLeafNodes: false);

  // 获取四叉树中的所有项目
  quadtree.getAllItems();

  // 四叉树可能包含重复项,如果想让四叉树返回重复项,使用:
  quadtree.getAllItems(removeDuplicates: false);

  // 清除整个四叉树
  quadtree.clear();
}
使用可扩展四叉树

如果你需要四叉树能够动态扩展,可以使用 ExpandableQuadtree

final quadtree = Quadtree<Rect>(
  Rect.fromLTWH(0, 0, 100, 100),
  getBounds: (item) => item,
);

// 无法插入超出边界的项目
quadtree.insert(Rect.fromLTWH(150, 150, 1, 1)); // 返回 false

// 若要插入超出边界的项目,可以使用可扩展四叉树
final expandableQuadtree = ExpandableQuadtree<Rect>(
  Rect.fromLTWH(0, 0, 100, 100),
  getBounds: (item) => item,
);

expandableQuadtree.insert(Rect.fromLTWH(150, 150, 1, 1)); // 返回 true
使用水平可扩展四叉树

如果你只想水平扩展四叉树,可以使用 HorizontallyExpandableQuadtree

final quadtree = Quadtree<Rect>(
  Rect.fromLTWH(0, 0, 100, 100),
  getBounds: (item) => item,
);

// 无法插入超出水平边界范围的项目
quadtree.insert(Rect.fromLTWH(-50, 0, 1, 1)); // 返回 false

// 若要插入超出水平边界范围的项目,可以使用水平可扩展四叉树
final horizontallyExpandableQuadtree = HorizontallyExpandableQuadtree<Rect>(
  Rect.fromLTWH(0, 0, 100, 100),
  getBounds: (item) => item,
);

horizontallyExpandableQuadtree.insert(Rect.fromLTWH(-50, 0, 1, 1)); // 返回 true

// 它也会防止插入超出垂直边界范围的项目
horizontallyExpandableQuadtree.insert(Rect.fromLTWH(0, -50, 1, 1)); // 返回 false
使用垂直可扩展四叉树

如果你只想垂直扩展四叉树,可以使用 VerticallyExpandableQuadtree

final quadtree = Quadtree<Rect>(
  Rect.fromLTWH(0, 0, 100, 100),
  getBounds: (item) => item,
);

// 无法插入超出垂直边界范围的项目
quadtree.insert(Rect.fromLTWH(0, -50, 1, 1)); // 返回 false

// 若要插入超出垂直边界范围的项目,可以使用垂直可扩展四叉树
final verticallyExpandableQuadtree = VerticallyExpandableQuadtree<Rect>(
  Rect.fromLTWH(0, 0, 100, 100),
  getBounds: (item) => item,
);

verticallyExpandableQuadtree.insert(Rect.fromLTWH(0, -50, 1, 1)); // 返回 true

// 它也会防止插入超出水平边界范围的项目
verticallyExpandableQuadtree.insert(Rect.fromLTWH(-50, 0, 1, 1)); // 返回 false

更多关于Flutter空间划分与数据管理插件expandable_quadtree的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter空间划分与数据管理插件expandable_quadtree的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter应用中使用expandable_quadtree插件进行空间划分和数据管理的示例代码。expandable_quadtree插件主要用于高效的空间搜索和数据管理,特别适用于需要处理大量地理位置数据的应用场景。

首先,确保你已经在pubspec.yaml文件中添加了expandable_quadtree依赖:

dependencies:
  flutter:
    sdk: flutter
  expandable_quadtree: ^最新版本号  # 请替换为实际最新版本号

然后,运行flutter pub get来获取依赖。

下面是一个简单的示例,展示了如何使用expandable_quadtree进行空间划分和数据管理:

import 'package:flutter/material.dart';
import 'package:expandable_quadtree/expandable_quadtree.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late QuadTree<Point> quadTree;

  @override
  void initState() {
    super.initState();

    // 初始化QuadTree,指定边界和最大项数
    final Rectangle boundary = Rectangle(
      Point(0, 0), // 左下角坐标
      Point(100, 100), // 右上角坐标
    );
    quadTree = QuadTree<Point>(boundary, capacity: 4);

    // 添加一些点到QuadTree中
    quadTree.insert(Point(10, 10));
    quadTree.insert(Point(50, 50));
    quadTree.insert(Point(90, 10));
    quadTree.insert(Point(20, 80));
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('QuadTree Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('Search within a rectangle:'),
              ElevatedButton(
                onPressed: () {
                  // 定义一个搜索区域
                  final Rectangle searchArea = Rectangle(
                    Point(20, 20),
                    Point(70, 70),
                  );

                  // 在QuadTree中搜索该区域内的点
                  final List<Point> pointsInArea = quadTree.search(searchArea);

                  // 打印搜索结果
                  print('Points in search area: $pointsInArea');
                },
                child: Text('Search'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

// 定义一个简单的Point类来表示二维空间中的点
class Point implements Comparable<Point> {
  final double x, y;

  Point(this.x, this.y);

  @override
  int compareTo(Point other) {
    if (x != other.x) {
      return x.compareTo(other.x);
    } else {
      return y.compareTo(other.y);
    }
  }

  @override
  bool operator ==(Object other) =>
      other is Point && other.x == x && other.y == y;

  @override
  int get hashCode => x.hashCode ^ y.hashCode;

  @override
  String toString() => 'Point($x, $y)';
}

在这个示例中:

  1. 我们定义了一个简单的Point类来表示二维空间中的点。
  2. initState方法中,我们初始化了一个QuadTree实例,并添加了一些点到树中。
  3. 在UI中,我们提供了一个按钮,点击按钮时会在指定的搜索区域内搜索点,并打印搜索结果。

注意:expandable_quadtree插件的具体API可能有所不同,请查阅最新的官方文档以获取最准确的信息。

回到顶部