private static LoopIndexCollection GetIndexCollection(BzPolyLoop loop) { var loopData = new LinkedLoop <LoopIndex>(); var loopNode = loop.edgeLoop.first; for (int i = 0; i < loop.edgeLoop.size; i++) { loopData.AddLast(new LoopIndex(loop, loopNode, loop.polyVertices2D[i])); loopNode = loopNode.next; } var indexCollection = new LoopIndexCollection(loop, loopData); return(indexCollection); }
private bool GetShortestConnection(LoopIndexCollection outerData, LoopIndexCollection innerData, BzPolyLoop[] allLoops, out LoopNode <LoopIndex> minOliNode, out LoopNode <LoopIndex> minIliNode) { minOliNode = null; minIliNode = null; float curDist = float.MaxValue; var oliNode = outerData.items.first; for (int oli = 0; oli < outerData.items.size; oli++) { var oliData = oliNode.value; var iliNode = innerData.items.first; for (int ili = 0; ili < innerData.items.size; ili++) { var iliNodeCurr = iliNode; iliNode = iliNode.next; var iliData = iliNodeCurr.value; Vector2 currOVector = iliData.vector2d - oliData.vector2d; float dist = currOVector.sqrMagnitude; if (dist >= curDist) { continue; } if (HaveLineSegmentsIntersection(allLoops, oliData, iliData)) { continue; } Vector2 center = oliData.vector2d; Vector2 vA = oliNode.previous.value.vector2d - center; Vector2 vB = iliData.vector2d - center; Vector2 vC = oliNode.next.value.vector2d - center; float angleA = Mathf.Atan2(vA.y, vA.x); float angleB = Mathf.Atan2(vB.y, vB.x); float angleC = Mathf.Atan2(vC.y, vC.x); float _2pi = 2 * Mathf.PI; if (angleA > angleB) { angleB += _2pi; } if (angleA > angleC) { angleC += _2pi; } if (angleB <= angleA | angleB >= angleC) { continue; } minOliNode = oliNode; minIliNode = iliNodeCurr; curDist = dist; } oliNode = oliNode.next; } return(minOliNode != null); }
private LoopIndex[] CombineLoops(BzPolyLoop outer, BzPolyLoop[] inners) { var outerData = GetIndexCollection(outer); var innersData = new LoopIndexCollection[inners.Length]; for (int i = 0; i < innersData.Length; i++) { var loop = inners[i]; innersData[i] = GetIndexCollection(loop); } var allLoops = new BzPolyLoop[inners.Length + 1]; allLoops[0] = outer; Array.Copy(inners, 0, allLoops, 1, inners.Length); for (int i = 0; i < innersData.Length; i++) { LoopNode <LoopIndex> minOliNode; LoopNode <LoopIndex> minIliNode; var inner = inners[i]; var innerData = innersData[i]; if (outer.Volume <= inner.Volume) { continue; } if (!inner.IsInside(outer)) { continue; } if (!GetShortestConnection(outerData, innerData, allLoops, out minOliNode, out minIliNode)) { continue; } if (minOliNode != null) { outerToInnerConnections.Add(new IndexVector( minOliNode.value.indexPointer.value, minIliNode.value.indexPointer.value) ); var list = minOliNode.list; list.InsertAfter(minOliNode, minOliNode.value); list.InsertAfter(minOliNode, minIliNode.value); list.InsertAfter(minOliNode, minIliNode, minIliNode.previous); } } var result = new LoopIndex[outerData.items.size]; var node = outerData.items.first; for (int i = 0; i < outerData.items.size; i++) { result[i] = node.value; node = node.next; } return(result); }