private static Boolean findConvexPolygon(final PlanetModel planetModel,final Edge currentEdge,final GeoCompositePolygon rval,final EdgeBuffer edgeBuffer,final List<GeoPolygon> holes,final GeoPoint testPoint){
  final Set<Edge> includedEdges=new HashSet<>();
  includedEdges.add(currentEdge);
  Edge firstEdge=currentEdge;
  Edge lastEdge=currentEdge;
  while (true) {
    if (firstEdge.startPoint == lastEdge.endPoint) {
      break;
    }
    final Edge newLastEdge=edgeBuffer.getNext(lastEdge);
    if (isWithin(newLastEdge.endPoint,includedEdges)) {
      final SidedPlane returnBoundary;
      if (firstEdge.startPoint != newLastEdge.endPoint) {
        returnBoundary=new SidedPlane(firstEdge.endPoint,firstEdge.startPoint,newLastEdge.endPoint);
      }
 else {
        returnBoundary=null;
      }
      boolean foundPointInside=false;
      final Iterator<Edge> edgeIterator=edgeBuffer.iterator();
      while (edgeIterator.hasNext()) {
        final Edge edge=edgeIterator.next();
        if (!includedEdges.contains(edge) && edge != newLastEdge) {
          if (edge.startPoint != newLastEdge.endPoint) {
            if (isWithin(edge.startPoint,includedEdges,newLastEdge,returnBoundary)) {
              foundPointInside=true;
              break;
            }
          }
          if (edge.endPoint != firstEdge.startPoint) {
            if (isWithin(edge.endPoint,includedEdges,newLastEdge,returnBoundary)) {
              foundPointInside=true;
              break;
            }
          }
        }
      }
      if (!foundPointInside) {
        includedEdges.add(newLastEdge);
        lastEdge=newLastEdge;
        continue;
      }
    }
    break;
  }
  while (true) {
    if (firstEdge.startPoint == lastEdge.endPoint) {
      break;
    }
    final Edge newFirstEdge=edgeBuffer.getPrevious(firstEdge);
    if (isWithin(newFirstEdge.startPoint,includedEdges)) {
      final SidedPlane returnBoundary;
      if (newFirstEdge.startPoint != lastEdge.endPoint) {
        returnBoundary=new SidedPlane(lastEdge.startPoint,lastEdge.endPoint,newFirstEdge.startPoint);
      }
 else {
        returnBoundary=null;
      }
      boolean foundPointInside=false;
      final Iterator<Edge> edgeIterator=edgeBuffer.iterator();
      while (edgeIterator.hasNext()) {
        final Edge edge=edgeIterator.next();
        if (!includedEdges.contains(edge) && edge != newFirstEdge) {
          if (edge.startPoint != lastEdge.endPoint) {
            if (isWithin(edge.startPoint,includedEdges,newFirstEdge,returnBoundary)) {
              foundPointInside=true;
              break;
            }
          }
          if (edge.endPoint != newFirstEdge.startPoint) {
            if (isWithin(edge.endPoint,includedEdges,newFirstEdge,returnBoundary)) {
              foundPointInside=true;
              break;
            }
          }
        }
      }
      if (!foundPointInside) {
        includedEdges.add(newFirstEdge);
        firstEdge=newFirstEdge;
        continue;
      }
    }
    break;
  }
  if (includedEdges.size() < 2) {
    return false;
  }
  final List<GeoPoint> points=new ArrayList<GeoPoint>(includedEdges.size() + 1);
  final BitSet internalEdges=new BitSet(includedEdges.size());
  final boolean returnIsInternal;
  if (firstEdge.startPoint == lastEdge.endPoint) {
    if (includedEdges.size() < 3) {
      return false;
    }
    Edge edge=firstEdge;
    points.add(edge.startPoint);
    int k=0;
    while (true) {
      if (edge == lastEdge) {
        break;
      }
      points.add(edge.endPoint);
      internalEdges.set(k++,edge.isInternal);
      edge=edgeBuffer.getNext(edge);
    }
    returnIsInternal=lastEdge.isInternal;
    for (int i=0; i < points.size(); i++) {
      final GeoPoint start=points.get(i);
      final GeoPoint end=points.get(getLegalIndex(i + 1,points.size()));
      final Plane planeToFind=new Plane(start,end);
      int endPointIndex=-1;
      for (int j=0; j < points.size(); j++) {
        final int index=getLegalIndex(j + i + 2,points.size());
        if (!planeToFind.evaluateIsZero(points.get(index))) {
          endPointIndex=index;
          break;
        }
      }
      if (endPointIndex == -1) {
        return false;
      }
    }
    edgeBuffer.clear();
  }
 else {
    final SidedPlane returnSidedPlane=new SidedPlane(firstEdge.endPoint,false,firstEdge.startPoint,lastEdge.endPoint);
    final Edge returnEdge=new Edge(firstEdge.startPoint,lastEdge.endPoint,returnSidedPlane,true);
    final List<Edge> edges=new ArrayList<Edge>(includedEdges.size());
    returnIsInternal=true;
    Edge edge=firstEdge;
    points.add(edge.startPoint);
    int k=0;
    while (true) {
      points.add(edge.endPoint);
      internalEdges.set(k++,edge.isInternal);
      edges.add(edge);
      if (edge == lastEdge) {
        break;
      }
      edge=edgeBuffer.getNext(edge);
    }
    for (int i=0; i < points.size(); i++) {
      final GeoPoint start=points.get(i);
      final GeoPoint end=points.get(getLegalIndex(i + 1,points.size()));
      final Plane planeToFind=new Plane(start,end);
      int endPointIndex=-1;
      for (int j=0; j < points.size(); j++) {
        final int index=getLegalIndex(j + i + 2,points.size());
        if (!planeToFind.evaluateIsZero(points.get(index))) {
          endPointIndex=index;
          break;
        }
      }
      if (endPointIndex == -1) {
        return false;
      }
    }
    edgeBuffer.replace(edges,returnEdge);
  }
  if (testPoint != null && holes != null && holes.size() > 0) {
    final GeoPolygon testPolygon=new GeoConvexPolygon(planetModel,points,null,internalEdges,returnIsInternal);
    if (testPolygon.isWithin(testPoint)) {
      return null;
    }
  }
  final GeoPolygon realPolygon=new GeoConvexPolygon(planetModel,points,holes,internalEdges,returnIsInternal);
  if (testPoint != null && (holes == null || holes.size() == 0)) {
    if (realPolygon.isWithin(testPoint)) {
      return null;
    }
  }
  rval.addShape(realPolygon);
  return true;
}

private static Boolean findConvexPolygon ( final PlanetModel planetModel , final Edge currentEdge , final GeoCompositePolygon rval , final EdgeBuffer edgeBuffer , final List < GeoPolygon > holes , final GeoPoint testPoint ) { final Set < Edge > includedEdges = new HashSet < > ( ) ; includedEdges . add ( currentEdge ) ; Edge firstEdge = currentEdge ; Edge lastEdge = currentEdge ; while ( true ) { if ( firstEdge . startPoint == lastEdge . endPoint ) { break ; } final Edge newLastEdge = edgeBuffer . getNext ( lastEdge ) ; if ( isWithin ( newLastEdge . endPoint , includedEdges ) ) { final SidedPlane returnBoundary ; if ( firstEdge . startPoint != newLastEdge . endPoint ) { returnBoundary = new SidedPlane ( firstEdge . endPoint , firstEdge . startPoint , newLastEdge . endPoint ) ; } else { returnBoundary = null ; } boolean foundPointInside = false ; final Iterator < Edge > edgeIterator = edgeBuffer . iterator ( ) ; while ( edgeIterator . hasNext ( ) ) { final Edge edge = edgeIterator . next ( ) ; if ( ! includedEdges . contains ( edge ) && edge != newLastEdge ) { if ( edge . startPoint != newLastEdge . endPoint ) { if ( isWithin ( edge . startPoint , includedEdges , newLastEdge , returnBoundary ) ) { foundPointInside = true ; break ; } } if ( edge . endPoint != firstEdge . startPoint ) { if ( isWithin ( edge . endPoint , includedEdges , newLastEdge , returnBoundary ) ) { foundPointInside = true ; break ; } } } } if ( ! foundPointInside ) { includedEdges . add ( newLastEdge ) ; lastEdge = newLastEdge ; continue ; } } break ; } while ( true ) { if ( firstEdge . startPoint == lastEdge . endPoint ) { break ; } final Edge newFirstEdge = edgeBuffer . getPrevious ( firstEdge ) ; if ( isWithin ( newFirstEdge . startPoint , includedEdges ) ) { final SidedPlane returnBoundary ; if ( newFirstEdge . startPoint != lastEdge . endPoint ) { returnBoundary = new SidedPlane ( lastEdge . startPoint , lastEdge . endPoint , newFirstEdge . startPoint ) ; } else { returnBoundary = null ; } boolean foundPointInside = false ; final Iterator < Edge > edgeIterator = edgeBuffer . iterator ( ) ; while ( edgeIterator . hasNext ( ) ) { final Edge edge = edgeIterator . next ( ) ; if ( ! includedEdges . contains ( edge ) && edge != newFirstEdge ) { if ( edge . startPoint != lastEdge . endPoint ) { if ( isWithin ( edge . startPoint , includedEdges , newFirstEdge , returnBoundary ) ) { foundPointInside = true ; break ; } } if ( edge . endPoint != newFirstEdge . startPoint ) { if ( isWithin ( edge . endPoint , includedEdges , newFirstEdge , returnBoundary ) ) { foundPointInside = true ; break ; } } } } if ( ! foundPointInside ) { includedEdges . add ( newFirstEdge ) ; firstEdge = newFirstEdge ; continue ; } } break ; } if ( includedEdges . size ( ) < 2 ) { return false ; } final List < GeoPoint > points = new ArrayList < GeoPoint > ( includedEdges . size ( ) + 1 ) ; final BitSet internalEdges = new BitSet ( includedEdges . size ( ) ) ; final boolean returnIsInternal ; if ( firstEdge . startPoint == lastEdge . endPoint ) { if ( includedEdges . size ( ) < 3 ) { return false ; } Edge edge = firstEdge ; points . add ( edge . startPoint ) ; int k = 0 ; while ( true ) { if ( edge == lastEdge ) { break ; } points . add ( edge . endPoint ) ; internalEdges . set ( k ++ , edge . isInternal ) ; edge = edgeBuffer . getNext ( edge ) ; } returnIsInternal = lastEdge . isInternal ; for ( int i = 0 ; i < points . size ( ) ; i ++ ) { final GeoPoint start = points . get ( i ) ; final GeoPoint end = points . get ( getLegalIndex ( i + 1 , points . size ( ) ) ) ; final Plane planeToFind = new Plane ( start , end ) ; int endPointIndex = - 1 ; for ( int j = 0 ; j < points . size ( ) ; j ++ ) { final int index = getLegalIndex ( j + i + 2 , points . size ( ) ) ; if ( ! planeToFind . evaluateIsZero ( points . get ( index ) ) ) { endPointIndex = index ; break ; } } if ( endPointIndex == - 1 ) { return false ; } } edgeBuffer . clear ( ) ; } else { final SidedPlane returnSidedPlane = new SidedPlane ( firstEdge . endPoint , false , firstEdge . startPoint , lastEdge . endPoint ) ; final Edge returnEdge = new Edge ( firstEdge . startPoint , lastEdge . endPoint , returnSidedPlane , true ) ; final List < Edge > edges = new ArrayList < Edge > ( includedEdges . size ( ) ) ; returnIsInternal = true ; Edge edge = firstEdge ; points . add ( edge . startPoint ) ; int k = 0 ; while ( true ) { points . add ( edge . endPoint ) ; internalEdges . set ( k ++ , edge . isInternal ) ; edges . add ( edge ) ; if ( edge == lastEdge ) { break ; } edge = edgeBuffer . getNext ( edge ) ; } for ( int i = 0 ; i < points . size ( ) ; i ++ ) { final GeoPoint start = points . get ( i ) ; final GeoPoint end = points . get ( getLegalIndex ( i + 1 , points . size ( ) ) ) ; final Plane planeToFind = new Plane ( start , end ) ; int endPointIndex = - 1 ; for ( int j = 0 ; j < points . size ( ) ; j ++ ) { final int index = getLegalIndex ( j + i + 2 , points . size ( ) ) ; if ( ! planeToFind . evaluateIsZero ( points . get ( index ) ) ) { endPointIndex = index ; break ; } } if ( endPointIndex == - 1 ) { return false ; } } edgeBuffer . replace ( edges , returnEdge ) ; } if ( testPoint != null && holes != null && holes . size ( ) > 0 ) { final GeoPolygon testPolygon = new GeoConvexPolygon ( planetModel , points , null , internalEdges , returnIsInternal ) ; if ( testPolygon . isWithin ( testPoint ) ) { return null ; } } final GeoPolygon realPolygon = new GeoConvexPolygon ( planetModel , points , holes , internalEdges , returnIsInternal ) ; if ( testPoint != null && ( holes == null || holes . size ( ) == 0 ) ) { if ( realPolygon . isWithin ( testPoint ) ) { return null ; } } rval . addShape ( realPolygon ) ; return true ; }
look for a convex polygon at the specified edge . if we find it , create one and adjust the edge buffer .
