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 #2
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);
  }
Example #3
0
  /**
   * Compute the positions of the arrow head of the graphic's legs.
   *
   * @param dc Current draw context
   * @param base Position of the arrow's starting point.
   * @param tip Position of the arrow head tip.
   * @param arrowLength Length of the arrowhead as a fraction of the total line length.
   * @param arrowAngle Angle of the arrow head.
   * @return Positions required to draw the arrow head.
   */
  protected List<Position> computeArrowheadPositions(
      DrawContext dc, Position base, Position tip, double arrowLength, Angle arrowAngle) {
    // Build a triangle to represent the arrowhead. The triangle is built from two vectors, one
    // parallel to the
    // segment, and one perpendicular to it.

    Globe globe = dc.getGlobe();

    Vec4 ptA = globe.computePointFromPosition(base);
    Vec4 ptB = globe.computePointFromPosition(tip);

    // Compute parallel component
    Vec4 parallel = ptA.subtract3(ptB);

    Vec4 surfaceNormal = globe.computeSurfaceNormalAtPoint(ptB);

    // Compute perpendicular component
    Vec4 perpendicular = surfaceNormal.cross3(parallel);

    double finalArrowLength = arrowLength * parallel.getLength3();
    double arrowHalfWidth = finalArrowLength * arrowAngle.tanHalfAngle();

    perpendicular = perpendicular.normalize3().multiply3(arrowHalfWidth);
    parallel = parallel.normalize3().multiply3(finalArrowLength);

    // Compute geometry of direction arrow
    Vec4 vertex1 = ptB.add3(parallel).add3(perpendicular);
    Vec4 vertex2 = ptB.add3(parallel).subtract3(perpendicular);

    return TacticalGraphicUtil.asPositionList(globe, vertex1, vertex2, ptB);
  }
Example #4
0
  /**
   * Determine the positions that make up the arrowhead.
   *
   * @param dc Current draw context.
   * @param startPosition Position of the arrow's base.
   * @param endPosition Position of the arrow head tip.
   * @return Positions that define the arrowhead.
   */
  protected List<Position> computeArrowheadPositions(
      DrawContext dc, Position startPosition, Position endPosition) {
    Globe globe = dc.getGlobe();

    // Arrowhead looks like this:
    //                  _
    //        A\         | 1/2 width
    // ________B\       _|
    // Pt. 1    /
    //        C/
    //         | |
    //      Length

    Vec4 p1 = globe.computePointFromPosition(startPosition);
    Vec4 pB = globe.computePointFromPosition(endPosition);

    // Find vector in the direction of the arrow
    Vec4 vB1 = p1.subtract3(pB);

    double arrowLengthFraction = this.getArrowLength();

    // Find the point at the base of the arrowhead
    Vec4 arrowBase = pB.add3(vB1.multiply3(arrowLengthFraction));

    Vec4 normal = globe.computeSurfaceNormalAtPoint(arrowBase);

    // Compute the length of the arrowhead
    double arrowLength = vB1.getLength3() * arrowLengthFraction;
    double arrowHalfWidth = arrowLength * this.getArrowAngle().tanHalfAngle();

    // Compute a vector perpendicular to the segment and the normal vector
    Vec4 perpendicular = vB1.cross3(normal);
    perpendicular = perpendicular.normalize3().multiply3(arrowHalfWidth);

    // Find points A and C
    Vec4 pA = arrowBase.add3(perpendicular);
    Vec4 pC = arrowBase.subtract3(perpendicular);

    return TacticalGraphicUtil.asPositionList(globe, pA, pB, pC);
  }
  /**
   * Determines whether this sector intersects the specified geographic line segment. The line
   * segment is specified by a begin location and an end location. The locations are are assumed to
   * be connected by a linear path in geographic space. This returns true if any location along that
   * linear path intersects this sector, including the begin and end locations.
   *
   * @param begin the line segment begin location.
   * @param end the line segment end location.
   * @return true <code>true</code> if this sector intersects the line segment, otherwise <code>
   *     false</code>.
   * @throws IllegalArgumentException if either the begin location or the end location is null.
   */
  public boolean intersectsSegment(LatLon begin, LatLon end) {
    if (begin == null) {
      throw new IllegalArgumentException("Begin Is Null");
    }

    if (end == null) {
      throw new IllegalArgumentException("End Is Null");
    }

    Vec4 segmentBegin = new Vec4(begin.getLongitude().degrees, begin.getLatitude().degrees, 0);
    Vec4 segmentEnd = new Vec4(end.getLongitude().degrees, end.getLatitude().degrees, 0);
    Vec4 tmp = segmentEnd.subtract3(segmentBegin);
    Vec4 segmentCenter = segmentBegin.add3(segmentEnd).divide3(2);
    Vec4 segmentDirection = tmp.normalize3();
    double segmentExtent = tmp.getLength3() / 2.0;

    LatLon centroid = this.getCentroid();
    Vec4 boxCenter = new Vec4(centroid.getLongitude().degrees, centroid.getLatitude().degrees, 0);
    double boxExtentX = this.getDeltaLonDegrees() / 2.0;
    double boxExtentY = this.getDeltaLatDegrees() / 2.0;

    Vec4 diff = segmentCenter.subtract3(boxCenter);

    if (Math.abs(diff.x) > (boxExtentX + segmentExtent * Math.abs(segmentDirection.x))) {
      return false;
    }

    if (Math.abs(diff.y) > (boxExtentY + segmentExtent * Math.abs(segmentDirection.y))) {
      return false;
    }

    //noinspection SuspiciousNameCombination
    Vec4 segmentPerp = new Vec4(segmentDirection.y, -segmentDirection.x, 0);

    return Math.abs(segmentPerp.dot3(diff))
        <= (boxExtentX * Math.abs(segmentPerp.x) + boxExtentY * Math.abs(segmentPerp.y));
  }