/** * 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"); // } }
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; }
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(); }
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; }
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; }
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++; } }
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); } }
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); }
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); } } }
/** * 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); }
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); }
// 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(); }
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; }
/** {@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); }
/** * 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); }
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); }