analysispanel.java

来自「world wind java sdk 源码」· Java 代码 · 共 718 行 · 第 1/2 页

JAVA
718
字号
    private int getCurrentPositionNumber()    {        return this.trackViewPanel.getCurrentPositionNumber();    }    private boolean isLastPosition(int n)    {        return n >= this.currentTrack.size() - 1;    }    public Position getCurrentSegmentStartPosition()    {        int n = this.getCurrentPositionNumber();        return getSegmentStartPosition(n);    }    public Position getSegmentStartPosition(int startPositionNumber)    {        if (this.currentTrack == null || this.currentTrack.size() == 0)            return null;        Position pos;        if (isLastPosition(startPositionNumber))            pos = this.currentTrack.get(this.currentTrack.size() - 1);        else            pos = this.currentTrack.get(startPositionNumber);        return new Position(pos.getLatitude(), pos.getLongitude(), pos.getElevation() + this.currentTrack.getOffset());    }    public Position getCurrentSegmentEndPosition()    {        int n = this.getCurrentPositionNumber();        return getSegmentEndPosition(n);    }    public Position getSegmentEndPosition(int startPositionNumber)    {        if (this.currentTrack == null || this.currentTrack.size() == 0)            return null;        Position pos;        if (isLastPosition(startPositionNumber + 1))            pos = this.currentTrack.get(this.currentTrack.size() - 1);        else            pos = this.currentTrack.get(startPositionNumber + 1);        return new Position(pos.getLatitude(), pos.getLongitude(), pos.getElevation() + this.currentTrack.getOffset());    }    public double getSegmentLength(int startPositionNumber)    {        Vec4 start = wwd.getModel().getGlobe().computePointFromPosition(getSegmentStartPosition(startPositionNumber));        Vec4 end = wwd.getModel().getGlobe().computePointFromPosition(getSegmentEndPosition(startPositionNumber));        return start.distanceTo3(end);    }    public Position getPositionAlongSegment()    {        double t = this.trackViewPanel.getPositionDelta();        return this.getPositionAlongSegment(t);    }    private Position getPositionAlongSegment(double t)    {        Position pa = this.getCurrentSegmentStartPosition();        if (pa == null)            return null;        Position pb = this.getCurrentSegmentEndPosition();        if (pb == null)            return pa;        return interpolateTrackPosition(t, pa, pb);    }    public Angle getHeading()    {        return getHeading(this.getCurrentPositionNumber());    }    public Angle getHeading(int cpn)    {        Position pA;        Position pB;        if ((cpn < 1) && (this.isLastPosition(cpn))) //handle first position            return Angle.ZERO;        else if (!this.isLastPosition(cpn))        {            pA = this.currentTrack.get(cpn);            pB = this.currentTrack.get(cpn + 1);        }        else        {            pA = this.currentTrack.get(cpn - 1);            pB = this.currentTrack.get(cpn);        }        return LatLon.greatCircleAzimuth(pA, pB);    }    // Interpolate heading at track jonctions    private Angle getSmoothedHeading(double dt)    {        int cpn = this.getCurrentPositionNumber();        Angle heading1, heading2;        double t1, t;        // Current segment        heading1 = getHeading(cpn);        t1 = this.trackViewPanel.getPositionDelta();        if (t1 <= dt && cpn > 0)        {            heading2 = getHeading(cpn - 1);            t = (1 - t1 / dt) * .5;        }        else if (t1 >= (1 - dt) && !this.isLastPosition(cpn))        {            heading2 = getHeading(cpn + 1);            t = (1 - (1 - t1) / dt) * .5;        }        else            return heading1;        return Angle.mix(t, heading1, heading2);    }    @SuppressWarnings({"UnusedDeclaration"})    private Position getGroundPositionAlongSegment()    {        if (this.wwd == null)            return null;        Position pos = getPositionAlongSegment();        if (pos == null)            return null;        double elevation = this.wwd.getModel().getGlobe().getElevation(pos.getLatitude(), pos.getLongitude());        return new Position(pos, elevation);    }    // TODO: weighted average should be over actual polyline track points    private Position getSmoothedGroundPositionAlongSegment()    {        if (this.currentTrack == null || this.currentTrack.size() == 0)            return null;        Position start = getCurrentSegmentStartPosition();        Position end = getCurrentSegmentEndPosition();        if (start == null || end == null)            return null;        Globe globe = this.wwd.getModel().getGlobe();        if (globe == null)            return null;        int n = this.getCurrentPositionNumber();        double t = this.trackViewPanel.getPositionDelta();        // Limit t to 0 if this is the last position.        if (isLastPosition(n))            t = 0;        double tstep = 1 / 100.0;        int numWeights = 15; // TODO: extract to configurable property        double elev = 0;        double sumOfWeights = 0;        // Compute the moving weighted average of track positions on both sides of the current track position.        for (int i = 0; i < numWeights; i++)        {            double tt;            Position pos;            // Previous ground positions.            tt = t - i * tstep;            pos = null;            if (tt >= 0) // Position is in the current track segment.                pos = interpolateTrackPosition(tt, start, end);            else if (tt < 0 && n > 0) // Position is in the previous track segment.                pos = interpolateTrackPosition(tt + 1, this.currentTrack.get(n-1), start);            if (pos != null)            {                double e = globe.getElevation(pos.getLatitude(), pos.getLongitude());                elev += (numWeights - i) * e;                sumOfWeights += (numWeights - i);            }            // Next ground positions.            // We don't want to count the first position twice.            if (i != 0)            {                tt = t + i * tstep;                pos = null;                if (tt <= 1) // Position is in the current track segment.                    pos = interpolateTrackPosition(tt, start, end);                else if (tt > 1 && !isLastPosition(n + 1)) // Position is in the next track segment.                    pos = interpolateTrackPosition(tt - 1, end, this.currentTrack.get(n+2));                if (pos != null)                {                    double e = globe.getElevation(pos.getLatitude(), pos.getLongitude());                    elev += (numWeights - i) * e;                    sumOfWeights += (numWeights - i);                }            }        }        elev /= sumOfWeights;        Position actualPos = interpolateTrackPosition(t, start, end);        return new Position(actualPos, elev);    }    /**     * SAR tracks points are connected with lines of constant heading (rhumb lines). In order to compute     * an interpolated position between two track points, we must use rhumb computations, rather     * than linearly interpolate the position.     * @param t a decimal number between 0 and 1     * @param begin first position     * @param end second position     * @return Position in between begin and end     */    private Position interpolateTrackPosition(double t, Position begin, Position end)    {        if (begin == null || end == null)            return null;        // The track is drawn as a rhumb line.        // Therefore we must use rhumb computations to interpolate lat/lon.        Angle az = LatLon.rhumbAzimuth(begin, end);        Angle dist = LatLon.rhumbDistance(begin, end);        dist = dist.multiply(t);        LatLon ll = LatLon.rhumbEndPosition(begin, az, dist);        // Elevation is independent of track line type (i.e. rhumb, great-circle, linear),        // so we interpolate elevation normally.        double e = (1d - t) * begin.getElevation() + t * end.getElevation();        return new Position(ll, e);    }//    /**//     * Compute crosshair location in viewport for 'follow' - 'fly-it' mode.//     * <p>//     * It computes the intersection of the air track with the near clipping plane//     * and determines the corresponding crosshair position in the viewport.</p>//     * <p>//     * This assumes the view is headed in the same direction as the air track,//     * and the eye is set to look at the aircraft from a distance and angle.</p>//     *//     * @param view the current <code>View</code>//     * @param a view pitch angle relative to the air track (0 degree = horizontal)//     * @param distance eye distance from the aircraft//     * @return the crosshair center position in the viewport.//     *///    private Vec4 computeCrosshairPosition(View view, Angle a, double distance)//    {//        double hfovH = view.getFieldOfView().radians / 2; // half horizontal fov in radians//        double hw = view.getViewport().width / 2;         // half viewport width//        double hh = view.getViewport().height / 2;        // half viewport height//        double d = hw / Math.tan(hfovH);                  // distance to viewport plane in pixels//        // distance to near plane in meters//        double dNearMeter = Math.abs(view.getFrustum().getNear().getDistance());//        // crosshair elevation above viewport center in meter//        double dyMeter = (dNearMeter - distance) * Math.sin(a.radians);//        // corresponding vertical fov half angle//        double ay = Math.atan(dyMeter / dNearMeter);//        // corresponding viewport crosshair elevation in pixels//        double dy = Math.tan(ay) * d;//        // final crosshair viewport position//        return new Vec4(hw, hh + dy, 0, 0);//    }    // Mark crosshair as needing update after next render pass    private void updateCrosshair()    {        this.crosshairNeedsUpdate = true;        this.wwd.redraw();    }    // Update crosshair position to follow the air track    private void doUpdateCrosshair()    {        Vec4 crosshairPos = computeCrosshairPosition();        if (crosshairPos != null)        {            this.crosshairLayer.setEnabled(true);            this.crosshairLayer.setLocationCenter(crosshairPos);        }        else        {            this.crosshairLayer.setEnabled(false);        }        this.crosshairNeedsUpdate = false;    }    // Compute cartesian intersection between the current air track segment and the near plane.    // Follow rhumb line segments.    private Vec4 computeCrosshairPosition()    {        Position posA = getCurrentSegmentStartPosition();        Position posB = getCurrentSegmentEndPosition();        Angle segmentAzimuth = LatLon.rhumbAzimuth(posA, posB);        Angle segmentDistance = LatLon.rhumbDistance(posA, posB);        int numSubsegments = 10;  // TODO: get from track polyline        double step = 1d / numSubsegments;        // Extend the track segment ends by one subsegment to make sure it will intersect the near plane        double deltaElevation = posB.getElevation() - posA.getElevation();        LatLon latLon = LatLon.rhumbEndPosition(posA, segmentAzimuth.addRadians(Math.PI),            Angle.fromRadians(segmentDistance.radians / numSubsegments));        posA = new Position(latLon, posA.getElevation() - deltaElevation / numSubsegments);        latLon = LatLon.rhumbEndPosition(posB, segmentAzimuth,            Angle.fromRadians(segmentDistance.radians / numSubsegments));        posB = new Position(latLon, posB.getElevation() + deltaElevation / numSubsegments);        segmentDistance = LatLon.rhumbDistance(posA, posB);        // Iterate through segments to find intersection        Globe globe = this.wwd.getModel().getGlobe();        Plane near = this.wwd.getView().getFrustumInModelCoordinates().getNear();        Position p1 = null, p2;        for (double s = 0; s <= 1; s += step)        {            if (s == 0)                p2 = posA;            else if (s >= 1)                p2 = posB;            else            {                Angle distance = Angle.fromRadians(s * segmentDistance.radians);                latLon = LatLon.rhumbEndPosition(posA, segmentAzimuth, distance);                p2 = new Position(latLon, (1 - s) * posA.getElevation() + s * posB.getElevation());            }            if (p1 != null)            {                Vec4 pa = globe.computePointFromPosition(p1);                Vec4 pb = globe.computePointFromPosition(p2);                if(pa.distanceTo3(pb) > 0)                {                    Vec4 intersection = near.intersect(pa, pb);                    if (intersection != null)                    {                        return this.wwd.getView().project(intersection);                    }                }            }            p1 = p2;        }        return null;    }    private void initComponents()    {        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));                        this.trackViewPanel = new TrackViewPanel(this);        this.trackViewPanel.setAlignmentX(Component.LEFT_ALIGNMENT);        add(this.trackViewPanel);        this.terrainProfilePanel = new TerrainProfilePanel();        this.terrainProfilePanel.setAlignmentX(Component.LEFT_ALIGNMENT);        add(this.terrainProfilePanel);    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?