protected void makeTessellatedLocations(
      Globe globe, int subdivisions, List<LatLon> locations, List<LatLon> tessellatedLocations) {
    ArrayList<Vec4> points = new ArrayList<Vec4>();
    for (LatLon ll : locations) {
      points.add(globe.computePointFromLocation(ll));
    }

    //noinspection StringEquality
    if (WWMath.computeWindingOrderOfLocations(locations) != AVKey.COUNTER_CLOCKWISE)
      Collections.reverse(locations);

    Vec4 centerPoint = Vec4.computeAveragePoint(points);
    Vec4 surfaceNormal = globe.computeSurfaceNormalAtPoint(centerPoint);

    int numPoints = points.size();
    float[] coords = new float[3 * numPoints];
    for (int i = 0; i < numPoints; i++) {
      points.get(i).toFloatArray(coords, 3 * i, 3);
    }

    GeometryBuilder gb = new GeometryBuilder();
    GeometryBuilder.IndexedTriangleArray tessellatedPoints =
        gb.tessellatePolygon(0, numPoints, coords, surfaceNormal);

    for (int i = 0; i < subdivisions; i++) {
      gb.subdivideIndexedTriangleArray(tessellatedPoints);
    }

    for (int i = 0; i < tessellatedPoints.getVertexCount(); i++) {
      Vec4 v = Vec4.fromFloatArray(tessellatedPoints.getVertices(), 3 * i, 3);
      tessellatedLocations.add(globe.computePositionFromPoint(v));
    }
  }
Beispiel #2
0
  /**
   * Computes a <code>Box</code> that bounds a specified buffer of points. Principal axes are
   * computed for the points and used to form a <code>Box</code>. This returns <code>null</code> if
   * the buffer is empty or contains only a partial point.
   *
   * <p>The buffer must contain XYZ coordinate tuples which are either tightly packed or offset by
   * the specified stride. The stride specifies the number of buffer elements between the first
   * coordinate of consecutive tuples. For example, a stride of 3 specifies that each tuple is
   * tightly packed as XYZXYZXYZ, whereas a stride of 5 specifies that there are two elements
   * between each tuple as XYZabXYZab (the elements "a" and "b" are ignored). The stride must be at
   * least 3. If the buffer's length is not evenly divisible into stride-sized tuples, this ignores
   * the remaining elements that follow the last complete tuple.
   *
   * @param buffer the buffer containing the point coordinates for which to compute a bounding
   *     volume.
   * @param stride the number of elements between the first coordinate of consecutive points. If
   *     stride is 3, this interprets the buffer has having tightly packed XYZ coordinate tuples.
   * @return the bounding volume, with axes lengths consistent with the conventions described in the
   *     <code>Box</code> class overview.
   * @throws IllegalArgumentException if the buffer is null or empty, or if the stride is less than
   *     three.
   */
  public static Box computeBoundingBox(FloatBuffer buffer, int stride) {
    if (buffer == null) {
      String msg = Logging.getMessage("nullValue.BufferIsNull");
      Logging.error(msg);
      throw new IllegalArgumentException(msg);
    }

    if (stride < 3) {
      String msg = Logging.getMessage("generic.StrideIsInvalid", stride);
      Logging.error(msg);
      throw new IllegalArgumentException(msg);
    }

    Vec4[] axes = WWMath.computePrincipalAxes(buffer, stride);
    if (axes == null) {
      String msg = Logging.getMessage("generic.BufferIsEmpty");
      Logging.error(msg);
      throw new IllegalArgumentException(msg);
    }

    Vec4 r = axes[0];
    Vec4 s = axes[1];
    Vec4 t = axes[2];

    // Find the extremes along each axis.
    double minDotR = Double.MAX_VALUE;
    double maxDotR = -minDotR;
    double minDotS = Double.MAX_VALUE;
    double maxDotS = -minDotS;
    double minDotT = Double.MAX_VALUE;
    double maxDotT = -minDotT;

    for (int i = buffer.position(); i <= buffer.limit() - stride; i += stride) {
      double x = buffer.get(i);
      double y = buffer.get(i + 1);
      double z = buffer.get(i + 2);

      double pdr = x * r.x + y * r.y + z * r.z;
      if (pdr < minDotR) minDotR = pdr;
      if (pdr > maxDotR) maxDotR = pdr;

      double pds = x * s.x + y * s.y + z * s.z;
      if (pds < minDotS) minDotS = pds;
      if (pds > maxDotS) maxDotS = pds;

      double pdt = x * t.x + y * t.y + z * t.z;
      if (pdt < minDotT) minDotT = pdt;
      if (pdt > maxDotT) maxDotT = pdt;
    }

    if (maxDotR == minDotR) maxDotR = minDotR + 1;
    if (maxDotS == minDotS) maxDotS = minDotS + 1;
    if (maxDotT == minDotT) maxDotT = minDotT + 1;

    return new Box(axes, minDotR, maxDotR, minDotS, maxDotS, minDotT, maxDotT);
  }
    public AppFrame() {
      super(true, true, false);

      // Create list of positions along the control line.
      List<Position> positions =
          Arrays.asList(
              Position.fromDegrees(49.0457, -122.8115, 100),
              Position.fromDegrees(49.0539, -122.8091, 110),
              Position.fromDegrees(49.0621, -122.7937, 120),
              Position.fromDegrees(49.0681, -122.8044, 130),
              Position.fromDegrees(49.0682, -122.7730, 140),
              Position.fromDegrees(49.0482, -122.7764, 150),
              Position.fromDegrees(49.0498, -122.7466, 140),
              Position.fromDegrees(49.0389, -122.7453, 130),
              Position.fromDegrees(49.0321, -122.7759, 120),
              Position.fromDegrees(49.0394, -122.7689, 110),
              Position.fromDegrees(49.0629, -122.7666, 100));

      // We will generate four paths parallel to the control path. Allocate lists to store the
      // positions of these
      // paths.
      List<Position> pathPositions1 = new ArrayList<Position>();
      List<Position> pathPositions2 = new ArrayList<Position>();
      List<Position> pathPositions3 = new ArrayList<Position>();
      List<Position> pathPositions4 = new ArrayList<Position>();

      Globe globe = getWwd().getModel().getGlobe();

      // Generate two sets of lines parallel to the control line. The positions will be added to the
      // pathPosition lists.
      WWMath.generateParallelLines(positions, pathPositions1, pathPositions2, 50, globe);
      WWMath.generateParallelLines(positions, pathPositions3, pathPositions4, 100, globe);

      // Create Path objects from the position lists, and add them to a layer.
      RenderableLayer layer = new RenderableLayer();
      this.addPath(layer, positions, "Control Path");
      this.addPath(layer, pathPositions1, "Path 1");
      this.addPath(layer, pathPositions2, "Path 2");
      this.addPath(layer, pathPositions3, "Path 3");
      this.addPath(layer, pathPositions4, "Path 4");

      insertBeforePlacenames(getWwd(), layer);
    }
Beispiel #4
0
  /**
   * Compute a <code>Box</code> that bounds a specified list of points. Principal axes are computed
   * for the points and used to form a <code>Box</code>.
   *
   * @param points the points for which to compute a bounding volume.
   * @return the bounding volume, with axes lengths consistent with the conventions described in the
   *     overview.
   * @throws IllegalArgumentException if the point list is null or empty.
   */
  public static Box computeBoundingBox(Iterable<? extends Vec4> points) {
    if (points == null) {
      String msg = Logging.getMessage("nullValue.PointListIsNull");
      Logging.error(msg);
      throw new IllegalArgumentException(msg);
    }

    Vec4[] axes = WWMath.computePrincipalAxes(points);
    if (axes == null) {
      String msg = Logging.getMessage("generic.PointListIsEmpty");
      Logging.error(msg);
      throw new IllegalArgumentException(msg);
    }

    Vec4 r = axes[0];
    Vec4 s = axes[1];
    Vec4 t = axes[2];

    // Find the extremes along each axis.
    double minDotR = Double.MAX_VALUE;
    double maxDotR = -minDotR;
    double minDotS = Double.MAX_VALUE;
    double maxDotS = -minDotS;
    double minDotT = Double.MAX_VALUE;
    double maxDotT = -minDotT;

    for (Vec4 p : points) {
      if (p == null) continue;

      double pdr = p.dot3(r);
      if (pdr < minDotR) minDotR = pdr;
      if (pdr > maxDotR) maxDotR = pdr;

      double pds = p.dot3(s);
      if (pds < minDotS) minDotS = pds;
      if (pds > maxDotS) maxDotS = pds;

      double pdt = p.dot3(t);
      if (pdt < minDotT) minDotT = pdt;
      if (pdt > maxDotT) maxDotT = pdt;
    }

    if (maxDotR == minDotR) maxDotR = minDotR + 1;
    if (maxDotS == minDotS) maxDotS = minDotS + 1;
    if (maxDotT == minDotT) maxDotT = minDotT + 1;

    return new Box(axes, minDotR, maxDotR, minDotS, maxDotS, minDotT, maxDotT);
  }