判断一个图形是否为凹多边形(1)

先百度一下凹多边形的定义:把一个各边不自交的多边形任意一边向两方无限延长成为一直线,如果多边形的所有边中只要有一条边向两方无限延长成为一直线时,其他各边不在此直线的同旁,那么这个多边形就叫做凹多边形。凹多边形有一个或多个内角大于180度。

      问:给出一个多边形的顶点集合,顶点与边的关系已知,如何判断这个多边形是否是一个凹多边形呢?

      如顶点集 ((0,0),(0,5),(5,5),(4,3),(5,0)) 围成了一个5变形,如何判断这个5变形是否是凹多边形?

      我给出的解法是:根据凹多边形的定义,如果将所有的边都无限延长成一条直线,必有一条直线会将这个图形切割成两半;而如果这个图形凸多边形则不会有这种情况。因此,我的解法需要从某一个顶点开始,顺时针(或逆时针)遍历完所有的边,每遍历一条边,都判断所有的顶点是否全部在这条直线的一侧,如果不是,说明这个图形是凹多边形。很明显,这个解法的算法复杂度是O(N^2),因为遍历所有顶点的开销需要 n,而每遍历一个顶点都需要比较其它n个顶点,合起来开销就是 n*n=n^2.
        我这个这个解法还涉及一个高中的数学知识:如何判断做标为 (x,y)的点在直线的哪一侧?
设直线是由其上两点(x1,y1)(x2,y2)确定的,直线方向是由(x1,y1)到(x2,y2)的方向。这时若直线方程记为Ax+By+C=0

则有:
     A=y2-y1; B=x1-x2; C=x2*y1-x1*y2;
这时可以计算D:
     D=A*xp+B*yp+C
若D<0,则点(xp,yp)在直线的左侧;若D>0,则点在直线的右侧;D=0点在直线上。

    小明童鞋的解法效率很高,证明方法也很独特,特将其解法抄录下来:
     定义:按照顶点的顺序,当我们从上一个顶点沿着边走向当前顶点时,若下个顶点在我们的左边(逆时针方向),我们称下个顶点为正顶点。
     定理:每个顶点都是正顶点的多边形为凸多边形。
     polygon=((0,0),(0,5),(5,5),(4,3),(5,0))
     def  IsConVex(polygon):
            r=len(polygon)
               for i in xrange(r):
                    #向量(下一个顶点与当前顶点,用来构建直线方程)
                    x,y=polygon[(i+1)%r][0] - polygon[i%r][0],   polygon[(i+1)%r][1] - polygon[(i%r)][1]
                    x1,y1=polygon[(i+1)%r]    #下一个顶点
                    x2,y2=polugon[(i-1+r)%r] #上一个顶点
                    if   (y*x2 + x*y1 -  y*x1) > y2*x:        #若下一个顶点不是正顶点
                           return False
            return True
      这个方法只需要遍历一次所有的顶点,因此复杂度是 n 。

 

转自:http://www.caxtu.com/thread-1080-1-1.html


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值