Epsilon 和坐标系

您选择的坐标系(即您选择的 1 个世界单位的含义)与您选择的笔刷 epsilon 值密切相关。坐标系反映在您传递给 InProgressStrokesView.startStroke() 的 inputToWorld 转换矩阵值以及您在绘制干笔触时应用于 Canvas 的类似转换中。

对于典型应用,可以仅考虑世界单位,并将 startStroke()strokeToWorldTransform 实参保留为默认的单位矩阵。

如果您的应用支持平移、缩放或旋转绘图表面,那么这些转换矩阵的确切值会随时间变化,但这些变化反映了用户通过相机查看绘图表面时,世界坐标系的变化。

世界坐标系可以想象成一个网格,每个单元格的大小都是一个世界单位。epsilon 是该网格中的一个大小,以世界单位表示的浮点数。

当用户放大内容时,也会放大世界单位网格,因此在默认 100% 缩放级别下,世界单位和 epsilon 大小的选择非常重要。

世界单位大小定义和世界单位中的 epsilon 值在应用的整个生命周期内必须是固定值。

内部实现使用 epsilon 来确定两个点必须彼此接近到什么程度才能被视为同一点。换句话说,任何小于 epsilon 的距离都被视为零距离。用于量化和舍入内部计算结果。

合理的实际单位大小和 epsilon 值是多少?

为了在不同的屏幕尺寸和设备密度之间实现可移植性,世界单位大小应与密度无关。此类场景的经典单位是密度无关像素 (dp)。通常选择 1 dp 作为世界单位大小。

选择固定 epsilon 值时,请避免内部实现将数字四舍五入为大于像素的任何距离。如果世界单位大小为 1 dp,则 epsilon 应最多为 1/4(0.25 个世界单位),以便在高显示密度设备上成为像素大小,其中 1 dp 可以是 4 px。不过,如果您想支持用户将内容放大到最多 10 倍,同时仍将与 epsilon 相关的舍入误差保持在 1 像素或更低,则 epsilon 应为 0.25 除以 10,即 0.025 个世界单位。

这并不意味着您无法将缩放倍数调高到 10 倍以上,但此时笔画渲染可能会出现一些不精确和伪影。

选择 epsilon 值时,需要在放大时的精确细节与计算资源之间取得平衡,例如:

  • CPU 周期,用于计算更精确的几何形状
  • 用于在相应几何图形中存储更多细节的内存
  • 渲染相应几何图形的 GPU 时间

这些准则是合理的默认值,但您可以根据自己的需求使用它们来选择更合适的坐标系和 epsilon 值。

如果偏离这些建议值过远,可能会对您的应用产生不利影响。例如,资源消耗增加可能会导致应用运行缓慢。在某些情况下,浮点精度问题也可能会表现为奇怪的视觉伪影。