我正在设计一个Web应用程序来计划Minecraft的构建。本质上,它是一个2D像素编辑器。为了避免与实际显示的像素混淆,我将这些点称为“平铺”。 (每个图块都具有块类型ID,而不是颜色,这种区别在很大程度上不重要。)
要求:
- “画布”的大小不受限制。对用户来说,在图像边界之外为图块上色应该不会太昂贵。
- 默认情况下,标题为空。用户无法填充无限的外部外观(或者如果可以的话,应用程序将以某种未指定的方式“欺骗”)。
- 程序应处理1000 x 1000瓦片的可见区域。
- 程序必须有效地表示非常大的区域(例如1000 x 1000平方英寸)上的操作。
- 小的编辑必须瞬时快速(即<100 ms)。
程序应支持以下操作:
- 为单个像素着色。
- 查找单色的连接组件(可能很大)。
- 合并多个画布。
- 翻译画布。
- 将画布旋转四分之一圈,或将其水平或垂直翻转。
- 撤消和重做编辑。
为了满足这些要求,我正在考虑使用的核心数据结构是:
- 四叉树。
- x,y偏移量,代表四叉树的中心。
- 一个大小值,代表四叉树的逻辑深度。
我认为,这应该允许在实际使用条件下有效执行所需的编辑操作。 (没有免费的午餐;我接受大型棋盘格模式会很慢。)据我了解:
- 移动画布很简单(只需更新偏移量)。
- 旋转或翻转画布可以在O(n)中进行递归处理(其中n是树中的节点数)。
- 查找连接的组件将是O(n)。
- 编辑单个点将为O(log(size))。
由于四叉树必须对齐,因此合并有点棘手,但是我们保留了单独的偏移量以提高翻译效率。据我了解,我们仅需在O(n + m)时间内合并之前进行“真实”转换,其中m是新四叉树中的节点数。大概我们会在合并之前在较小的四叉树上执行此操作(即,最小逻辑深度以避免检查实际大小)。
编辑历史记录是一个悬而未决的问题。显然,我们不能一直复制画布。有些操作(例如平移或旋转)本质上是可逆的,而其他一些操作(直接编辑或合并)则可以通过“复制”画布但重新使用未更改的节点来完成。听起来这在大多数情况下应该有日志空间开销。
我有以下问题:
- 这种方法是否存在我忽略的主要缺陷?
- 是否存在一个良好的现有四叉树实现,我应该以此为起点?
- 是否有任何文档保留有关四叉树的编辑历史记录?
- 鉴于我不是第一个(基本上)创建位图编辑器的人,我还应该在哪里寻找指导?