All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.gov.nasa.worldwind.animation.AnimationSupport Maven / Gradle / Ivy

Go to download

World Wind is a collection of components that interactively display 3D geographic information within Java applications or applets.

There is a newer version: 2.0.0-986
Show newest version
/*
 * Copyright (C) 2012 United States Government as represented by the Administrator of the
 * National Aeronautics and Space Administration.
 * All Rights Reserved.
 */
package gov.nasa.worldwind.animation;

import gov.nasa.worldwind.geom.*;
import gov.nasa.worldwind.util.Logging;

/**
 * @author jym
 * @version $Id: AnimationSupport.java 1171 2013-02-11 21:45:02Z dcollins $
 */
public class AnimationSupport
{

    /**
     * Calcualte a scaled time based on the great circle distance between two points.  The time is calulated by
     * interpolating between the minLengthMillis and the maxLengthMillis using the ratio
     * of the spherical distance between the given positions over 180 degrees.
     *
     * @param beginLatLon The first geographic position
     * @param endLatLon The second geographio position
     * @param minTimeMillis The minimum length of tine
     * @param maxTimeMillis The maximum length of time
     * @return The scaled time in milliseconds.
     */
    public static long getScaledTimeMillisecs(
            LatLon beginLatLon, LatLon endLatLon,
            long minTimeMillis, long maxTimeMillis)
    {
        Angle sphericalDistance = LatLon.greatCircleDistance(beginLatLon, endLatLon);
        double scaleFactor = angularRatio(sphericalDistance, Angle.POS180);
        return (long) mixDouble(scaleFactor, minTimeMillis, maxTimeMillis);
    }

    /**
     * Calculate a scaled tiome based on the ratio of the angular distance between the begin and
     * end angles over the max value.
     *
     * @param begin the begin angle
     * @param end the end angle
     * @param max the maximun number of degrees
     * @param minTimeMillisecs the minimum length of time
     * @param maxTimeMillisecs the maximum length of time
     * @return the scaled time in milliseconds
     */
    public static long getScaledTimeMillisecs(
        Angle begin, Angle end, Angle max,
        long minTimeMillisecs, long maxTimeMillisecs)
    {
        Angle angularDistance = begin.angularDistanceTo(end);
        double scaleFactor = angularRatio(angularDistance, max);
        return (long) mixDouble(scaleFactor, minTimeMillisecs, maxTimeMillisecs);
    }

    /**
     * Calculate a scaled time based on the ratio of the distance between the beginZoom and
     * endZoom distances over the larger of the beginZoom and endZoom.
     *
     * @param beginZoom the begin zoom value
     * @param endZoom the end zoom value
     * @param minTimeMillisecs the minimum length of time
     * @param maxTimeMillisecs the maximum length of time
     * @return the scaled time in milliseconds
     */
    public static long getScaledTimeMillisecs(
        double beginZoom, double endZoom,
        long minTimeMillisecs, long maxTimeMillisecs)
    {
        double scaleFactor = Math.abs(endZoom - beginZoom) / Math.max(endZoom, beginZoom);
        // Clamp scaleFactor to range [0, 1].
        scaleFactor = clampDouble(scaleFactor, 0.0, 1.0);
        // Iteration time is interpolated value between minumum and maximum lengths.
        return (long) mixDouble(scaleFactor, minTimeMillisecs, maxTimeMillisecs);
    }

    /**
     * Calculate the angular ratio between two angles
     * @param x The numerator
     * @param y The denominator
     * @return The angular ratio of x/y>
     */
    public static double angularRatio(Angle x, Angle y)
    {
        if (x == null || y == null)
        {
            String message = Logging.getMessage("nullValue.AngleIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        double unclampedRatio = x.divide(y);
        return clampDouble(unclampedRatio, 0, 1);
    }

    /**
     * Calculate the linear interpolation between two values
     *
     * @param amount The interpolant, a number between 0 and 1.
     * @param value1 The minimum value of the range
     * @param value2 The maximum value of the range
     * @return the interpolated value
     */
    public static double mixDouble(double amount, double value1, double value2)
    {
        if (amount < 0)
            return value1;
        else if (amount > 1)
            return value2;
        return value1 * (1.0 - amount) + value2 * amount;
    }

    /**
     * Clamps a value between a minimum and maximum
     *
     * @param value the value to clamo
     * @param min the minimum
     * @param max the maximum
     * @return the clamped value
     */
    public static double clampDouble(double value, double min, double max)
    {
        return value < min ? min : (value > max ? max : value);
    }

    /**
     * Normalize an interpolant value
     *
     * @param amount The value to normalize
     * @param startAmount The lower end of the range
     * @param stopAmount  The upper end of the range
     * @return the normalized interpolant
     */
    public static double interpolantNormalized(double amount, double startAmount,
        double stopAmount)
    {
        if (amount < startAmount)
            return 0.0;
        else if (amount > stopAmount)
            return 1.0;
        if ((stopAmount - startAmount) == 0)
        {
            return(1.0);
        }
        return (amount - startAmount) / (stopAmount - startAmount);
    }

    /**
     * Smooth an interpolant value using hermite smoothing
     *
     * @param interpolant The interpolant
     * @param smoothingIterations the number of smoothing iterations
     * @return the smoothed interpolant
     */
    public static double interpolantSmoothed(double interpolant, int smoothingIterations)
    {
        // Apply iterative hermite smoothing.
        double smoothed = interpolant;
        for (int i = 0; i < smoothingIterations; i++)
        {
            smoothed = smoothed * smoothed * (3.0 - 2.0 * smoothed);
        }
        return smoothed;
    }

    /**
     * Calculate a normalized, smoothed interpolant
     * @param interpolant the unsmoothed, unnormalized interpolant
     * @param startInterpolant the lower end of interpolant range
     * @param stopInterpolant the higher end of the interpolant range
     * @param maxSmoothing the numver of iterations to smooth.
     * @return the normalized, smoothed interpolant
     */
    public static double basicInterpolant(double interpolant, double startInterpolant, double stopInterpolant,
        int maxSmoothing)
    {
        double normalizedInterpolant = interpolantNormalized(interpolant, startInterpolant, stopInterpolant);
        return interpolantSmoothed(normalizedInterpolant, maxSmoothing);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy