Пример #1
0
        /**
         * Set the value of the field being animated based on the given interpolant.
         * @param interpolant A value between 0 and 1.
         */
        public void set(double interpolant)
        {
            const int    MAX_SMOOTHING = 1;
            const double ZOOM_START    = 0.0;
            const double ZOOM_STOP     = 1.0;

            if (interpolant >= 1.0)
            {
                this.stop();
            }
            double zoomInterpolant;

            if (this.UseMidZoom)
            {
                double value;
                zoomInterpolant = this.zoomInterpolant(interpolant, ZOOM_START, ZOOM_STOP, MAX_SMOOTHING);
                if (interpolant <= .5)
                {
                    value = nextDouble(zoomInterpolant, this.Begin, this.End);
                }
                else
                {
                    value = nextDouble(zoomInterpolant, this.End, this.trueEndZoom);
                }
                this.propertyAccessor.setDouble(value);
            }
            else
            {
                zoomInterpolant = AnimationSupport.basicInterpolant(interpolant, ZOOM_START, ZOOM_STOP, MAX_SMOOTHING);
                base.set(zoomInterpolant);
            }
        }
Пример #2
0
        /**
         * Computes the value for the given interpolant.
         *
         * @param interpolant the interpolant to use for interpolating
         * @param start the lower end of the interpolated range.
         * @param end the upper end of the interpolated range.
         * @return the interpolated value.
         */
        protected double nextDouble(double interpolant, double start, double end)
        {
            double elevation = AnimationSupport.mixDouble(
                interpolant,
                start,
                end);

            // Check the altitude mode. If the altitude mode depends on the surface elevation we will reevaluate the
            // end position altitude. When the animation starts we may not have accurate elevation data available for
            // the end position, so recalculating the elevation as we go ensures that the animation will end at the
            // correct altitude.
            double endElevation         = 0.0;
            bool   overrideEndElevation = false;

            if (this.globe != null && this.altitudeMode == WorldWind.CLAMP_TO_GROUND)
            {
                overrideEndElevation = true;
                endElevation         = this.globe.getElevation(endLatLon.getLatitude(), endLatLon.getLongitude());
            }
            else if (this.globe != null && this.altitudeMode == WorldWind.RELATIVE_TO_GROUND)
            {
                overrideEndElevation = true;
                endElevation         = this.globe.getElevation(endLatLon.getLatitude(), endLatLon.getLongitude()) + end;
            }

            if (overrideEndElevation)
            {
                elevation = (1 - interpolant) * start + interpolant * endElevation;
            }

            return(elevation);
        }
Пример #3
0
        /**
         * Create an animator to animate heading, pitch, and roll.
         *
         * @param view         View to animate
         * @param beginHeading staring heading
         * @param endHeading   final heading
         * @param beginPitch   starting pitch
         * @param endPitch     final pitch
         * @param beginRoll    starting roll
         * @param endRoll      final roll
         *
         * @return A CompoundAnimator to animate heading, pitch, and roll.
         */
        public static CompoundAnimator createHeadingPitchRollAnimator(View view, Angle beginHeading, Angle endHeading,
                                                                      Angle beginPitch, Angle endPitch, Angle beginRoll, Angle endRoll)
        {
            if (beginHeading == null || endHeading == null || beginPitch == null || endPitch == null || beginRoll == null ||
                endRoll == null)
            {
                String message = Logging.getMessage("nullValue.AngleIsNull");
                Logging.logger().severe(message);
                throw new ArgumentException(message);
            }

            const long MIN_LENGTH_MILLIS   = 500;
            const long MAX_LENGTH_MILLIS   = 3000;
            long       headingLengthMillis = AnimationSupport.getScaledTimeMillisecs(
                beginHeading, endHeading, Angle.POS180,
                MIN_LENGTH_MILLIS, MAX_LENGTH_MILLIS);
            long pitchLengthMillis = AnimationSupport.getScaledTimeMillisecs(
                beginPitch, endPitch, Angle.POS90,
                MIN_LENGTH_MILLIS, MAX_LENGTH_MILLIS / 2L);
            long rollLengthMillis = AnimationSupport.getScaledTimeMillisecs(
                beginRoll, endRoll, Angle.POS90,
                MIN_LENGTH_MILLIS, MAX_LENGTH_MILLIS / 2L);
            long lengthMillis = headingLengthMillis + pitchLengthMillis + rollLengthMillis;

            AngleAnimator headingAnimator = createHeadingAnimator(view, beginHeading, endHeading);
            AngleAnimator pitchAnimator   = createPitchAnimator(view, beginPitch, endPitch);
            AngleAnimator rollAnimator    = createRollAnimator(view, beginRoll, endRoll);

            CompoundAnimator headingPitchAnimator = new CompoundAnimator(new ScheduledInterpolator(lengthMillis),
                                                                         headingAnimator, pitchAnimator, rollAnimator);

            return(headingPitchAnimator);
        }
Пример #4
0
        protected static double basicInterpolant(double interpolant, double startInterpolant,
                                                 double stopInterpolant,
                                                 int maxSmoothing)
        {
            var normalizedInterpolant = AnimationSupport.interpolantNormalized(interpolant, startInterpolant,
                                                                               stopInterpolant);

            return(AnimationSupport.interpolantSmoothed(normalizedInterpolant, maxSmoothing));
        }
Пример #5
0
        protected static double computeMidZoom(
            Globe globe,
            LatLon beginLatLon, LatLon endLatLon,
            double beginZoom, double endZoom)
        {
            // Scale factor is angular distance over 180 degrees.
            Angle  sphericalDistance = LatLon.greatCircleDistance(beginLatLon, endLatLon);
            double scaleFactor       = AnimationSupport.angularRatio(sphericalDistance, Angle.POS180);

            // Mid-point zoom is interpolated value between minimum and maximum zoom.
            double MIN_ZOOM = Math.Min(beginZoom, endZoom);
            double MAX_ZOOM = 3.0 * globe.getRadius();

            return(AnimationSupport.mixDouble(scaleFactor, MIN_ZOOM, MAX_ZOOM));
        }
Пример #6
0
        /**
         * Create an animator to animate heading.
         *
         * @param view  View to animate
         * @param begin starting heading
         * @param end   final heading
         *
         * @return An Animator to animate heading.
         */
        public static AngleAnimator createHeadingAnimator(View view, Angle begin, Angle end)
        {
            if (begin == null || end == null)
            {
                String message = Logging.getMessage("nullValue.AngleIsNull");
                Logging.logger().severe(message);
                throw new ArgumentException(message);
            }

            const long MIN_LENGTH_MILLIS = 500;
            const long MAX_LENGTH_MILLIS = 3000;
            long       lengthMillis      = AnimationSupport.getScaledTimeMillisecs(
                begin, end, Angle.POS180,
                MIN_LENGTH_MILLIS, MAX_LENGTH_MILLIS);

            return(new AngleAnimator(new ScheduledInterpolator(lengthMillis),
                                     begin, end, new ViewPropertyAccessor.HeadingAccessor(view)));
        }
Пример #7
0
        private double zoomInterpolant(double interpolant, double startInterpolant, double stopInterpolant,
                                       int maxSmoothing)
        {
            // Map interpolant in to range [start, stop].
            double normalizedInterpolant = AnimationSupport.interpolantNormalized(
                interpolant, startInterpolant, stopInterpolant);

            // During first half of iteration, zoom increases from begin to mid,
            // and decreases from mid to end during second half.
            if (normalizedInterpolant <= 0.5)
            {
                normalizedInterpolant = (normalizedInterpolant * 2.0);
            }
            else
            {
                normalizedInterpolant = ((normalizedInterpolant - .5) * 2.0);
            }

            return(AnimationSupport.interpolantSmoothed(normalizedInterpolant, maxSmoothing));
        }
Пример #8
0
            protected Position nextPosition(double interpolant)
            {
                const int MAX_SMOOTHING = 1;

                double CENTER_START      = this.useMidZoom ? 0.2 : 0.0;
                double CENTER_STOP       = this.useMidZoom ? 0.8 : 0.8;
                double latLonInterpolant = AnimationSupport.basicInterpolant(interpolant, CENTER_START, CENTER_STOP,
                                                                             MAX_SMOOTHING);

                // Invoke the standard next position functionality.
                Position pos = base.nextPosition(latLonInterpolant);

                // Check the altitude mode. If the altitude mode depends on the surface elevation we will reevaluate the
                // end position altitude. When the animation starts we may not have accurate elevation data available for
                // the end position, so recalculating the elevation as we go ensures that the animation will end at the
                // correct altitude.
                double endElevation         = 0.0;
                bool   overrideEndElevation = false;

                if (this.altitudeMode == WorldWind.CLAMP_TO_GROUND)
                {
                    overrideEndElevation = true;
                    endElevation         = this.globe.getElevation(getEnd().getLatitude(), getEnd().getLongitude());
                }
                else if (this.altitudeMode == WorldWind.RELATIVE_TO_GROUND)
                {
                    overrideEndElevation = true;
                    endElevation         = this.globe.getElevation(getEnd().getLatitude(), getEnd().getLongitude())
                                           + getEnd().getAltitude();
                }

                if (overrideEndElevation)
                {
                    LatLon ll = pos; // Use interpolated lat/lon.
                    double e1 = getBegin().getElevation();
                    pos = new Position(ll, (1 - latLonInterpolant) * e1 + latLonInterpolant * endElevation);
                }

                return(pos);
            }