如何用等距水平线填充封闭的折线?

时间:2015-09-29 08:48:28

标签: c++ algorithm computational-geometry

  

我需要编写和算法用水平等距线填充闭合多义线

我用矩形 circle 做了类似的事情,这是后者的代码片段:

// circle parameters: center(point(0).x, point(0).y), radius
int offsetX = point(0).x + radius;
int offsetY = point(0).y + radius;
for(int i = -radius; i < radius; i += spacing){
    int ry = i;
    int rx = sqrt(double(radius*radius - ry*ry));
    // the parameters are pair of coordinates of the horizontal line
    fl_line(offsetX - rx, offsetY + i, 
            offsetX + rx, offsetY + i);
}

闭合多线的情况下,额外的难度(对我而言)是水平线的坐标不会从单个方程中提取(圆形,矩形的高度,等),而是来自具有相同“y”坐标的线的方程式,这些坐标将不会连续匹配。

问题:

  1. 您能否就如何创建一个用水平线填充封闭多边形线的算法向我提供一些见解?

2 个答案:

答案 0 :(得分:5)

这只是扫描线算法(用于填充多边形)的特例:http://www.tutorialspoint.com/computer_graphics/polygon_filling_algorithm.htm

使用所需的步长(间距)将y从yMin(多边形的顶部)迭代到yMax。

对于每个y,找到与多边形线段的交点,按x坐标排序,用线连接每隔一对

答案 1 :(得分:1)

首先创建一个具有最低端点的所有边的列表。通过增加纵坐标(最低端点)对列表进行排序。

创建一个“活动列表”,其中包含与当前水平相交的所有边。

初始化最低边缘下方的当前水平位置,并确保活动列表为空。

以所需的增量向上移动水平,直到活动列表再次清空。

移动后,从活动列表中丢弃不再与其相交的边。还要添加将开始交叉的边缘(因为边缘已经排序,您将搜索不超过需要的数量。)

请注意,可以完全跳过边缘(它可以进入活动列表并立即离开)。

当活动列表是最新的时,计算所有交叉点并按从左到右的水平段连接它们。

请注意,在成对连接交叉点之前,可以通过在必要时小心插入新边来避免水平排序。鉴于活动列表通常很短,我更喜欢系统地应用插入排序。

假设所有活动列表操作都采用列表大小的线性时间,总时间就像O(Ne.Lg(Ne) + Ny.L),其中Ne是边数,Ny的数量是L水平线和O(Ne.Ny)每个水平线的平均交叉点数(通常在2到4之间)。对于天真的算法,这将与button(-text => 'Row1', -command => \&do_something_with('Row 1')); ttk::button -text $row -command [list RowOpertaion $row $xyz $abc] 进行比较。