我对实现算法比较陌生,所以我无法理解它的所有部分.到目前为止,这是我的代码:
local function getPolygonIntersectingVertices( poly ) -- initializing and sorting X local X = {} for i = 1, table.getn( poly ) do if i == 1 then table.insert( X, { x = poly[i].x, y = poly[i].y, endpoint = 'left' } ) elseif i == table.getn( poly ) then table.insert( X, { x = poly[i].x, y = poly[i].y, endpoint = 'right' } ) else table.insert( X, { x = poly[i].x, y = poly[i].y, endpoint = 'right' }) table.insert( X, { x = poly[i].x, y = poly[i].y, endpoint = 'left' }) end end local sortxy = function( a, b ) if a.x < b.x then return true elseif a.x > b.x then return false elseif a.y <= b.y then return true else return false end end table.sort( X, sortxy ) -- Main loop local SL = {} local L = {} local E local i = 1 while next(X) ~= nil do E = { x = X[i].x, y = X[i].y, endpoint = X[i].endpoint } if E.endpoint == 'left' then -- left endpoint code here elseif E.endpoint == 'right' then -- right endpoint code here else end table.remove( X, i ) end return L end
我的多边形是一个使用此结构的表:{{x = 1,y = 3},{x = 5,y = 6},…}
如何确定“SL中segE以上的段”;和“SL中segE以下的部分;”如果扫描线(SL)为空怎么办?同样,当我将I插入X时,我应该用endpoint =’intersect’标记它并将其附加到末尾,这样当循环到达这个部分时进入主循环的“else”语句或者我得到了整个算法错误?
这将是完美的,有人可以通过Python,Ruby等简单实现向我展示链接,因为我发现很难遵循伪代码并将其与C示例相匹配.
您的参考链接从我的位置失败.我会参考 the Wikipedia article,这是相当不错的.How do I determine “the segment above segE in SL;” and “the segment below segE in SL;”
该算法需要BST用于在y的关键字上排序的当前扫描线交叉点,即按垂直顺序排序.所以上面的部分是BST的继任者,下面的部分是BST的前身.在BST中查找给定节点的前任和后继是标准的东西.密钥K的前身是K左边最右边的节点.后继节点是K的最左边节点.有几种计算方法.最简单的方法是使用父指针向后行走,然后从K向下行走.基于堆栈的迭代器是另一个.
what to do if the sweep line (SL) is empty?
继续处理事件队列.空扫描线仅表示没有段在其当前x位置处交叉.
Also when inserting I into X, should I mark it with endpoint = ‘intersect’ and append it to the end …?
事件队列必须按点的x坐标排序.插入交集时,它也必须按x坐标顺序排列.必须将其标记为交叉点,因为交叉点的处理方式与端点不同.当它是x顺序中的第一个剩余项目时,它将在适当的时候处理.
请注意,Bentley Ottman – 就像几乎所有几何算法一样 – 因浮点不准确而臭名昭着.此外,该算法通常给出一个“一般位置”假设,它假设所有令人讨厌的垂直边缘,点边重合,边缘重叠等情况.我最强烈的建议是使用有理算术.即便如此,获得完全稳健,正确的实施也是一项重大成就.你可以通过极少数的免费实现来说明这一点!