protected void movePolygon(Point previousMousePoint, Point mousePoint) { // Intersect a ray through each mouse point, with a geoid passing through the reference // elevation. // If either ray fails to intersect the geoid, then ignore this event. Use the difference // between the two // intersected positions to move the control point's location. View view = this.wwd.getView(); Globe globe = this.wwd.getModel().getGlobe(); Position refPos = this.polygon.getReferencePosition(); if (refPos == null) return; Line ray = view.computeRayFromScreenPoint(mousePoint.getX(), mousePoint.getY()); Line previousRay = view.computeRayFromScreenPoint(previousMousePoint.getX(), previousMousePoint.getY()); Vec4 vec = AirspaceEditorUtil.intersectGlobeAt(this.wwd, refPos.getElevation(), ray); Vec4 previousVec = AirspaceEditorUtil.intersectGlobeAt(this.wwd, refPos.getElevation(), previousRay); if (vec == null || previousVec == null) { return; } Position pos = globe.computePositionFromPoint(vec); Position previousPos = globe.computePositionFromPoint(previousVec); LatLon change = pos.subtract(previousPos); this.polygon.move(new Position(change.getLatitude(), change.getLongitude(), 0.0)); }
/** * Determine the point at which a ray intersects a the globe at the elevation of the polygon. * * @param ray Ray to intersect with the globe. * @return The point at which the ray intersects the globe at the elevation of the polygon. */ protected Vec4 intersectPolygonAltitudeAt(Line ray) { // If there are control points computed, use the elevation of the first control point as the // polygon elevation. // Otherwise, if there are no control points, intersect the globe at sea level double elevation = 0.0; if (this.controlPoints.size() > 0) { elevation = this.controlPoints.get(0).getPosition().getElevation(); } return AirspaceEditorUtil.intersectGlobeAt(this.wwd, elevation, ray); }
protected void setPolygonHeight(Point previousMousePoint, Point mousePoint) { // Find the closest points between the rays through each screen point, and the ray from the // control point // and in the direction of the globe's surface normal. Compute the elevation difference between // these two // points, and use that as the change in polygon height. Position referencePos = this.polygon.getReferencePosition(); if (referencePos == null) return; Vec4 referencePoint = this.wwd.getModel().getGlobe().computePointFromPosition(referencePos); Vec4 surfaceNormal = this.wwd .getModel() .getGlobe() .computeSurfaceNormalAtLocation( referencePos.getLatitude(), referencePos.getLongitude()); Line verticalRay = new Line(referencePoint, surfaceNormal); Line screenRay = this.wwd.getView().computeRayFromScreenPoint(mousePoint.getX(), mousePoint.getY()); Line previousScreenRay = this.wwd .getView() .computeRayFromScreenPoint(previousMousePoint.getX(), previousMousePoint.getY()); Vec4 pointOnLine = AirspaceEditorUtil.nearestPointOnLine(verticalRay, screenRay); Vec4 previousPointOnLine = AirspaceEditorUtil.nearestPointOnLine(verticalRay, previousScreenRay); Position pos = this.wwd.getModel().getGlobe().computePositionFromPoint(pointOnLine); Position previousPos = this.wwd.getModel().getGlobe().computePositionFromPoint(previousPointOnLine); double elevationChange = pos.getElevation() - previousPos.getElevation(); java.util.List<Position> boundary = new ArrayList<Position>(); for (LatLon ll : this.polygon.getOuterBoundary()) { boundary.add(new Position(ll, ((Position) ll).getElevation() + elevationChange)); } this.polygon.setOuterBoundary(boundary); }
/** * 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); }
protected void moveControlPoint( ControlPointMarker controlPoint, Point lastMousePoint, Point moveToPoint) { View view = this.wwd.getView(); Globe globe = this.wwd.getModel().getGlobe(); Position refPos = controlPoint.getPosition(); if (refPos == null) return; Line ray = view.computeRayFromScreenPoint(moveToPoint.getX(), moveToPoint.getY()); Line previousRay = view.computeRayFromScreenPoint(lastMousePoint.getX(), lastMousePoint.getY()); Vec4 vec = AirspaceEditorUtil.intersectGlobeAt(this.wwd, refPos.getElevation(), ray); Vec4 previousVec = AirspaceEditorUtil.intersectGlobeAt(this.wwd, refPos.getElevation(), previousRay); if (vec == null || previousVec == null) { return; } Position pos = globe.computePositionFromPoint(vec); Position previousPos = globe.computePositionFromPoint(previousVec); LatLon change = pos.subtract(previousPos); java.util.List<LatLon> boundary = new ArrayList<LatLon>(); for (LatLon ll : this.polygon.getOuterBoundary()) { boundary.add(ll); } boundary.set(controlPoint.getIndex(), new Position(pos.add(change), refPos.getAltitude())); // ExtrudedPolygon ensures that the last boundary position is the same as the first. Remove the // last point // before setting the boundary. boundary.remove(boundary.size() - 1); this.polygon.setOuterBoundary(boundary); }