画布操作与元素操作

War*_*ith 5 graphics performance android scenegraph android-canvas

我正在开发一个小型库作为某些应用程序的基础.当我即将创建一个场景图(2D)时,我想知道在性能,可维护性,易用性等观点下,以下哪种方法看起来更有前途.

  1. 我可以给每个可绘制元素一个矩阵,在那里我执行平移,旋转等等.
  2. 我可以在画布上做所有事情而不是元素.

第一个解决方案有一个缺点:对于像圆形这样的原始元素,我无法在绘制调用中传递矩阵,我必须从矩阵中访问转换后的值,如下所示:

private float get(int index) {
    final float[] values = new float[9];
    getValues(values);
    return values[index];
}

public float getX() {
    return get(Matrix.MTRANS_X);
}

public float getY() {
    return get(Matrix.MTRANS_Y);
}
Run Code Online (Sandbox Code Playgroud)

因此,在每次绘制调用时,我为每个getter调用创建一个float数组(一个用于getX(),一个用于getY()).假设屏幕上有足够的元素,这可能会导致内存和性能影响.

第二种方法具有"消极"思维的缺点.如果我想在100/100点绘制一个元素,我必须将画布转换为-100/-100,因为我会在0/0上绘制.如果我在那之后恢复画布,结果将是在想要的100/100上绘制的元素.我不确定这种消极的想法是否会对代码可维护性和理解能力产生重大影响(甚至从未考虑通过简单地忘记否定某些内容来引入错误......).

有人有提示哪种方式应该首选吗?

War*_*ith 2

看来确实必须将两种解决方案结合起来。

我对第二种方法的假设是完全错误的。如果我将一个元素转换为 100/100,原点将更改为 100/100。当然,这同样适用于画布。消极的想法完全是我的胡言乱语。

合并结果如下:

  1. 将绘制的每个元素都有自己的矩阵,其中包含旋转、平移和缩放。
  2. 画布将通过 保存save(),使用提供的方法concat(Matrix matrix)可以应用元素的矩阵。绘图将完成,画布将通过 恢复restore()。
  3. 作为其他可绘制元素的父元素的每个可绘制元素将循环遍历子元素并以相同的方式保存、连接和恢复。

这使得无需任何大的实现工作就可以实现 2D 场景图。