private void _transferVertexData(int vertexFrom, int vertexTo) { int v1 = m_shape.getUserIndex(vertexTo, m_userIndexSortedIndexToVertex); int v2 = m_shape.getUserIndex(vertexTo, m_userIndexSortedAngleIndexToVertex); m_shape.transferAllDataToTheVertex(vertexFrom, vertexTo); m_shape.setUserIndex(vertexTo, m_userIndexSortedIndexToVertex, v1); m_shape.setUserIndex(vertexTo, m_userIndexSortedAngleIndexToVertex, v2); }
private void _removeAngleSortInfo(int vertex) { int angleIndex = m_shape.getUserIndex(vertex, m_userIndexSortedAngleIndexToVertex); if (angleIndex != -1) { m_bunchEdgeIndices.set(angleIndex, -1); m_shape.setUserIndex(vertex, m_userIndexSortedAngleIndexToVertex, -1); } }
private void _beforeRemoveVertex(int vertex, boolean bChangePathFirst) { int vertexlistIndex = m_shape.getUserIndex(vertex, m_userIndexSortedIndexToVertex); // _ASSERT(m_sortedVertices.getData(vertexlistIndex) != 0xdeadbeef); if (m_nextVertexToProcess == vertexlistIndex) { m_nextVertexToProcess = m_sortedVertices.getNext(m_nextVertexToProcess); } if (m_firstCoincidentVertex == vertexlistIndex) m_firstCoincidentVertex = m_sortedVertices.getNext(m_firstCoincidentVertex); m_sortedVertices.deleteElement(m_sortedVerticesListIndex, vertexlistIndex); _removeAngleSortInfo(vertex); if (bChangePathFirst) { int path = m_shape.getPathFromVertex(vertex); if (path != -1) { int first = m_shape.getFirstVertex(path); if (first == vertex) { int next = m_shape.getNextVertex(vertex); if (next != vertex) m_shape.setFirstVertex_(path, next); else { m_shape.setFirstVertex_(path, -1); m_shape.setLastVertex_(path, -1); } } } } }
private boolean _processBunch() { boolean bModified = false; int iter = 0; Point2D ptCenter = new Point2D(); while (true) { m_dbgCounter++; // only for debugging iter++; // _ASSERT(iter < 10); if (m_bunchEdgeEndPoints == null) { m_bunchEdgeEndPoints = new AttributeStreamOfInt32(0); m_bunchEdgeCenterPoints = new AttributeStreamOfInt32(0); m_bunchEdgeIndices = new AttributeStreamOfInt32(0); } else { m_bunchEdgeEndPoints.clear(false); m_bunchEdgeCenterPoints.clear(false); m_bunchEdgeIndices.clear(false); } int currentVertex = m_firstCoincidentVertex; int index = 0; boolean bFirst = true; while (currentVertex != m_nextVertexToProcess) { int v = m_sortedVertices.getData(currentVertex); { // debug Point2D pt = new Point2D(); m_shape.getXY(v, pt); double y = pt.x; } if (bFirst) { m_shape.getXY(v, ptCenter); bFirst = false; } int vertP = m_shape.getPrevVertex(v); int vertN = m_shape.getNextVertex(v); // _ASSERT(vertP != vertN || m_shape.getPrevVertex(vertN) == v // && m_shape.getNextVertex(vertP) == v); int id = m_shape.getUserIndex(vertP, m_userIndexSortedAngleIndexToVertex); if (id != 0xdeadbeef) // avoid adding a point twice { // _ASSERT(id == -1); m_bunchEdgeEndPoints.add(vertP); m_shape.setUserIndex(vertP, m_userIndexSortedAngleIndexToVertex, 0xdeadbeef); // mark // that // it // has // been // already // added m_bunchEdgeCenterPoints.add(v); m_bunchEdgeIndices.add(index++); } int id2 = m_shape.getUserIndex(vertN, m_userIndexSortedAngleIndexToVertex); if (id2 != 0xdeadbeef) // avoid adding a point twice { // _ASSERT(id2 == -1); m_bunchEdgeEndPoints.add(vertN); m_shape.setUserIndex(vertN, m_userIndexSortedAngleIndexToVertex, 0xdeadbeef); // mark // that // it // has // been // already // added m_bunchEdgeCenterPoints.add(v); m_bunchEdgeIndices.add(index++); } currentVertex = m_sortedVertices.getNext(currentVertex); } if (m_bunchEdgeEndPoints.size() < 2) break; // Sort the bunch edpoints by angle (angle between the axis x and // the edge, connecting the endpoint with the bunch center) m_bunchEdgeIndices.Sort(0, m_bunchEdgeIndices.size(), new SimplificatorAngleComparer(this)); // SORTDYNAMICARRAYEX(m_bunchEdgeIndices, int, 0, // m_bunchEdgeIndices.size(), SimplificatorAngleComparer, this); for (int i = 0, n = m_bunchEdgeIndices.size(); i < n; i++) { int indexL = m_bunchEdgeIndices.get(i); int vertex = m_bunchEdgeEndPoints.get(indexL); m_shape.setUserIndex(vertex, m_userIndexSortedAngleIndexToVertex, i); // rember the // sort by angle // order { // debug Point2D pt = new Point2D(); m_shape.getXY(vertex, pt); double y = pt.x; } } boolean bCrossOverResolved = _processCrossOvers(ptCenter); // see of // there // are // crossing // over // edges. for (int i = 0, n = m_bunchEdgeIndices.size(); i < n; i++) { int indexL = m_bunchEdgeIndices.get(i); if (indexL == -1) continue; int vertex = m_bunchEdgeEndPoints.get(indexL); m_shape.setUserIndex(vertex, m_userIndexSortedAngleIndexToVertex, -1); // remove // mapping } if (bCrossOverResolved) { bModified = true; continue; } break; } return bModified; }
private boolean _detectAndResolveCrossOver( boolean bDirection1, boolean bDirection2, int vertexB1, int vertexA1, int vertexC1, int vertexB2, int vertexA2, int vertexC2) { // _ASSERT(!m_shape.isEqualXY(vertexB1, vertexB2)); // _ASSERT(!m_shape.isEqualXY(vertexC1, vertexC2)); if (vertexA1 == vertexA2) { _removeAngleSortInfo(vertexB1); _removeAngleSortInfo(vertexB2); return false; } // _ASSERT(!m_shape.isEqualXY(vertexB1, vertexC2)); // _ASSERT(!m_shape.isEqualXY(vertexB1, vertexC1)); // _ASSERT(!m_shape.isEqualXY(vertexB2, vertexC2)); // _ASSERT(!m_shape.isEqualXY(vertexB2, vertexC1)); // _ASSERT(!m_shape.isEqualXY(vertexA1, vertexB1)); // _ASSERT(!m_shape.isEqualXY(vertexA1, vertexC1)); // _ASSERT(!m_shape.isEqualXY(vertexA2, vertexB2)); // _ASSERT(!m_shape.isEqualXY(vertexA2, vertexC2)); // _ASSERT(m_shape.isEqualXY(vertexA1, vertexA2)); // get indices of the vertices for the angle sort. int iB1 = m_shape.getUserIndex(vertexB1, m_userIndexSortedAngleIndexToVertex); int iC1 = m_shape.getUserIndex(vertexC1, m_userIndexSortedAngleIndexToVertex); int iB2 = m_shape.getUserIndex(vertexB2, m_userIndexSortedAngleIndexToVertex); int iC2 = m_shape.getUserIndex(vertexC2, m_userIndexSortedAngleIndexToVertex); // _ASSERT(iB1 >= 0); // _ASSERT(iC1 >= 0); // _ASSERT(iB2 >= 0); // _ASSERT(iC2 >= 0); // Sort the indices to restore the angle-sort order int[] ar = new int[8]; int[] br = new int[4]; ar[0] = 0; br[0] = iB1; ar[1] = 0; br[1] = iC1; ar[2] = 1; br[2] = iB2; ar[3] = 1; br[3] = iC2; for (int j = 1; j < 4; j++) // insertion sort { int key = br[j]; int data = ar[j]; int i = j - 1; while (i >= 0 && br[i] > key) { br[i + 1] = br[i]; ar[i + 1] = ar[i]; i--; } br[i + 1] = key; ar[i + 1] = data; } int detector = 0; if (ar[0] != 0) detector |= 1; if (ar[1] != 0) detector |= 2; if (ar[2] != 0) detector |= 4; if (ar[3] != 0) detector |= 8; if (detector != 5 && detector != 10) // not an overlap return false; if (bDirection1 == bDirection2) { if (bDirection1) { m_shape.setNextVertex_(vertexC2, vertexA1); // B1< >B2 m_shape.setPrevVertex_(vertexA1, vertexC2); // \ / m_shape.setNextVertex_(vertexC1, vertexA2); // A1A2 m_shape.setPrevVertex_(vertexA2, vertexC1); // / \ // // C2> <C1 } else { m_shape.setPrevVertex_(vertexC2, vertexA1); // B1> <B2 m_shape.setNextVertex_(vertexA1, vertexC2); // \ / m_shape.setPrevVertex_(vertexC1, vertexA2); // A1A2 m_shape.setNextVertex_(vertexA2, vertexC1); // / \ // // C2< >C1 } } else { if (bDirection1) { m_shape.setPrevVertex_(vertexA1, vertexB2); // B1< <B2 m_shape.setNextVertex_(vertexB2, vertexA1); // \ / m_shape.setPrevVertex_(vertexA2, vertexC1); // A1A2 m_shape.setNextVertex_(vertexC1, vertexA2); // / \ // // C2< <C1 } else { m_shape.setNextVertex_(vertexA1, vertexB2); // B1> >B2 m_shape.setPrevVertex_(vertexB2, vertexA1); // \ / m_shape.setNextVertex_(vertexA2, vertexC1); // A1A2 m_shape.setPrevVertex_(vertexC1, vertexA2); // / \ // // C2> >C1 } } return true; }