• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
bobird的学习笔记
博客园    首页    新随笔    联系   管理    订阅  订阅
基于ArcGIS Engine的任意多边形凸剖分算法

文章出处:http://www.cnblogs.com/wall/archive/2008/04/10/1147220.html

基于ArcGIS Engine的任意多边形凸剖分算法

 

任意多边形凸剖分对于编程人员来说是经常遇到的问题,当然算法也很多,但是大多很复杂,如果从底层来编写,非常繁琐
下面介绍一种基于AE的方法,理解起来,编写起来都比较简单,供大家参考

算法思想:
1、首先找到该多边形的包罗矩形(IGeometry.Envelope)
2、然后将该多边形的顶点集合(IPointCollection)按照X坐标(或Y坐标)进行从小到大(或从大到小)排序
3、然后过排序后的多边形顶点从小到大(或从大到小)绘制竖直(或水平)的直线
4、绘制的直线与多边形边界相交,就将该多边形分割成为若干个凸多边形。 

附VB.Net源码
''' <summary>
  ''' 得到任意多边形的剖分凸多边形集合
  ''' </summary>
  ''' <param name="pGeo">任意多边形</param>
  ''' <returns>剖分凸多边形集合</returns>
  ''' <remarks></remarks>
  Private Shared Function GetSolidHatchs(ByVal pGeo As IGeometry) As IGeometryCollection
    Dim pPoints As IPointCollection = pGeo
    Dim pXs As New List(Of Double)
    For i As Integer = 0 To pPoints.PointCount - 1
      pXs.Add(pPoints.Point(i).X)
    Next
    '’对该多边形边界的所有点集合以X或Y为标准进行排序,用于画切割线
    pXs.Sort()
    Dim pGeos As IGeometryCollection = New Polygon
    Dim pTopo As ITopologicalOperator = pGeo
    Dim listCount As Integer = pXs.Count

    Dim leftGeo As IGeometryCollection = New Polygon
    Dim rightGeo As IGeometryCollection = New Polygon
    For i As Integer = 0 To listCount - 1
      If pTopo.Boundary.IsEmpty Then Continue For
      If pXs(i) <= pTopo.Boundary.Envelope.XMin Or pXs(i) >= pTopo.Boundary.Envelope.XMax Then Continue For
      Dim cutLine As IPolyline = New Polyline
      Dim fromPoint As IPoint = New Point
      fromPoint.PutCoords(pXs(i), pTopo.Boundary.Envelope.YMax)
      Dim toPoint As IPoint = New Point
      toPoint.PutCoords(pXs(i), pTopo.Boundary.Envelope.YMin)
      ''生成切割线
      cutLine.FromPoint = fromPoint
      cutLine.ToPoint = toPoint
      ''用切割线切割多边形
      Try
        pTopo.Cut(cutLine, leftGeo, rightGeo)
      Catch ex As Exception
        Continue For
      End Try
      ''一条切割线切割出两个多边形,rightGeo是凸的,leftGeo继续用于切割
      pTopo = leftGeo
      For j As Integer = 0 To rightGeo.GeometryCount - 1
        pGeos.AddGeometry(rightGeo.Geometry(j))
      Next
    Next
    If Not rightGeo Is Nothing Then
      For j As Integer = 0 To leftGeo.GeometryCount - 1
        pGeos.AddGeometry(leftGeo.Geometry(j))
      Next
    End If
    If pGeos.GeometryCount = 0 Then
      For j As Integer = 0 To CType(pGeo, IGeometryCollection).GeometryCount - 1
        pGeos.AddGeometry(CType(pGeo, IGeometryCollection).Geometry(j))
      Next
    End If
    Return pGeos
  End Function

posted on 2013-01-10 14:11  bobird  阅读(949)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3