一种矢量多边形栅格化的算法及系统的制作方法_3

文档序号:9433576阅读:来源:国知局
,首先是标记当前要处理的网格行里的每一列的网格点。在这里,会新建两个数组:第一个数组,是当前行处理结果数组,用byte类型存储,大小为N+1,记为Al ;第二个数组,是以与之前生成的每一行相交的多边形线段索引个数为行,以格网列数(N+1)为列的byte类型二维数组,记为A2。实际上,A2是中间计算占用的内存数组,而由于只需要标记格网点是否与多边形边相交的关系就可以了,所以实际上这个标识只需要占用一个bit位,即A2的大小实际上可以是可以缩小八倍的。这里将数组A2缩小八倍的解决方案有两个,第一个就是将这个数组的行减少,即每8个索引占用一个行数;这种方式实现起来简单,即按位来取某一行的某一个格网上的值即可,每个值代表的是同一列的8个索引的情况,但是这种方案占用的额外空间可能要多一行,即多N+1个字节;第二个方案就是把二维数组A2看作是一维,再除以8,得到一个数组,原来的每个索引和格网点现在需要将它们的原位置除以8,得到的新的位置上,再取这个byte上原位置与8的余数的位,得到相应的标记值;这种方法就是计算量会大一点,但是最多能节省N+1个字节空间。
[0058]标记当前要处理的网格行里的每一列的网格点的方法是这样的:遍历第i行相交的多边形线段索引数组,即在上面生成的与多边形相交的线段索引集合中取第i行记录的索引数组,得到多边形的一条线段,这条线段与第i行一定是相交的;此时,若线段的两个端点X不与栅格化范围相交,且比栅格化范围的右坐标要大,则不处理;否则,计算线段与第i行的行边界相交的两个交点vl、v2(若不相交,则直接取线段的两个端点),计算vl、v2所在的网格列号idxl、idx2(可以超出栅格化范围),并且调整到idxl〈 = idx2,设置数组Al和A2的最后一个存储字节flag为false (初始化),flag代表的是线段有没有到栅格化范围以左的范围。若网格列号idx2超出最大的网格列号,则令idx2为网格列号最大值,若网格列号idxl或者idx2小于0,则令idxl或idx2为0,设置flag标志为true。计算完后,从idxl到idx2的格网点都需要进行标记,即数组Al,A2都需要被标记。若flag标志为true,则标记Al的最后一个存储字节,表示有线段延伸到了左边。同时标记A2的当前线段对应行的最后一个存储字节(若按照bit位压缩则设置到对应的bit位),表示当前线段延伸到了左边,至此标记结束。
[0059]然后,就是循环处理第i行每一个网格点的过程。新建一个长度为第i行相交多边形线段数目的数组A3,初始化所有值为O (这是个临时标记数组,可以和前面的考虑一样,采用bit位进行标记),因为前面一步已经做了边界的标记,也就是栅格化后代表多边形的边的标记,所以,这里我们只需要对数组Al中没有做标记的对应格网点做处理即可。现在,对于第j个网格点,先往左查找。若j = 0,并且Al的第N+1个值没有被标记,则当前标记的值为0,进入下次循环,此时索引ifrom为-1。若j#0,且Al的第N+1个值没有被标记,此时,若第j个网格点左边的未标记的网格点的标记值不为1,则将左边的未标记的网格点的标记值赋给当前要处理的网格点的标记,若第j个网格点左边的未标记的网格点的标记值为I,则一直寻找直到左边标记值不为I,设此时找到的索引为ifrom,等待下一步操作;
[0060]下一步,新建一个长度为与第i行相交的多边形的线段数目的数组A3,初始化所有值为0,将数组A2每一列中最后一个索引位置上的每一条相交的多边形的线段对应位的标记相与到A3数组的相应位置中,并设置此时的网格点的起始索引值ifrom = O ;再遍历数组A2中的网格点的起始索引值ifrom到当前,将数组A2里每一条相交的线段对应的位标记相与到A3数组相应位置,得到被标记的数组A3 ;这样做的目的,是找出当前网格点到上一个不为边界的网格点之间,到底有多少个多边形的线段。这样做的目的,是找出当前网格点到上一个不为边界的网格点之间,到底有多少多边形的线段。
[0061]接下来,则是使用测试射线来测试射线穿越了多少条这样的线段。在这一步中,使用的测试点test为当前网格点的中点,选这样的点事方便计算。现在遍历每一条在上一步A3数组里标记的线段,不妨设其端点为vl,v20判断的方法是这样的:若vl,v2的y值同时大于test的y值,或者vl,v2的y值同时小于test的y值,或者vl,v2的y值相等,贝Ij不认为射线穿越;否则,认为射线穿越。
[0062]最后,判断穿越线段的条数。若ifrom〈0,并且穿越条数为偶数条,则当前网格点标记为O ;若ifrom ^ 0,并且穿越条数为偶数条,则当前网格点标记为ifrom索引对应的网格点的标记值;若ifrom〈0,并且穿越条数为奇数条,则当前网格点标记为2 ;若ifrom多0,并且穿越条数为奇数条,则分两种情况:第一,ifrom索引对应的网格点标记值为0,则当前网格点的标记为2 ;第二,ifrom索引对应的网格点标记值为2,则当前网格点的标记为O (O代表在多边形外部,I代表在多边形边上,2代表在多边形内部)。
[0063]根据最后一步中网格点的标记值,进行数据填充,生成栅格化结果。
[0064]至此,本算法完成了,此时栅格化的结果,已经可以满足第一和第四个场景的需要,可以直接利用栅格化的结果来做个性化的渲染了。
[0065]而对于第三个场景的需要,因为已经可以利用大量栅格化的点来加速判断矢量要素与当前多边形的关系,对于一般的应用场景来说,这种加速已经够用了,此时生成的计算结果也可以算作是索引;但是实际上,在第三个场景遇到点判断不在线上,但又在容限范围内与含有多边形边界的网格相交时,需要判断点与多边形的关系时,还有进一步优化的余地,并且这种优化会将这种单次计算的算法复杂度降低几个数量级。在这里,若要满足进一步的需要,在前面的计算中,我们需要将每个栅格化的网格点,具体是与哪些多边形的线段相交这一信息记录下来,即需要额外计算并存储网格点与多边形线段相交的线段的索引集合。对于某个需要判断的点P,若P落在未被标记的网格点范围内,则不需要进一步处理,直接返回该网格点栅格值即可;否则,找到P点落在的栅格化网格点左右连续的被标记的网格点集合。即一个找到一个连续的集合,所有被标记的网格点,并且包含P点所在的网格点。统计这样的每个网格点里相交的线段总数,这样,就能决定P点是向左做射线测试还是向右做射线测试,以减少计算量。这里假设是向右做射线测试,在我们需要把位于P所在网格点右边的所有网格点,和P所在网格点,与它们相交的所有的线段与P做求交测试。在这里,若为了计算简便,可以直接使用直线方程与P向正X轴做的射线求交得到交点,统计交点的个数。若交点的个数为奇数,则P点的内外关系与右边相邻的未被标记的网格点内外关系相反,反之,则相同。
[0066]而若为了进一步的极致性能,可以在这一步进一步优化。我们可以观察到,由于多边形的线段都是连续的,并且多边形的边是不相交的,所以,在这一个连续的栅格集合中,所有相交的多边形线段,构成了一系列两两不相交的多段线。在这里,对这些多段线进行排序。排序的比较字段是这些多段线起始端点和终止端点中的较小值,或者较大值也可以。得到排序后的索引值。这样排序之后,可以得到一个性质,就是任意一条沿X轴的射线与这些多段线的交点的顺序与这些排序后的索引值顺序是一致的,利用数学方法可以证明,因为他们的端点较小值和端点较大值都遵循这个索引值顺序,而中间值则是由两个端点值的一定比例得到的,所以也是一致的。这样,对于这些多段线两两间隔成的区间,是可以得到其内外性质的,这个内外性质在前面第三步时都能算出来。
[0067]这样,若要得到P点的内外性质,只需要知道P点所在的区间即可。
[0068]先假设这些多段线中不含两个端点在同一根行线上的情况。这样,若点P落在某个区间内,向右做射线的话,除了 P点所在的区间的左边界多段线之外的话,必定会与P点所在的区间的右边界多段线最先相交。这样,我们考虑P点与多段线的范围相交,和P点不与任何多段线的范围相交两种情况即可。若P点不与任何多段线的范围相交,则只需要找出位于P点右边的多段线的范围,这些范围里的最左边的多段线,即是P点所在区间的右多段线。这个判断只需要范围的X坐标比P的X坐标大即可。若P点与多段线的范围相交,则需要先找出与P点相交的多段线的范围,从P点向X正轴方向做射线与这些多段线求交,得到的交点再进行排序。若产生的第一个交点对应的多段线与P点向X正轴方向做的射线的交点个数为偶数个,则该多段线为P点所在区间的左边界;若为奇数个,则该多段线为P点所在区间的右边界;若没有产生任何交点,则这些多段线的最右边的多段线,为P点所在区间的左边界。至此,两个端点跨行线的情况讨论完了。
[0069]下面讨论存在两个端点在同一根行线上的情况,即形成了一个回环的情况。这里也有两种情况:第一是回环的范围不与P点相交,这样回环的存在与否与P点的判断没有关系,就和多段线中不含两个端点在同一根行线上的情况一样,可以放在上面讨论;第二是回环的范围与P点相交,这样向X正轴方向做射线,与这些回环进行求交,若产生的交点数总数为偶数个(只计算总数,不关心交点是分布在同一回环还是不同回环上),则P点内外关系和忽略回环时的内外关系相同,这时再到前面的情况讨论。若交点总数为奇数个,则P点内外关系与忽略回环时的内外关系相反。
[0070]至此,对于前面【背景技术】中的第一、第三、第四个场景本发明的算法都有了很好的解决。
[0071]下面再来看看,本发明的算法对于并行、海量数据方面的支持情况。
[0072]由于本算法的性质,将本算法改造成并行执行还是比较容易的,这是一个并行策略的问题。首先在第一步和第二步,计算边信息和计算每一行与多边形相交的线段的索引集合都是可以并行执行的。前者是互不影响的,可以直接修
当前第3页1 2 3 4 5 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1