Example #1
0
  /**
   * Construct a unit-length cube centered at a specified point.
   *
   * @param point the center of the cube.
   * @throws IllegalArgumentException if the point is null.
   */
  public Box(Vec4 point) {
    if (point == null) {
      String msg = Logging.getMessage("nullValue.PointIsNull");
      Logging.error(msg);
      throw new IllegalArgumentException(msg);
    }

    this.ru = new Vec4(1, 0, 0, 1);
    this.su = new Vec4(0, 1, 0, 1);
    this.tu = new Vec4(0, 0, 1, 1);

    this.r = this.ru;
    this.s = this.su;
    this.t = this.tu;

    this.rLength = 1;
    this.sLength = 1;
    this.tLength = 1;

    // Plane normals point outwards from the box.
    this.planes = new Plane[6];
    double d = 0.5 * point.getLength3();
    this.planes[0] = new Plane(-this.ru.x, -this.ru.y, -this.ru.z, -(d + 0.5));
    this.planes[1] = new Plane(+this.ru.x, +this.ru.y, +this.ru.z, -(d + 0.5));
    this.planes[2] = new Plane(-this.su.x, -this.su.y, -this.su.z, -(d + 0.5));
    this.planes[3] = new Plane(+this.su.x, +this.su.y, +this.su.z, -(d + 0.5));
    this.planes[4] = new Plane(-this.tu.x, -this.tu.y, -this.tu.z, -(d + 0.5));
    this.planes[5] = new Plane(+this.tu.x, +this.tu.y, +this.tu.z, -(d + 0.5));

    this.center = ru.add3(su).add3(tu).multiply3(0.5);

    Vec4 rHalf = r.multiply3(0.5);
    this.topCenter = this.center.add3(rHalf);
    this.bottomCenter = this.center.subtract3(rHalf);
  }
  public static void main(String[] args) {
    BarycentricPlanarShape bc = new BarycentricQuadrilateral(i0, i1, i2, i3);

    for (Vec4 point : testPoints) {
      double[] w = bc.getBarycentricCoords(point);
      Vec4 p = bc.getPoint(w);
      double[] uv = bc.getBilinearCoords(w[1], w[2]);

      System.out.printf(
          "%s, %s: ( %f, %f, %f) : ( %f, %f), %s\n",
          point, p, w[0], w[1], w[2], uv[0], uv[1], p.equals(point) ? "true" : "false");
    }
    //
    //        BarycentricPlanarShape bc = new BarycentricQuadrilateral(new Vec4(4, 3, 0), new
    // Vec4(7, 1, 0),
    //            new Vec4(10, 5, 0), new Vec4(7, 7, 0));
    //
    //        ArrayList<Vec4> points = makePoints(0, 0, 14, 10);
    //        for (Vec4 point : points)
    //        {
    //            double[] w = bc.getBarycentricCoords(point);
    //            Vec4 p = bc.getPoint(w);
    //            double[] uv = bc.getBilinearCoords(w[1], w[2]);
    //
    //            System.out.printf("%s, %s: ( %f, %f, %f) : ( %f, %f), %s\n",
    //                point, p, w[0], w[1], w[2], uv[0], uv[1], p.equals(point) ? "true" : "false");
    //        }
  }
Example #3
0
  protected double computeLength(Globe globe, boolean followTerrain) {
    if (this.positions == null || this.positions.size() < 2) return -1;

    if (this.subdividedPositions == null) {
      // Subdivide path so as to have at least segments smaller then maxSegmentLenth. If follow
      // terrain,
      // subdivide so as to have at least lengthTerrainSamplingSteps segments, but no segments
      // shorter then
      // DEFAULT_MIN_SEGMENT_LENGTH either.
      double maxLength = this.maxSegmentLength;
      if (followTerrain) {
        // Recurse to compute overall path length not following terrain
        double pathLength = computeLength(globe, !followTerrain);
        // Determine segment length to have enough sampling points
        maxLength = pathLength / this.lengthTerrainSamplingSteps;
        maxLength =
            Math.min(Math.max(maxLength, DEFAULT_MIN_SEGMENT_LENGTH), getMaxSegmentLength());
      }
      this.subdividedPositions =
          subdividePositions(globe, this.positions, maxLength, followTerrain, this.pathType);
    }

    // Sum each segment length
    double length = 0;
    Vec4 p1 = globe.computePointFromPosition(this.subdividedPositions.get(0));
    for (int i = 1; i < subdividedPositions.size(); i++) {
      Vec4 p2 = globe.computePointFromPosition(this.subdividedPositions.get(i));
      length += p1.distanceTo3(p2);
      p1 = p2;
    }
    return length;
  }
    protected boolean areShapesIntersecting(Airspace a1, Airspace a2) {
      if ((a1 instanceof SphereAirspace) && (a2 instanceof SphereAirspace)) {
        SphereAirspace s1 = (SphereAirspace) a1;
        SphereAirspace s2 = (SphereAirspace) a2;

        LatLon location1 = s1.getLocation();
        LatLon location2 = s2.getLocation();
        double altitude1 = s1.getAltitudes()[0];
        double altitude2 = s2.getAltitudes()[0];
        boolean terrainConforming1 = s1.isTerrainConforming()[0];
        boolean terrainConforming2 = s2.isTerrainConforming()[0];

        // We have to compute the 3D coordinates of the sphere's center ourselves here.
        Vec4 p1 =
            terrainConforming1
                ? this.getSurfacePoint(location1, altitude1)
                : this.getPoint(location1, altitude1);
        Vec4 p2 =
            terrainConforming2
                ? this.getSurfacePoint(location2, altitude2)
                : this.getPoint(location2, altitude2);
        double r1 = s1.getRadius();
        double r2 = s2.getRadius();

        double d = p1.distanceTo3(p2);

        return d <= (r1 + r2);
      }

      return false;
    }
Example #5
0
 public void color(float red, float green, float blue, float alpha) {
   Vec4 c = mVert.mColor;
   c.x = red;
   c.y = green;
   c.z = blue;
   c.w = alpha;
 }
  protected void assembleHeightControlPoints() {
    if (this.controlPoints.size() < 2) return;

    // Add one control point for the height between the first and second vertices.
    // TODO: ensure that this control point is visible
    Position firstVertex = this.controlPoints.get(0).getPosition();
    Position secondVertex = this.controlPoints.get(1).getPosition();

    Globe globe = this.wwd.getModel().getGlobe();

    // Get cartesian points for the vertices
    Vec4 firstPoint = globe.computePointFromPosition(firstVertex);
    Vec4 secondPoint = globe.computePointFromPosition(secondVertex);

    // Find the midpoint of the line segment that connects the vertices
    Vec4 halfwayPoint = firstPoint.add3(secondPoint).divide3(2.0);

    Position halfwayPosition = globe.computePositionFromPoint(halfwayPoint);

    this.controlPoints.add(
        new ControlPointMarker(
            CHANGE_HEIGHT_ACTION,
            halfwayPosition,
            halfwayPoint,
            this.heightControlAttributes,
            this.controlPoints.size()));
  }
    /**
     * Performs one line of sight calculation between the reference position and a specified grid
     * position.
     *
     * @param gridPosition the grid position.
     * @throws InterruptedException if the operation is interrupted.
     */
    protected void performIntersection(Position gridPosition) throws InterruptedException {
      // Intersect the line between this grid point and the selected position.
      Intersection[] intersections = this.terrain.intersect(this.referencePosition, gridPosition);
      if (intersections == null || intersections.length == 0) {
        // No intersection, so the line goes from the center to the grid point.
        this.sightLines.add(new Position[] {this.referencePosition, gridPosition});
        return;
      }

      // Only the first intersection is shown.
      Vec4 iPoint = intersections[0].getIntersectionPoint();
      Vec4 gPoint =
          terrain.getSurfacePoint(
              gridPosition.getLatitude(), gridPosition.getLongitude(), gridPosition.getAltitude());

      // Check to see whether the intersection is beyond the grid point.
      if (iPoint.distanceTo3(this.referencePoint) >= gPoint.distanceTo3(this.referencePoint)) {
        // Intersection is beyond the grid point; the line goes from the center to the grid point.
        this.addSightLine(this.referencePosition, gridPosition);
        return;
      }

      // Compute the position corresponding to the intersection.
      Position iPosition = this.terrain.getGlobe().computePositionFromPoint(iPoint);

      // The sight line goes from the user-selected position to the intersection position.
      this.addSightLine(this.referencePosition, new Position(iPosition, 0));

      // Keep track of the intersection positions.
      this.addIntersectionPosition(iPosition);

      this.updateProgress();
    }
Example #8
0
 public void colorub(int red, int green, int blue, int alpha) {
   Vec4 c = mVert.mColor;
   c.x = red / 255f;
   c.y = green / 255f;
   c.z = blue / 255f;
   c.w = alpha / 255f;
 }
Example #9
0
  protected double intersectsAt(
      Plane plane, double effectiveRadius, Vec4 endpoint1, Vec4 endpoint2) {
    // Test the distance from the first end-point.
    double dq1 = plane.dot(endpoint1);
    boolean bq1 = dq1 <= -effectiveRadius;

    // Test the distance from the possibly reduced second end-point.
    double dq2 = plane.dot(endpoint2);
    boolean bq2 = dq2 <= -effectiveRadius;

    if (bq1
        && bq2) // endpoints more distant from plane than effective radius; box is on neg. side of
      // plane
      return -1;

    if (bq1 == bq2) // endpoints less distant from plane than effective radius; can't draw any
      // conclusions
      return 0;

    // Compute and return the endpoints of the cylinder on the positive side of the plane.
    this.tmp3.subtract3AndSet(endpoint1, endpoint2);
    double t = (effectiveRadius + dq1) / plane.getNormal().dot3(this.tmp3);

    this.tmp3.subtract3AndSet(endpoint2, endpoint1).multiply3AndSet(t).add3AndSet(endpoint1);
    // truncate the line to only that in the positive halfspace (e.g., inside the frustum)
    if (bq1) endpoint1.set(this.tmp3);
    else endpoint2.set(this.tmp3);

    return t;
  }
  private void makePartialDiskTerrainConformant(
      DrawContext dc,
      int numCoords,
      float[] verts,
      double altitude,
      boolean terrainConformant,
      Vec4 referenceCenter) {
    Globe globe = dc.getGlobe();
    Matrix transform = this.computeTransform(dc.getGlobe(), dc.getVerticalExaggeration());

    for (int i = 0; i < numCoords; i += 3) {
      Vec4 vec = new Vec4(verts[i], verts[i + 1], verts[i + 2]);
      vec = vec.transformBy4(transform);
      Position p = globe.computePositionFromPoint(vec);

      double elevation = altitude;
      if (terrainConformant)
        elevation += this.computeElevationAt(dc, p.getLatitude(), p.getLongitude());

      vec = globe.computePointFromPosition(p.getLatitude(), p.getLongitude(), elevation);
      verts[i] = (float) (vec.x - referenceCenter.x);
      verts[i + 1] = (float) (vec.y - referenceCenter.y);
      verts[i + 2] = (float) (vec.z - referenceCenter.z);
    }
  }
  private void makeRadialWallTerrainConformant(
      DrawContext dc,
      int pillars,
      int stacks,
      float[] verts,
      double[] altitudes,
      boolean[] terrainConformant,
      Vec4 referenceCenter) {
    Globe globe = dc.getGlobe();
    Matrix transform = this.computeTransform(dc.getGlobe(), dc.getVerticalExaggeration());

    for (int p = 0; p <= pillars; p++) {
      int index = p;
      index = 3 * index;
      Vec4 vec = new Vec4(verts[index], verts[index + 1], verts[index + 2]);
      vec = vec.transformBy4(transform);
      Position pos = globe.computePositionFromPoint(vec);

      for (int s = 0; s <= stacks; s++) {
        double elevation = altitudes[s];
        if (terrainConformant[s])
          elevation += this.computeElevationAt(dc, pos.getLatitude(), pos.getLongitude());
        vec = globe.computePointFromPosition(pos.getLatitude(), pos.getLongitude(), elevation);

        index = p + s * (pillars + 1);
        index = 3 * index;
        verts[index] = (float) (vec.x - referenceCenter.x);
        verts[index + 1] = (float) (vec.y - referenceCenter.y);
        verts[index + 2] = (float) (vec.z - referenceCenter.z);
      }
    }
  }
  @Override
  protected List<Vec4> computeMinimalGeometry(Globe globe, double verticalExaggeration) {
    double[] angles = this.computeAngles();
    // Angles are equal, fall back to building a closed cylinder.
    if (angles == null) return super.computeMinimalGeometry(globe, verticalExaggeration);

    double[] radii = this.getRadii();
    Matrix transform = this.computeTransform(globe, verticalExaggeration);

    GeometryBuilder gb = this.getGeometryBuilder();
    int count = gb.getPartialDiskVertexCount(MINIMAL_GEOMETRY_SLICES, MINIMAL_GEOMETRY_LOOPS);
    int numCoords = 3 * count;
    float[] verts = new float[numCoords];
    gb.makePartialDiskVertices(
        (float) radii[0],
        (float) radii[1], // Inner radius, outer radius.
        MINIMAL_GEOMETRY_SLICES,
        MINIMAL_GEOMETRY_LOOPS, // Slices, loops,
        (float) angles[0],
        (float) angles[2], // Start angle, sweep angle.
        verts);

    List<LatLon> locations = new ArrayList<LatLon>();
    for (int i = 0; i < numCoords; i += 3) {
      Vec4 v = new Vec4(verts[i], verts[i + 1], verts[i + 2]);
      v = v.transformBy4(transform);
      locations.add(globe.computePositionFromPoint(v));
    }

    ArrayList<Vec4> points = new ArrayList<Vec4>();
    this.makeExtremePoints(globe, verticalExaggeration, locations, points);

    return points;
  }
Example #13
0
  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));
    }
  }
  private void makePartialCylinderTerrainConformant(
      DrawContext dc,
      int slices,
      int stacks,
      float[] verts,
      double[] altitudes,
      boolean[] terrainConformant,
      Vec4 referenceCenter) {
    Globe globe = dc.getGlobe();
    Matrix transform = this.computeTransform(dc.getGlobe(), dc.getVerticalExaggeration());

    for (int i = 0; i <= slices; i++) {
      int index = i * (stacks + 1);
      index = 3 * index;
      Vec4 vec = new Vec4(verts[index], verts[index + 1], verts[index + 2]);
      vec = vec.transformBy4(transform);
      Position p = globe.computePositionFromPoint(vec);

      for (int j = 0; j <= stacks; j++) {
        double elevation = altitudes[j];
        if (terrainConformant[j])
          elevation += this.computeElevationAt(dc, p.getLatitude(), p.getLongitude());
        vec = globe.computePointFromPosition(p.getLatitude(), p.getLongitude(), elevation);

        index = j + i * (stacks + 1);
        index = 3 * index;
        verts[index] = (float) (vec.x - referenceCenter.x);
        verts[index + 1] = (float) (vec.y - referenceCenter.y);
        verts[index + 2] = (float) (vec.z - referenceCenter.z);
      }
    }
  }
  protected void requestTile(DrawContext dc, Tile tile) {
    Vec4 centroid = dc.getGlobe().computePointFromPosition(tile.getSector().getCentroid(), 0);
    if (this.getReferencePoint() != null)
      tile.setPriority(centroid.distanceTo3(this.getReferencePoint()));

    RequestTask task = new RequestTask(tile, this);
    this.getRequestQ().add(task);
  }
  protected void assembleVertexControlPoints(DrawContext dc) {
    Terrain terrain = dc.getTerrain();
    ExtrudedPolygon polygon = this.getPolygon();

    Position refPos = polygon.getReferencePosition();
    Vec4 refPoint = terrain.getSurfacePoint(refPos.getLatitude(), refPos.getLongitude(), 0);

    int altitudeMode = polygon.getAltitudeMode();
    double height = polygon.getHeight();

    Vec4 vaa = null;
    double vaaLength = 0; // used to compute independent length of each cap vertex
    double vaLength = 0;

    int i = 0;
    for (LatLon location : polygon.getOuterBoundary()) {
      Vec4 vert;

      // Compute the top/cap point.
      if (altitudeMode == WorldWind.CONSTANT || !(location instanceof Position)) {
        if (vaa == null) {
          // Compute the vector lengths of the top and bottom points at the reference position.
          vaa = refPoint.multiply3(height / refPoint.getLength3());
          vaaLength = vaa.getLength3();
          vaLength = refPoint.getLength3();
        }

        // Compute the bottom point, which is on the terrain.
        vert = terrain.getSurfacePoint(location.getLatitude(), location.getLongitude(), 0);

        double delta = vaLength - vert.dot3(refPoint) / vaLength;
        vert = vert.add3(vaa.multiply3(1d + delta / vaaLength));
      } else if (altitudeMode == WorldWind.RELATIVE_TO_GROUND) {
        vert =
            terrain.getSurfacePoint(
                location.getLatitude(),
                location.getLongitude(),
                ((Position) location).getAltitude());
      } else // WorldWind.ABSOLUTE
      {
        vert =
            terrain
                .getGlobe()
                .computePointFromPosition(
                    location.getLatitude(),
                    location.getLongitude(),
                    ((Position) location).getAltitude() * terrain.getVerticalExaggeration());
      }

      Position vertexPosition = this.wwd.getModel().getGlobe().computePositionFromPoint(vert);

      this.controlPoints.add(
          new ControlPointMarker(
              MOVE_VERTEX_ACTION, vertexPosition, vert, this.vertexControlAttributes, i));
      i++;
    }
  }
Example #17
0
 public Vec4 multiply(final Vec4 vec) {
   final float x = vec.getX();
   final float y = vec.getY();
   final float z = vec.getZ();
   final float w = vec.getW();
   return new Vec4(
       x * this.data[M00] + y * this.data[M01] + z * this.data[M02] + w * this.data[M03],
       x * this.data[M10] + y * this.data[M11] + z * this.data[M12] + w * this.data[M13],
       x * this.data[M20] + y * this.data[M21] + z * this.data[M22] + w * this.data[M23],
       x * this.data[M30] + y * this.data[M31] + z * this.data[M32] + w * this.data[M33]);
 }
  protected static boolean isNameVisible(
      DrawContext dc, PlaceNameService service, Position namePosition) {
    double elevation = dc.getVerticalExaggeration() * namePosition.getElevation();
    Vec4 namePoint =
        dc.getGlobe()
            .computePointFromPosition(
                namePosition.getLatitude(), namePosition.getLongitude(), elevation);
    Vec4 eyeVec = dc.getView().getEyePoint();

    double dist = eyeVec.distanceTo3(namePoint);
    return dist >= service.getMinDisplayDistance() && dist <= service.getMaxDisplayDistance();
  }
  protected void onHorizontalTranslateRel(
      Angle forwardChange, Angle sideChange, ViewInputAttributes.ActionAttributes actionAttribs) {
    View view = this.getView();
    if (view == null) // include this test to ensure any derived implementation performs it
    {
      return;
    }

    if (forwardChange.equals(Angle.ZERO) && sideChange.equals(Angle.ZERO)) {
      return;
    }

    if (view instanceof BasicFlyView) {

      Vec4 forward = view.getForwardVector();
      Vec4 up = view.getUpVector();
      Vec4 side = forward.transformBy3(Matrix.fromAxisAngle(Angle.fromDegrees(90), up));

      forward = forward.multiply3(forwardChange.getDegrees());
      side = side.multiply3(sideChange.getDegrees());
      Vec4 eyePoint = view.getEyePoint();
      eyePoint = eyePoint.add3(forward.add3(side));
      Position newPosition = view.getGlobe().computePositionFromPoint(eyePoint);

      this.setEyePosition(this.uiAnimControl, view, newPosition, actionAttribs);
      view.firePropertyChange(AVKey.VIEW, null, view);
    }
  }
Example #20
0
  private void makeCap(
      DrawContext dc,
      GeometryBuilder.IndexedTriangleArray ita,
      double altitude,
      boolean terrainConformant,
      int orientation,
      Matrix locationTransform,
      Vec4 referenceCenter,
      int indexPos,
      int[] indices,
      int vertexPos,
      float[] vertices,
      float[] normals) {
    GeometryBuilder gb = this.getGeometryBuilder();
    Globe globe = dc.getGlobe();

    int indexCount = ita.getIndexCount();
    int vertexCount = ita.getVertexCount();
    int[] locationIndices = ita.getIndices();
    float[] locationVerts = ita.getVertices();

    this.copyIndexArray(
        indexCount,
        (orientation == GeometryBuilder.INSIDE),
        locationIndices,
        vertexPos,
        indexPos,
        indices);

    for (int i = 0; i < vertexCount; i++) {
      int index = 3 * i;
      Vec4 vec = new Vec4(locationVerts[index], locationVerts[index + 1], locationVerts[index + 2]);
      vec = vec.transformBy4(locationTransform);

      Position pos = globe.computePositionFromPoint(vec);
      vec =
          this.computePointFromPosition(
              dc, pos.getLatitude(), pos.getLongitude(), altitude, terrainConformant);

      index = 3 * (vertexPos + i);
      vertices[index] = (float) (vec.x - referenceCenter.x);
      vertices[index + 1] = (float) (vec.y - referenceCenter.y);
      vertices[index + 2] = (float) (vec.z - referenceCenter.z);
    }

    gb.makeIndexedTriangleArrayNormals(
        indexPos, indexCount, indices, vertexPos, vertexCount, vertices, normals);
  }
Example #21
0
  private void makeSectionVertices(
      DrawContext dc,
      int locationPos,
      float[] locations,
      double[] altitude,
      boolean[] terrainConformant,
      int subdivisions,
      Matrix locationTransform,
      Vec4 referenceCenter,
      int vertexPos,
      float[] vertices) {
    GeometryBuilder gb = this.getGeometryBuilder();
    int numPoints = gb.getSubdivisionPointsVertexCount(subdivisions);

    Globe globe = dc.getGlobe();
    int index1 = 3 * locationPos;
    int index2 = 3 * (locationPos + 1);

    float[] locationVerts = new float[3 * numPoints];
    gb.makeSubdivisionPoints(
        locations[index1],
        locations[index1 + 1],
        locations[index1 + 2],
        locations[index2],
        locations[index2 + 1],
        locations[index2 + 2],
        subdivisions,
        locationVerts);

    for (int i = 0; i < numPoints; i++) {
      int index = 3 * i;
      Vec4 vec = new Vec4(locationVerts[index], locationVerts[index + 1], locationVerts[index + 2]);
      vec = vec.transformBy4(locationTransform);
      Position pos = globe.computePositionFromPoint(vec);

      for (int j = 0; j < 2; j++) {
        vec =
            this.computePointFromPosition(
                dc, pos.getLatitude(), pos.getLongitude(), altitude[j], terrainConformant[j]);

        index = 2 * i + j;
        index = 3 * (vertexPos + index);
        vertices[index] = (float) (vec.x - referenceCenter.x);
        vertices[index + 1] = (float) (vec.y - referenceCenter.y);
        vertices[index + 2] = (float) (vec.z - referenceCenter.z);
      }
    }
  }
Example #22
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);
  }
Example #23
0
  protected void addToolTip(DrawContext dc, WWIcon icon, Vec4 iconPoint) {
    if (icon.getToolTipFont() == null && icon.getToolTipText() == null) return;

    Vec4 screenPoint = dc.getView().project(iconPoint);
    if (screenPoint == null) return;

    if (icon.getToolTipOffset() != null) screenPoint = screenPoint.add3(icon.getToolTipOffset());

    OrderedText tip =
        new OrderedText(
            icon.getToolTipText(),
            icon.getToolTipFont(),
            screenPoint,
            icon.getToolTipTextColor(),
            0d);
    dc.addOrderedRenderable(tip);
  }
Example #24
0
  // Draw the scale label
  private void drawLabel(DrawContext dc, String text, Vec4 screenPoint) {
    TextRenderer textRenderer =
        OGLTextRenderer.getOrCreateTextRenderer(dc.getTextRendererCache(), this.defaultFont);

    Rectangle2D nameBound = textRenderer.getBounds(text);
    int x = (int) (screenPoint.x() - nameBound.getWidth() / 2d);
    int y = (int) screenPoint.y();

    textRenderer.begin3DRendering();

    textRenderer.setColor(this.getBackgroundColor(this.color));
    textRenderer.draw(text, x + 1, y - 1);
    textRenderer.setColor(this.color);
    textRenderer.draw(text, x, y);

    textRenderer.end3DRendering();
  }
Example #25
0
  public Box translate(Vec4 point) {
    if (point == null) {
      String msg = Logging.getMessage("nullValue.PointIsNull");
      Logging.error(msg);
      throw new IllegalArgumentException(msg);
    }

    this.bottomCenter.add3AndSet(point);
    this.topCenter.add3AndSet(point);
    this.center.add3AndSet(point);

    for (int i = 0; i < this.planes.length; i++) {
      Vec4 n = this.planes[i].getNormal();
      double d = this.planes[i].getDistance();
      this.planes[i].set(n.x, n.y, n.z, d - n.dot3(point));
    }

    return this;
  }
Example #26
0
  /** {@inheritDoc} */
  public double distanceTo(Vec4 point) {
    if (point == null) {
      String msg = Logging.getMessage("nullValue.PointIsNull");
      Logging.error(msg);
      throw new IllegalArgumentException(msg);
    }

    double distance = point.distanceTo3(this.center) - this.getRadius();
    return (distance < 0d) ? 0d : distance;
  }
  /**
   * Add a vertex to the polygon's outer boundary.
   *
   * @param mousePoint the point at which the mouse was clicked. The new vertex will be placed as
   *     near as possible to this point, at the elevation of the polygon.
   */
  protected void addVertex(Point mousePoint) {
    // Try to find the edge that is closest to a ray passing through the screen point. We're trying
    // to determine
    // the user's intent as to which edge a new two control points should be added to.

    Line ray = this.wwd.getView().computeRayFromScreenPoint(mousePoint.getX(), mousePoint.getY());
    Vec4 pickPoint = this.intersectPolygonAltitudeAt(ray);

    double nearestDistance = Double.MAX_VALUE;
    int newVertexIndex = 0;

    // Loop through the control points and determine which edge is closest to the pick point
    for (int i = 0; i < this.controlPoints.size(); i++) {
      ControlPointMarker thisMarker = (ControlPointMarker) this.controlPoints.get(i);
      ControlPointMarker nextMarker =
          (ControlPointMarker) this.controlPoints.get((i + 1) % this.controlPoints.size());

      Vec4 pointOnEdge =
          AirspaceEditorUtil.nearestPointOnSegment(thisMarker.point, nextMarker.point, pickPoint);
      if (!AirspaceEditorUtil.isPointBehindLineOrigin(ray, pointOnEdge)) {
        double d = pointOnEdge.distanceTo3(pickPoint);
        if (d < nearestDistance) {
          newVertexIndex = i + 1;
          nearestDistance = d;
        }
      }
    }

    Position newPosition = this.wwd.getModel().getGlobe().computePositionFromPoint(pickPoint);

    // Copy the outer boundary list
    ArrayList<Position> positionList = new ArrayList<Position>(this.controlPoints.size());
    for (LatLon position : this.getPolygon().getOuterBoundary()) {
      positionList.add((Position) position);
    }

    // Add the new vertex
    positionList.add(newVertexIndex, newPosition);

    this.getPolygon().setOuterBoundary(positionList);
  }
Example #28
0
  /**
   * Construct a box from three specified unit axes and the locations of the box faces relative to
   * those axes. The box faces are specified by two scalar locations along each axis, each location
   * indicating a face. The non-unit length of an axis is the distance between its respective two
   * locations. The longest side is specified first, followed by the second longest side and then
   * the shortest side.
   *
   * <p>The axes are normally principal axes computed from a collection of points in order to form
   * an oriented bounding volume. See {@link WWMath#computePrincipalAxes(Iterable)}.
   *
   * <p>Note: No check is made to ensure the order of the face locations.
   *
   * @param axes the unit-length axes.
   * @param rMin the location along the first axis corresponding to the left-most box side relative
   *     to the axis.
   * @param rMax the location along the first axis corresponding to the right-most box side relative
   *     to the axis.
   * @param sMin the location along the second axis corresponding to the left-most box side relative
   *     to the axis.
   * @param sMax the location along the second axis corresponding to the right-most box side
   *     relative to the axis.
   * @param tMin the location along the third axis corresponding to the left-most box side relative
   *     to the axis.
   * @param tMax the location along the third axis corresponding to the right-most box side relative
   *     to the axis.
   * @throws IllegalArgumentException if the axes array or one of its entries is null.
   */
  public Box(
      Vec4 axes[], double rMin, double rMax, double sMin, double sMax, double tMin, double tMax) {
    if (axes == null || axes[0] == null || axes[1] == null || axes[2] == null) {
      String msg = Logging.getMessage("nullValue.AxesIsNull");
      Logging.error(msg);
      throw new IllegalArgumentException(msg);
    }

    this.ru = axes[0];
    this.su = axes[1];
    this.tu = axes[2];

    this.r = this.ru.multiply3(rMax - rMin);
    this.s = this.su.multiply3(sMax - sMin);
    this.t = this.tu.multiply3(tMax - tMin);

    this.rLength = this.r.getLength3();
    this.sLength = this.s.getLength3();
    this.tLength = this.t.getLength3();

    // Plane normals point outward from the box.
    this.planes = new Plane[6];
    this.planes[0] = new Plane(-this.ru.x, -this.ru.y, -this.ru.z, +rMin);
    this.planes[1] = new Plane(+this.ru.x, +this.ru.y, +this.ru.z, -rMax);
    this.planes[2] = new Plane(-this.su.x, -this.su.y, -this.su.z, +sMin);
    this.planes[3] = new Plane(+this.su.x, +this.su.y, +this.su.z, -sMax);
    this.planes[4] = new Plane(-this.tu.x, -this.tu.y, -this.tu.z, +tMin);
    this.planes[5] = new Plane(+this.tu.x, +this.tu.y, +this.tu.z, -tMax);

    double a = 0.5 * (rMin + rMax);
    double b = 0.5 * (sMin + sMax);
    double c = 0.5 * (tMin + tMax);
    this.center = ru.multiply3(a).add3(su.multiply3(b)).add3(tu.multiply3(c));

    Vec4 rHalf = r.multiply3(0.5);
    this.topCenter = this.center.add3(rHalf);
    this.bottomCenter = this.center.subtract3(rHalf);
  }
Example #29
0
  protected Extent computeExtent(Globe globe, double verticalExaggeration) {
    List<Vec4> points = this.computeMinimalGeometry(globe, verticalExaggeration);
    if (points == null || points.isEmpty()) return null;

    // Add a point at the center of this polygon to the points used to compute its extent. The
    // center point captures
    // the curvature of the globe when the polygon's minimal geometry only contain any points near
    // the polygon's
    // edges.
    Vec4 centerPoint = Vec4.computeAveragePoint(points);
    LatLon centerLocation = globe.computePositionFromPoint(centerPoint);
    this.makeExtremePoints(globe, verticalExaggeration, Arrays.asList(centerLocation), points);

    return Box.computeBoundingBox(points);
  }
  /**
   * Returns the vector element at the specified position, as a {@link Vec4}. This buffer's logical
   * vector size must be either 2, 3 or 4.
   *
   * @param position the logical vector position.
   * @return the vector at the specified vector position.
   * @throws IllegalArgumentException if the position is out of range, or if this buffer cannot
   *     store a Vec4.
   */
  public Vec4 getVector(int position) {
    if (position < 0 || position >= this.getSize()) {
      String message =
          Logging.getMessage("generic.ArgumentOutOfRange", "position < 0 or position >= size");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    if (this.coordsPerVec != 2 && this.coordsPerVec != 3 && this.coordsPerVec != 4) {
      String message = Logging.getMessage("generic.BufferIncompatible", this);
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    double[] compArray = new double[this.coordsPerVec];
    this.get(position, compArray);
    return Vec4.fromDoubleArray(compArray, 0, this.coordsPerVec);
  }