对半平面交s&i算法的理解

当时学这个算法的时候仅仅是粗略的理解了一下,好多细节其实根本就没有懂。借着bzoj_1007把这个梗补上。

先上图

首先,我们姑且把算法的过程按照有向直线的倾角分成四个阶段。

第一阶段也就是(-PI,-PI/2) 这一阶段搞定以后焦点一定是从右向左(最先加的点最靠右,最后加的点最靠左,栈顶的元素最靠左)

第二阶段也就是(-pi/2,0) 这一阶段搞定以后焦点一定是从左到右

注意:两个阶段的交界处位置(第一阶段和第二阶段的交界处位置),我们可以发现点越靠左越容易被删除!!所以直接从栈中弹

第三阶段也就是(0,PI/2),这一阶段搞定以后可以发现焦点一定是从左到右

注意:两个阶段的交界处位置(2,3的交界处位置),我们可以发现越靠右越容易被删除!!所以直接从栈中弹不会出现任何问题

我上面这句话是有问题的。。事实上从栈中弹会出问题。为什么?

如果这个时候点集中只有第二阶段的点,当然不会出现问题,问题是,现在点集中还有第一阶段的点,如果第一阶段最右边的点(因为第一阶段是从右到左,所以这个点一定是第一个点,即栈底)比第二阶段最后一个点还要靠右,这个店岂不是更容易被删除?所以只考虑栈顶肯定不行的呀。所以就是双端队列(还是双端栈?大雾)的样子。

第四阶段也就是(PI/2,PI),这一阶段搞定以后可以发现焦点一定是从左到右。

注意:两个阶段的交接位置(3,4),我们可以发现越靠右越容易被删除。所以,我们直接从栈中弹不会出现问题(的吧。。)

同理我们还要考虑最开始从右到左那块的栈底元素。

那么我们用不用考虑第二阶段最后的那附近元素呢?

答案是不用。

从第二阶段转化为第三阶段的时候,这些比第三阶段焦点还靠右的早就被砍回家吃饭了。哪有心情管它们。。咳咳。。扯远了。。不过好像这时候栈底也不用考虑?好像同样被砍到回家吃饭。

那么我们回过头来看第一阶段加的点。

第一阶段貌似如果删除的话,好像是删掉靠左的点更方便一点。

然后就用第一阶段还活着的直线把第四阶段末尾的那些很不友好的直线删掉。

然后就爽了

然后木有然后了

(哎?不对,好像考虑栈底元素不只是交界处的事?算了这不影响代码结果。话说我今天怎么想起来画图看这个来着QAQ)

(我果然是太弱了 QAQ)

如果作为神犇的你发现了文章中很多很多很多的问题,或者有什么意见或改进方法。。来打我呀~\(≧▽≦)/~(逃

posted @ 2015-06-12 16:25  清羽晨风  阅读(775)  评论(0编辑  收藏  举报