Search in sources :

Example 86 with BitSet

use of java.util.BitSet in project lucene-solr by apache.

the class GeoPolygonFactory method makeConcavePolygon.

/** Look for a concave polygon in the remainder of the edgebuffer.
   * By this point, if there are any edges in the edgebuffer, they represent a concave polygon.
   * @param planetModel is the planet model.
   * @param rval is the composite polygon we're building.
   * @param seenConcave is true if we've already seen a concave polygon.
   * @param edgeBuffer is the edge buffer.
   * @param holes is the optional list of holes.
   * @param testPoint is the optional test point.
   * @return true unless the testPoint caused failure.
   */
private static boolean makeConcavePolygon(final PlanetModel planetModel, final GeoCompositePolygon rval, final MutableBoolean seenConcave, final EdgeBuffer edgeBuffer, final List<GeoPolygon> holes, final GeoPoint testPoint) {
    if (edgeBuffer.size() == 0) {
        return true;
    }
    if (seenConcave.value) {
        throw new IllegalArgumentException("Illegal polygon; polygon edges intersect each other");
    }
    seenConcave.value = true;
    // can happen but check.
    if (edgeBuffer.size() < 3) {
        // Here we can emit GeoWorld, but probably this means we had a broken poly to start with.
        throw new IllegalArgumentException("Illegal polygon; polygon edges intersect each other");
    }
    // Create the list of points
    final List<GeoPoint> points = new ArrayList<GeoPoint>(edgeBuffer.size());
    final BitSet internalEdges = new BitSet(edgeBuffer.size() - 1);
    //System.out.println("Concave polygon points:");
    Edge edge = edgeBuffer.pickOne();
    boolean isInternal = false;
    for (int i = 0; i < edgeBuffer.size(); i++) {
        //System.out.println(" "+edge.plane+": "+edge.startPoint+"->"+edge.endPoint+"; previous? "+(edge.plane.isWithin(edgeBuffer.getPrevious(edge).startPoint)?"in":"out")+" next? "+(edge.plane.isWithin(edgeBuffer.getNext(edge).endPoint)?"in":"out"));
        points.add(edge.startPoint);
        if (i < edgeBuffer.size() - 1) {
            internalEdges.set(i, edge.isInternal);
        } else {
            isInternal = edge.isInternal;
        }
        edge = edgeBuffer.getNext(edge);
    }
    if (testPoint != null && holes != null && holes.size() > 0) {
        // No holes, for test
        final GeoPolygon testPolygon = new GeoConcavePolygon(planetModel, points, null, internalEdges, isInternal);
        if (testPolygon.isWithin(testPoint)) {
            return false;
        }
    }
    final GeoPolygon realPolygon = new GeoConcavePolygon(planetModel, points, holes, internalEdges, isInternal);
    if (testPoint != null && (holes == null || holes.size() == 0)) {
        if (realPolygon.isWithin(testPoint)) {
            return false;
        }
    }
    rval.addShape(realPolygon);
    return true;
}
Also used : ArrayList(java.util.ArrayList) BitSet(java.util.BitSet)

Example 87 with BitSet

use of java.util.BitSet in project lucene-solr by apache.

the class GeoPolygonFactory method findConvexPolygon.

/** Look for a convex polygon at the specified edge.  If we find it, create one and adjust the edge buffer.
   * @param planetModel is the planet model.
   * @param currentEdge is the current edge to use starting the search.
   * @param rval is the composite polygon to build.
   * @param edgeBuffer is the edge buffer.
   * @param holes is the optional list of holes.
   * @param testPoint is the optional test point.
   * @return null if the testPoint is within any polygon detected, otherwise true if a convex polygon was created.
   */
private static Boolean findConvexPolygon(final PlanetModel planetModel, final Edge currentEdge, final GeoCompositePolygon rval, final EdgeBuffer edgeBuffer, final List<GeoPolygon> holes, final GeoPoint testPoint) {
    //System.out.println("Looking at edge "+currentEdge+" with startpoint "+currentEdge.startPoint+" endpoint "+currentEdge.endPoint);
    // Initialize the structure.
    // We don't keep track of order here; we just care about membership.
    // The only exception is the head and tail pointers.
    final Set<Edge> includedEdges = new HashSet<>();
    includedEdges.add(currentEdge);
    Edge firstEdge = currentEdge;
    Edge lastEdge = currentEdge;
    // First, walk towards the end until we need to stop
    while (true) {
        if (firstEdge.startPoint == lastEdge.endPoint) {
            break;
        }
        final Edge newLastEdge = edgeBuffer.getNext(lastEdge);
        if (isWithin(newLastEdge.endPoint, includedEdges)) {
            //System.out.println(" maybe can extend to next edge");
            // Found a candidate for extension.  But do some other checks first.  Basically, we need to know if we construct a polygon
            // here will overlap with other remaining points?
            final SidedPlane returnBoundary;
            if (firstEdge.startPoint != newLastEdge.endPoint) {
                returnBoundary = new SidedPlane(firstEdge.endPoint, firstEdge.startPoint, newLastEdge.endPoint);
            } else {
                returnBoundary = null;
            }
            // The complete set of sided planes for the tentative new polygon include the ones in includedEdges, plus the one from newLastEdge,
            // plus the new tentative return boundary.  We have to make sure there are no points from elsewhere within the tentative convex polygon.
            boolean foundPointInside = false;
            final Iterator<Edge> edgeIterator = edgeBuffer.iterator();
            while (edgeIterator.hasNext()) {
                final Edge edge = edgeIterator.next();
                if (!includedEdges.contains(edge) && edge != newLastEdge) {
                    // This edge has a point to check
                    if (edge.startPoint != newLastEdge.endPoint) {
                        // look at edge.startPoint
                        if (isWithin(edge.startPoint, includedEdges, newLastEdge, returnBoundary)) {
                            //System.out.println("  nope; point within found: "+edge.startPoint);
                            foundPointInside = true;
                            break;
                        }
                    }
                    if (edge.endPoint != firstEdge.startPoint) {
                        // look at edge.endPoint
                        if (isWithin(edge.endPoint, includedEdges, newLastEdge, returnBoundary)) {
                            //System.out.println("  nope; point within found: "+edge.endPoint);
                            foundPointInside = true;
                            break;
                        }
                    }
                }
            }
            if (!foundPointInside) {
                //System.out.println("  extending!");
                // Extend the polygon by the new last edge
                includedEdges.add(newLastEdge);
                lastEdge = newLastEdge;
                // continue extending in this direction
                continue;
            }
        }
        // We can't extend any more in this direction, so break from the loop.
        break;
    }
    // Now, walk towards the beginning until we need to stop
    while (true) {
        if (firstEdge.startPoint == lastEdge.endPoint) {
            break;
        }
        final Edge newFirstEdge = edgeBuffer.getPrevious(firstEdge);
        if (isWithin(newFirstEdge.startPoint, includedEdges)) {
            //System.out.println(" maybe can extend to previous edge");
            // Found a candidate for extension.  But do some other checks first.  Basically, we need to know if we construct a polygon
            // here will overlap with other remaining points?
            final SidedPlane returnBoundary;
            if (newFirstEdge.startPoint != lastEdge.endPoint) {
                returnBoundary = new SidedPlane(lastEdge.startPoint, lastEdge.endPoint, newFirstEdge.startPoint);
            } else {
                returnBoundary = null;
            }
            // The complete set of sided planes for the tentative new polygon include the ones in includedEdges, plus the one from newLastEdge,
            // plus the new tentative return boundary.  We have to make sure there are no points from elsewhere within the tentative convex polygon.
            boolean foundPointInside = false;
            final Iterator<Edge> edgeIterator = edgeBuffer.iterator();
            while (edgeIterator.hasNext()) {
                final Edge edge = edgeIterator.next();
                if (!includedEdges.contains(edge) && edge != newFirstEdge) {
                    // This edge has a point to check
                    if (edge.startPoint != lastEdge.endPoint) {
                        // look at edge.startPoint
                        if (isWithin(edge.startPoint, includedEdges, newFirstEdge, returnBoundary)) {
                            //System.out.println("  nope; point within found: "+edge.startPoint);
                            foundPointInside = true;
                            break;
                        }
                    }
                    if (edge.endPoint != newFirstEdge.startPoint) {
                        // look at edge.endPoint
                        if (isWithin(edge.endPoint, includedEdges, newFirstEdge, returnBoundary)) {
                            //System.out.println("  nope; point within found: "+edge.endPoint);
                            foundPointInside = true;
                            break;
                        }
                    }
                }
            }
            if (!foundPointInside) {
                //System.out.println("  extending!");
                // Extend the polygon by the new last edge
                includedEdges.add(newFirstEdge);
                firstEdge = newFirstEdge;
                // continue extending in this direction
                continue;
            }
        }
        // We can't extend any more in this direction, so break from the loop.
        break;
    }
    if (includedEdges.size() < 2) {
        //System.out.println("Done edge "+currentEdge+": no poly found");
        return false;
    }
    // It's enough to build a convex polygon
    //System.out.println("Edge "+currentEdge+": Found complex poly");
    // Create the point list and edge list, starting with the first edge and going to the last.  The return edge will be between
    // the start point of the first edge and the end point of the last edge.  If the first edge start point is the same as the last edge end point,
    // it's a degenerate case and we want to just clean out the edge buffer entirely.
    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) {
        // Degenerate case!!  There is no return edge -- or rather, we already have it.
        if (includedEdges.size() < 3) {
            // has no contents, so we generate no polygon.
            return false;
        }
        // Now look for completely planar points.  This too is a degeneracy condition that we should
        // return "false" for.
        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;
        // Look for coplanarity; abort if so
        for (int i = 0; i < points.size(); i++) {
            final GeoPoint start = points.get(i);
            final GeoPoint end = points.get(getLegalIndex(i + 1, points.size()));
            // We have to find the next point that is not on the plane between start and end.
            // If there is no such point, it's an error.
            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 {
        // Build the return edge (internal, of course)
        final SidedPlane returnSidedPlane = new SidedPlane(firstEdge.endPoint, false, firstEdge.startPoint, lastEdge.endPoint);
        final Edge returnEdge = new Edge(firstEdge.startPoint, lastEdge.endPoint, returnSidedPlane, true);
        // Build point list and edge list
        final List<Edge> edges = new ArrayList<Edge>(includedEdges.size());
        returnIsInternal = true;
        // Now look for completely planar points.  This too is a degeneracy condition that we should
        // return "false" for.
        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);
        }
        // Look for coplanarity; abort if so
        for (int i = 0; i < points.size(); i++) {
            final GeoPoint start = points.get(i);
            final GeoPoint end = points.get(getLegalIndex(i + 1, points.size()));
            // We have to find the next point that is not on the plane between start and end.
            // If there is no such point, it's an error.
            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;
            }
        }
        // Modify the edge buffer
        edgeBuffer.replace(edges, returnEdge);
    }
    // Now, construct the polygon
    if (testPoint != null && holes != null && holes.size() > 0) {
        // No holes, for test
        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;
}
Also used : ArrayList(java.util.ArrayList) BitSet(java.util.BitSet) HashSet(java.util.HashSet)

Example 88 with BitSet

use of java.util.BitSet in project lucene-solr by apache.

the class GeoPolygonFactory method generateGeoPolygon.

/**
   * Create a GeoPolygon using the specified points and holes and a test point.
   *
   * @param filteredPointList is a filtered list of the GeoPoints to build an arbitrary polygon out of.
   * @param holes is a list of polygons representing "holes" in the outside polygon.  Null == none.
   * @param testPoint is a test point that is either known to be within the polygon area, or not.
   * @param testPointInside is true if the test point is within the area, false otherwise.
   * @return a GeoPolygon corresponding to what was specified, or null if what was specified
   *  cannot be turned into a valid non-degenerate polygon.
   */
static GeoPolygon generateGeoPolygon(final PlanetModel planetModel, final List<GeoPoint> filteredPointList, final List<GeoPolygon> holes, final GeoPoint testPoint, final boolean testPointInside) {
    // We will be trying twice to find the right GeoPolygon, using alternate siding choices for the first polygon
    // side.  While this looks like it might be 2x as expensive as it could be, there's really no other choice I can
    // find.
    final SidedPlane initialPlane = new SidedPlane(testPoint, filteredPointList.get(0), filteredPointList.get(1));
    // We don't know if this is the correct siding choice.  We will only know as we build the complex polygon.
    // So we need to be prepared to try both possibilities.
    GeoCompositePolygon rval = new GeoCompositePolygon();
    MutableBoolean seenConcave = new MutableBoolean();
    if (buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, initialPlane, holes, testPoint) == false) {
        // The testPoint was within the shape.  Was that intended?
        if (testPointInside) {
            // Yes: build it for real
            rval = new GeoCompositePolygon();
            seenConcave = new MutableBoolean();
            buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, initialPlane, holes, null);
            return rval;
        }
        // No: do the complement and return that.
        rval = new GeoCompositePolygon();
        seenConcave = new MutableBoolean();
        buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, new SidedPlane(initialPlane), holes, null);
        return rval;
    } else {
        // The testPoint was outside the shape.  Was that intended?
        if (!testPointInside) {
            // Yes: return what we just built
            return rval;
        }
        // No: return the complement
        rval = new GeoCompositePolygon();
        seenConcave = new MutableBoolean();
        buildPolygonShape(rval, seenConcave, planetModel, filteredPointList, new BitSet(), 0, 1, new SidedPlane(initialPlane), holes, null);
        return rval;
    }
}
Also used : BitSet(java.util.BitSet)

Example 89 with BitSet

use of java.util.BitSet in project lucene-solr by apache.

the class GeoPolygonFactory method buildPolygonShape.

/** Build a GeoPolygon out of one concave part and multiple convex parts given points, starting edge, and whether starting edge is internal or not.
   * @param rval is the composite polygon to add to.
   * @param seenConcave is true if a concave polygon has been seen in this generation yet.
   * @param planetModel is the planet model.
   * @param pointsList is a list of the GeoPoints to build an arbitrary polygon out of.
   * @param internalEdges specifies which edges are internal.
   * @param startPointIndex is the first of the points, constituting the starting edge.
   * @param startingEdge is the plane describing the starting edge.
   * @param holes is the list of holes in the polygon, or null if none.
   * @param testPoint is an (optional) test point, which will be used to determine if we are generating
   *  a shape with the proper sidedness.  It is passed in only when the test point is supposed to be outside
   *  of the generated polygon.  In this case, if the generated polygon is found to contain the point, the
   *  method exits early with a null return value.
   *  This only makes sense in the context of evaluating both possible choices and using logic to determine
   *  which result to use.  If the test point is supposed to be within the shape, then it must be outside of the
   *  complement shape.  If the test point is supposed to be outside the shape, then it must be outside of the
   *  original shape.  Either way, we can figure out the right thing to use.
   * @return false if what was specified
   *  was inconsistent with what we generated.  Specifically, if we specify an exterior point that is
   *  found in the interior of the shape we create here we return false, which is a signal that we chose
   *  our initial plane sidedness backwards.
   */
static boolean buildPolygonShape(final GeoCompositePolygon rval, final MutableBoolean seenConcave, final PlanetModel planetModel, final List<GeoPoint> pointsList, final BitSet internalEdges, final int startPointIndex, final int endPointIndex, final SidedPlane startingEdge, final List<GeoPolygon> holes, final GeoPoint testPoint) {
    // It could be the case that we need a concave polygon.  So we need to try and look for that case
    // as part of the general code for constructing complex polygons.
    // Note that there can be only one concave polygon.  This code will enforce that condition and will return
    // false if it is violated.
    // The code here must keep track of two lists of sided planes.  The first list contains the planes consistent with
    // a concave polygon.  This list will grow and shrink.  The second list is built starting at the current edge that
    // was last consistent with the concave polygon, and contains all edges consistent with a convex polygon.
    // When that sequence of edges is done, then an internal edge is created and the identified points are converted to a
    // convex polygon.  That internal edge is used to extend the list of edges in the concave polygon edge list.
    // The edge buffer.
    final EdgeBuffer edgeBuffer = new EdgeBuffer(pointsList, internalEdges, startPointIndex, endPointIndex, startingEdge);
    /*
    // Verify that the polygon does not self-intersect
    // Now, look for non-adjacent edges that cross.
    System.err.println("Looking for intersections...");
    System.err.println("Starting edge is: "+startingEdge);
    final Iterator<Edge> edgeIterator = edgeBuffer.iterator();
    while (edgeIterator.hasNext()) {
      final Edge edge = edgeIterator.next();
      final Set<Edge> excludedEdges = new HashSet<>();
      excludedEdges.add(edge);
      Edge oneBoundary = edgeBuffer.getPrevious(edge);
      while (oneBoundary.plane.isNumericallyIdentical(edge.plane)) {
        excludedEdges.add(oneBoundary);
        oneBoundary = edgeBuffer.getPrevious(oneBoundary);
      }
      excludedEdges.add(oneBoundary);
      Edge otherBoundary = edgeBuffer.getNext(edge);
      while (otherBoundary.plane.isNumericallyIdentical(edge.plane)) {
        excludedEdges.add(otherBoundary);
        otherBoundary = edgeBuffer.getNext(otherBoundary);
      }
      excludedEdges.add(otherBoundary);

      // Now go through all other edges and rule out any intersections
      final Iterator<Edge> compareIterator = edgeBuffer.iterator();
      while (compareIterator.hasNext()) {
        final Edge compareEdge = compareIterator.next();
        if (!excludedEdges.contains(compareEdge)) {
          // Found an edge we can compare with!
          //System.err.println("Found a compare edge...");
          boolean nonOverlapping = true;
          // We need the other boundaries though.
          Edge oneCompareBoundary = edgeBuffer.getPrevious(compareEdge);
          while (oneCompareBoundary.plane.isNumericallyIdentical(compareEdge.plane)) {
            if (excludedEdges.contains(oneCompareBoundary)) {
              //System.err.println(" excluded because oneCompareBoundary found to be in set");
              nonOverlapping = false;
              break;
            }
            oneCompareBoundary = edgeBuffer.getPrevious(oneCompareBoundary);
          }
          Edge otherCompareBoundary = edgeBuffer.getNext(compareEdge);
          while (otherCompareBoundary.plane.isNumericallyIdentical(compareEdge.plane)) {
            if (excludedEdges.contains(otherCompareBoundary)) {
              //System.err.println(" excluded because otherCompareBoundary found to be in set");
              nonOverlapping = false;
              break;
            }
            otherCompareBoundary = edgeBuffer.getNext(otherCompareBoundary);
          }
          if (nonOverlapping) {
            //System.err.println("Preparing to call findIntersections...");
            // Finally do an intersection test
            if (edge.plane.findIntersections(planetModel, compareEdge.plane, oneBoundary.plane, otherBoundary.plane, oneCompareBoundary.plane, otherCompareBoundary.plane).length > 0) {
              throw new IllegalArgumentException("polygon has intersecting edges");
            }
          }
        }
      }
    }
    */
    // Starting state:
    // The stopping point
    Edge stoppingPoint = edgeBuffer.pickOne();
    // The current edge
    Edge currentEdge = stoppingPoint;
    // do the concave polygon, if necessary.
    while (true) {
        if (currentEdge == null) {
            // We're done!
            break;
        }
        // Find convexity around the current edge, if any
        final Boolean foundIt = findConvexPolygon(planetModel, currentEdge, rval, edgeBuffer, holes, testPoint);
        if (foundIt == null) {
            return false;
        }
        if (foundIt) {
            // New start point
            stoppingPoint = edgeBuffer.pickOne();
            currentEdge = stoppingPoint;
            // back around
            continue;
        }
        // Otherwise, go on to the next
        currentEdge = edgeBuffer.getNext(currentEdge);
        if (currentEdge == stoppingPoint) {
            break;
        }
    }
    // Look for any reason that the concave polygon cannot be created.
    // This test is really the converse of the one for a convex polygon.
    // Points on the edge of a convex polygon MUST be inside all the other
    // edges.  For a concave polygon, this check is still the same, except we have
    // to look at the reverse sided planes, not the forward ones.
    // If we find a point that is outside of the complementary edges, it means that
    // the point is in fact able to form a convex polygon with the edge it is
    // offending. 
    // If what is left has any plane/point pair that is on the wrong side, we have to split using one of the plane endpoints and the 
    // point in question.  This is best structured as a recursion, if detected.
    final Iterator<Edge> checkIterator = edgeBuffer.iterator();
    while (checkIterator.hasNext()) {
        final Edge checkEdge = checkIterator.next();
        final SidedPlane flippedPlane = new SidedPlane(checkEdge.plane);
        // Now walk around again looking for points that fail
        final Iterator<Edge> confirmIterator = edgeBuffer.iterator();
        while (confirmIterator.hasNext()) {
            final Edge confirmEdge = confirmIterator.next();
            if (confirmEdge == checkEdge) {
                continue;
            }
            // Look for a point that is on the wrong side of the check edge.  This means that we can't build the polygon.
            final GeoPoint thePoint;
            if (checkEdge.startPoint != confirmEdge.startPoint && checkEdge.endPoint != confirmEdge.startPoint && !flippedPlane.isWithin(confirmEdge.startPoint)) {
                thePoint = confirmEdge.startPoint;
            } else if (checkEdge.startPoint != confirmEdge.endPoint && checkEdge.endPoint != confirmEdge.endPoint && !flippedPlane.isWithin(confirmEdge.endPoint)) {
                thePoint = confirmEdge.endPoint;
            } else {
                thePoint = null;
            }
            if (thePoint != null) {
                // thePoint is on the wrong side of the complementary plane.  That means we cannot build a concave polygon, because the complement would not
                // be a legal convex polygon.
                // But we can take advantage of the fact that the distance between the edge and thePoint is less than 180 degrees, and so we can split the
                // would-be concave polygon into three segments.  The first segment includes the edge and thePoint, and uses the sense of the edge to determine the sense
                // of the polygon.
                // This should be the only problematic part of the polygon.
                // We know that thePoint is on the "wrong" side of the edge -- that is, it's on the side that the
                // edge is pointing at.
                final List<GeoPoint> thirdPartPoints = new ArrayList<>(3);
                final BitSet thirdPartInternal = new BitSet();
                thirdPartPoints.add(checkEdge.startPoint);
                thirdPartInternal.set(0, checkEdge.isInternal);
                thirdPartPoints.add(checkEdge.endPoint);
                thirdPartInternal.set(1, true);
                thirdPartPoints.add(thePoint);
                assert checkEdge.plane.isWithin(thePoint) : "Point was on wrong side of complementary plane, so must be on the right side of the non-complementary plane!";
                final GeoPolygon convexPart = new GeoConvexPolygon(planetModel, thirdPartPoints, holes, thirdPartInternal, true);
                //System.out.println("convex part = "+convexPart);
                rval.addShape(convexPart);
                // The part preceding the bad edge, back to thePoint, needs to be recursively
                // processed.  So, assemble what we need, which is basically a list of edges.
                Edge loopEdge = edgeBuffer.getPrevious(checkEdge);
                final List<GeoPoint> firstPartPoints = new ArrayList<>();
                final BitSet firstPartInternal = new BitSet();
                int i = 0;
                while (true) {
                    firstPartPoints.add(loopEdge.endPoint);
                    if (loopEdge.endPoint == thePoint) {
                        break;
                    }
                    firstPartInternal.set(i++, loopEdge.isInternal);
                    loopEdge = edgeBuffer.getPrevious(loopEdge);
                }
                firstPartInternal.set(i, true);
                //System.out.println("Doing first part...");
                if (buildPolygonShape(rval, seenConcave, planetModel, firstPartPoints, firstPartInternal, firstPartPoints.size() - 1, 0, new SidedPlane(checkEdge.endPoint, false, checkEdge.startPoint, thePoint), holes, testPoint) == false) {
                    return false;
                }
                //System.out.println("...done first part.");
                final List<GeoPoint> secondPartPoints = new ArrayList<>();
                final BitSet secondPartInternal = new BitSet();
                loopEdge = edgeBuffer.getNext(checkEdge);
                i = 0;
                while (true) {
                    secondPartPoints.add(loopEdge.startPoint);
                    if (loopEdge.startPoint == thePoint) {
                        break;
                    }
                    secondPartInternal.set(i++, loopEdge.isInternal);
                    loopEdge = edgeBuffer.getNext(loopEdge);
                }
                secondPartInternal.set(i, true);
                //System.out.println("Doing second part...");
                if (buildPolygonShape(rval, seenConcave, planetModel, secondPartPoints, secondPartInternal, secondPartPoints.size() - 1, 0, new SidedPlane(checkEdge.startPoint, false, checkEdge.endPoint, thePoint), holes, testPoint) == false) {
                    return false;
                }
                return true;
            }
        }
    }
    //System.out.println("adding concave part");
    if (makeConcavePolygon(planetModel, rval, seenConcave, edgeBuffer, holes, testPoint) == false) {
        return false;
    }
    return true;
}
Also used : ArrayList(java.util.ArrayList) BitSet(java.util.BitSet)

Example 90 with BitSet

use of java.util.BitSet in project lucene-solr by apache.

the class GeoPolygonTest method testPolygonFactoryCase3.

@Test
public void testPolygonFactoryCase3() {
    /*
    This one failed to be detected as convex:

   [junit4]   1> convex part = GeoConvexPolygon: {planetmodel=PlanetModel.WGS84, points=
   [[lat=0.39346633764155237, lon=1.306697331415816([X=0.24124272064589647, Y=0.8921189226448045, Z=0.3836311592666308])], 
   [lat=-0.4252164254406539, lon=-1.0929282311747601([X=0.41916238097763436, Y=-0.8093435958043177, Z=-0.4127428785664968])], 
   [lat=0.4654236264787552, lon=1.3013260557429494([X=0.2380080413677112, Y=0.8617612419312584, Z=0.4489988990508502])]], internalEdges={0, 1, 2}}
    */
    final GeoPoint p3 = new GeoPoint(PlanetModel.WGS84, 0.39346633764155237, 1.306697331415816);
    final GeoPoint p2 = new GeoPoint(PlanetModel.WGS84, -0.4252164254406539, -1.0929282311747601);
    final GeoPoint p1 = new GeoPoint(PlanetModel.WGS84, 0.4654236264787552, 1.3013260557429494);
    final List<GeoPoint> points = new ArrayList<>();
    points.add(p3);
    points.add(p2);
    points.add(p1);
    final BitSet internal = new BitSet();
    final GeoCompositePolygon rval = new GeoCompositePolygon();
    final GeoPolygonFactory.MutableBoolean mutableBoolean = new GeoPolygonFactory.MutableBoolean();
    boolean result = GeoPolygonFactory.buildPolygonShape(rval, mutableBoolean, PlanetModel.WGS84, points, internal, 0, 1, new SidedPlane(p1, p3, p2), new ArrayList<GeoPolygon>(), null);
    assertFalse(mutableBoolean.value);
}
Also used : ArrayList(java.util.ArrayList) BitSet(java.util.BitSet) Test(org.junit.Test)

Aggregations

BitSet (java.util.BitSet)2037 Test (org.junit.Test)294 ArrayList (java.util.ArrayList)224 List (java.util.List)83 HashMap (java.util.HashMap)76 Map (java.util.Map)70 IOException (java.io.IOException)60 HashSet (java.util.HashSet)52 Test (org.junit.jupiter.api.Test)47 RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)45 Random (java.util.Random)42 Configuration (org.apache.hadoop.conf.Configuration)40 Path (org.apache.hadoop.fs.Path)39 ValidReadTxnList (org.apache.hadoop.hive.common.ValidReadTxnList)33 BlockNode (jadx.core.dex.nodes.BlockNode)29 File (java.io.File)27 LinkedList (java.util.LinkedList)27 RexNode (org.apache.calcite.rex.RexNode)27 ByteBuffer (java.nio.ByteBuffer)25 ValidReaderWriteIdList (org.apache.hadoop.hive.common.ValidReaderWriteIdList)25