多边形选多边形(blend polygons)
支持初始化、写入、直读 Canvas
输入点、凸多边形,并显示它们
Boost: GIL 用于读写 PNG 格式图片(已弃用)- Eigen: 用于高性能线性代数计算
注意到几何变换的目的坐标是通过
所以,对于坐标
好在现代 OpenGL 为了 GPGPU 添加了新的工具:Image。Image 就像 CUDA 中位于全局内存的数组,可以任意地读取和写入,但是操作顺序、同步、原子性等问题须由程序员负责。
目前暂定所有数据存储都使用 Image 来抽象。暂不知传统 Texture 和 Image 的性能差异(官方 Wiki 并无说明)。
原文称切分是针对每个非空像素点,单独挑出,形成 Canvas。我认为纯粹依照原文的概念,极难实现这一操作。首先,原文声称用 OpenGL Texture 来实现 Canvas,然而 OpenGL 支持的最大 Texture 数量十分有限(在我的机器上最多 80 个),难道切分操作不支持超过 80 个非空像素点吗?其次,一张 Canvas 的空间消耗极大。假设原文中
综上所述,切分的实现不可能是朴素的,不能照搬论文中的概念进行操作。
我目前的想法是,将切分定义为一种特殊的中间运算,定义特殊的储存格式与其运算结果对应,而不是 Canvas。副作用是,这会产生切分与后续运算的耦合性。
以下内容(除实现外)皆来自 arXiv:2004.03630 [cs]
$$ C'=\mathscr{G}\gamma $$
- 根据坐标变换:$C'(\gamma(x, y))=C(x, y)$
- 根据值变换:$C'(\gamma(C(x, y)))=C(x, y)$
$$ C'=\mathscr{V}f \ f: \mathbb{R}^{2} \times S^{3} \rightarrow S^{3} $$
根据值和坐标变换:$C'(x, y)=f(x, y, C(x, y))$
$$ C'=\mathscr{M}M $$
若值不符合要求,则抛弃之:
$C'(x, y)=\left{\begin{array}{ll}C(x, y), & \text { if } C(x, y) \in M \ \emptyset & \text { otherwise }\end{array}\right.$
根据两旧值产生新值:
每个非空像素点产生一张新 canvas:
$C_{i}\left(x', y'\right)=\left{\begin{array}{ll}C(x, y), & \text { if }\left(x', y'\right)=(x, y) \ \emptyset & \text { otherwise }\end{array}\right.$
$$ \begin{aligned} \left{C_{1}, C_{2}, \ldots, C_{n}\right}=&\mathscr{D}^{*}\gamma\ =& \mathscr{G}\gamma
\end{aligned} $$
$C_{i}(x, y)[0]=\left{\begin{array}{ll}(i d, 1,0) & \text { if }(x, y)=\left(x_{i}, y_{i}\right) \ \emptyset & \text { otherwise }\end{array}\right.$
$\begin{aligned} C_{Q}(x, y)[0] &=C_{Q}(x, y)[1]=\emptyset \ C_{Q}(x, y)[2] &=\left{\begin{array}{ll}(1,1,0) & \text { if }(x, y) \text { falls inside } Q \ \emptyset & \text { otherwise }\end{array}\right.\end{aligned}$
$\mathbb{C}{\text {result }} \leftarrow \mathscr{M}\left[M{p}\right]\left(\mathscr{B}[\odot]\left(\mathbb{C}{P}, C{Q}\right)\right)$
$s_{1} \odot s_{2}=\left[\begin{array}{ccc}s_{1}[0][0] & s_{1}[0][1] & s_{1}[0][2] \ - & \emptyset & - \ s_{2}[2][0] & s_{2}[2][1] & s_{2}[2][2]\end{array}\right]$
$\begin{aligned} C_{i}(x, y)[0] &=C_{i}(x, y)[1]=\emptyset \ C_{i}(x, y)[2] &=\left{\begin{array}{ll}(i d, 1,0) & \text { if }(x, y) \text { falls inside } Y_{i} \ \emptyset & \text { otherwise }\end{array}\right.\end{aligned}$
$\mathbb{C}{\text {result }} \leftarrow \mathscr{M}\left[M{y}\right]\left(\mathscr{B}[\oplus]\left(\mathbb{C}{Y}, C{Q}\right)\right)$
$s_{1} \oplus s_{2}=\left[\begin{array}{ccc}- & \emptyset & - \ - & \emptyset & - \ s_{1}[2][0] & s_{1}[2][1]+s_{2}[2][1] & s_{1}[2][2]\end{array}\right]$
[TODO]
SELECT COUNT (*) FROM
- & \emptyset & - \ s_{2}[2][0] & s_{2}[2][1] & s_{2}[2][2] \end{array}\right] $$ $\mathbb{C}{\text {result }} \leftarrow \mathscr{M}\left[M{p}\right]\left(\mathscr{B}[\odot]\left(\mathbb{C}{P}, C{Q}\right)\right)$ 是选点查询的结果。是多张 canvas。
做法:给定一个半径画圆,求出点的数量,据此二分答案。
- 对于点,需要记住精确的 location
- 对于多边形,需要标记像素是否在边界上
- 使用扩展:conservative rasterization
- 维护一个map,将位于边界的像素映射到原多边形(矢量形式)
- 用 (r,g,b,a) 来储存 canvas function
- 对于有洞的多边形,先绘制无洞版本,再单独绘制洞,做减法
- 混合 通过直接 alpha blending 两张 textures 实现
- 遮罩 并行地测试每个像素点。此时边界信息用于精确测试每个像素是否位于多边形边界。