/** @param arrayId index of the array argument to increment. */
 private void incrementIndex(final int arrayId) {
   indexes.set(arrayId, indexes.get(arrayId) + 1);
   if (arrayId > 0 && indexes.get(arrayId) == values.get(arrayId).length) {
     indexes.set(arrayId, 0);
     incrementIndex(arrayId - 1);
   }
 }
  private FloatArray computeTriangles() {
    FloatArray verticesArray = this.verticesArray;
    float[] vertices = this.vertices = verticesArray.items;

    IntArray vertexTypes = this.vertexTypes;
    vertexCount = verticesArray.size / 2;
    vertexTypes.ensureCapacity(vertexCount);
    for (int i = 0, n = vertexCount; i < n; ++i) vertexTypes.add(classifyVertex(i));

    FloatArray triangles = this.triangles;
    triangles.clear();
    // A polygon with n vertices has a triangulation of n-2 triangles.
    triangles.ensureCapacity(Math.max(0, vertexCount - 2) * 3 * 2);

    while (vertexCount > 3) {
      int earTipIndex = findEarTip();
      cutEarTip(earTipIndex);

      // The type of the two vertices adjacent to the clipped vertex may have changed.
      int previousIndex = previousIndex(earTipIndex);
      int nextIndex = earTipIndex == vertexCount ? 0 : earTipIndex;
      vertexTypes.set(previousIndex, classifyVertex(previousIndex));
      vertexTypes.set(nextIndex, classifyVertex(nextIndex));
    }

    if (vertexCount == 3) {
      triangles.add(vertices[0]);
      triangles.add(vertices[1]);
      triangles.add(vertices[2]);
      triangles.add(vertices[3]);
      triangles.add(vertices[4]);
      triangles.add(vertices[5]);
    }

    verticesArray.clear();
    vertexTypes.clear();
    return triangles;
  }