// ========================================== 合并 ============================================= // /// <summary> /// 合并两个交叉的多边形(多边形必须先转换为顺时针方向,调用CW()函数!) /// </summary> /// <param name="other"></param> /// <param name="polyRes"></param> /// <returns></returns> public PolyResCode Union(Polygon other, ref List<Polygon> polyRes) { if (this.m_lstPoints.Count == 0 || other.m_lstPoints.Count == 0) return PolyResCode.ErrEmpty; else if (!NMath.CheckCross(GetCoverRect(), other.GetCoverRect())) return PolyResCode.ErrNotCross; // 转换为顺时针方向 //this.CW(); //other.CW(); List<NavNode> mainNode = new List<NavNode>(); //主多边形顶点 List<NavNode> subNode = new List<NavNode>(); //需要合并的多边形顶点 // init main nodes for (int i = 0; i < this.m_lstPoints.Count; i++) { NavNode currNode = new NavNode(this.m_lstPoints[i], false, true); if (i > 0) { NavNode preNode = mainNode[i - 1]; preNode.next = currNode; } mainNode.Add(currNode); } // init sub nodes for (int j = 0; j < other.m_lstPoints.Count; j++) { NavNode currNode = new NavNode(other.m_lstPoints[j], false, false); if (j > 0) { NavNode preNode = subNode[j - 1]; preNode.next = currNode; } subNode.Add(currNode); } int insCnt = 0; PolyResCode result = NavUtil.NavNodeIntersectPoint(mainNode, subNode, out insCnt); if (result == PolyResCode.Success && insCnt > 0) { if (insCnt % 2 != 0) { return PolyResCode.ErrCrossNum; } else { PolyResCode linkRes = NavUtil.LinkToPolygon(mainNode, subNode, ref polyRes); return linkRes; } } return PolyResCode.ErrCrossNum; }
/// <summary> /// 合并两个节点列表为一个多边形,结果为顺时针序( 生成的内部孔洞多边形为逆时针序) /// </summary> /// <param name="mainNode"></param> /// <param name="subNode"></param> /// <param name="polyRes"></param> /// <returns></returns> public static PolyResCode LinkToPolygon(List<NavNode> mainNode, List<NavNode> subNode, ref List<Polygon> polyRes) { polyRes.Clear(); for (int i = 0; i < mainNode.Count; i++) { NavNode currNode = mainNode[i]; // 选择一个没有访问过的交点做起始点 if (currNode.isIns && !currNode.passed) { List<Vector2> points = new List<Vector2>(); while (currNode != null) { currNode.passed = true; //交点转换 if (currNode.isIns) { currNode.other.passed = true; if (!currNode.o)//该交点为进点(跟踪裁剪多边形边界) { if (currNode.isMain)//当前点在主多边形中 currNode = currNode.other;//切换到裁剪多边形中 } else { //该交点为出点(跟踪主多边形边界) if (!currNode.isMain)//当前点在裁剪多边形中 currNode = currNode.other;//切换到主多边形中 } } points.Add(currNode.vertex); if (currNode.next == null) { if (currNode.isMain) currNode = mainNode[0]; else currNode = subNode[0]; } else currNode = currNode.next; if (currNode.vertex == points[0]) break; } // 删除重复顶点 Polygon poly = new Polygon(points); poly.DelRepeatPoint(); polyRes.Add(poly); } } return PolyResCode.Success; }
/// <summary> /// 合并两个节点列表为一个多边形,结果为顺时针序( 生成的内部孔洞多边形为逆时针序) /// </summary> /// <param name="mainNode"></param> /// <param name="subNode"></param> /// <param name="polyRes"></param> /// <returns></returns> public static PolyResCode LinkToPolygon(List <NavNode> mainNode, List <NavNode> subNode, ref List <Polygon> polyRes) { polyRes.Clear(); for (int i = 0; i < mainNode.Count; i++) { NavNode currNode = mainNode[i]; // 选择一个没有访问过的交点做起始点 if (currNode.isIns && !currNode.passed) { List <Vector2> points = new List <Vector2>(); while (currNode != null) { currNode.passed = true; //交点转换 if (currNode.isIns) { currNode.other.passed = true; if (!currNode.o) //该交点为进点(跟踪裁剪多边形边界) { if (currNode.isMain) //当前点在主多边形中 { currNode = currNode.other; //切换到裁剪多边形中 } } else { //该交点为出点(跟踪主多边形边界) if (!currNode.isMain) //当前点在裁剪多边形中 { currNode = currNode.other; //切换到主多边形中 } } } points.Add(currNode.vertex); if (currNode.next == null) { if (currNode.isMain) { currNode = mainNode[0]; } else { currNode = subNode[0]; } } else { currNode = currNode.next; } if (currNode.vertex == points[0]) { break; } } // 删除重复顶点 Polygon poly = new Polygon(points); poly.DelRepeatPoint(); polyRes.Add(poly); } } return(PolyResCode.Success); }