无向图:计算亏格(环的孔洞)

前一篇文章:无向图:计算亏格(环的孔洞)         

首先,判断图中是否存在环。方法,找到联通子图,循环删除度为1的节点,同时删除边。直到不存在度为1的边,则联通子图只剩下环或者复杂环。

         在不需要遍历出环的算法里面,可以通过欧拉公式直接计算亏格。孔洞的个数。

         公式: nGenus = l-p+1;  l为边的个数,p为点的个数。

         过程:对于所有联通的集合,循环删除度数为1的顶点,同时删除边;计算亏格。

然而,上述过程出现了问题。主要是平面图中若严格按照直线边进行拓扑,出现了复杂图,即立体图。


如图:

       


改进方法:

        使用多边形并差计算,以此寻找孔洞,以此来应对复杂图的特殊情况。

代码段:

import seisw.util.geom.Clip;
import seisw.util.geom.Poly;
import seisw.util.geom.PolyDefault;

	// 适应情况,一个房间多个家具,只有一次孔洞,不会有岛屿!
	private static int findPolyGenus( List<NewPoint> walls, List<List<NewPoint>> furniturePolygons, double wallwidth,
			double width) {
		// 1.根据分区得到房间剩下的多个多边形,要求生成的多个多边形不能有空洞
		int genus = 0;
		
		// 默认房间为逆时针多边形,分区需保证为顺时针
		Poly diffPoly = new PolyDefault();
		for (NewPoint p : walls) {
			diffPoly.add(p.m_x, p.m_y);
		}

		// 确保逆时针
		for (int k = 0; k < furniturePolygons.size(); ++k) {

			List<NewPoint> f = furniturePolygons.get(k);
			ArrayList<NewPoint> fEx = extendPoly(furniturePolygons.get(k), 15+ width + wallwidth);//width );// 	
			furniturePolygons.set(k, fEx);

			Poly subPoly = new PolyDefault();
			for (NewPoint p : fEx) {
				subPoly.add(p.m_x, p.m_y);
			}
			diffPoly = (PolyDefault) Clip.difference(diffPoly, subPoly);
		}

		// 获取所有孔洞
		genus = diffPoly.getNumInnerPoly();
		for ( int i = 0; i < diffPoly.getNumInnerPoly(); ++i) {
			boolean isHole = diffPoly.getInnerPoly(i).isHole();
			if( isHole ){
				genus = genus - 1;
			}
		}
    return genus;


最后,可以得到正确结果。





posted @ 2018-01-29 11:47  wishchin  阅读(371)  评论(0编辑  收藏  举报