001/*
002        AUTOMATICALLY GENERATED BY jTemp FROM
003        /Users/jsh2/Work/openimaj/target/checkout/content/animation/src/main/jtemp/org/openimaj/content/animation/animator/RandomLinear#TT#ValueAnimator.jtemp
004*/
005/**
006 * Copyright (c) 2011, The University of Southampton and the individual contributors.
007 * All rights reserved.
008 *
009 * Redistribution and use in source and binary forms, with or without modification,
010 * are permitted provided that the following conditions are met:
011 *
012 *   *  Redistributions of source code must retain the above copyright notice,
013 *      this list of conditions and the following disclaimer.
014 *
015 *   *  Redistributions in binary form must reproduce the above copyright notice,
016 *      this list of conditions and the following disclaimer in the documentation
017 *      and/or other materials provided with the distribution.
018 *
019 *   *  Neither the name of the University of Southampton nor the names of its
020 *      contributors may be used to endorse or promote products derived from this
021 *      software without specific prior written permission.
022 *
023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
024 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
025 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
026 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
027 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
028 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
029 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
030 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
031 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
032 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
033 */
034package org.openimaj.content.animation.animator;
035
036import cern.jet.random.Uniform;
037import cern.jet.random.engine.MersenneTwister;
038
039/**
040 * A {@link ValueAnimator} that continuously animates between
041 * randomly selected values in a range. Once the stop value 
042 * has been reached, the animator chooses a new random target
043 * value. 
044 * 
045 * Each animation between values is linear and has a fixed
046 * duration. 
047 * 
048 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
049 *
050 */
051public class RandomLinearFloatValueAnimator implements ValueAnimator<Float> {
052        private int seed;
053        
054        Uniform rng;
055        LinearFloatValueAnimator animator;
056        private float min;
057        private float max;
058        private int duration;
059        
060        /**
061         * Construct a {@link RandomLinearFloatValueAnimator} with the given
062         * range and duration for each sub-animation.
063         * 
064         * @param min minimum allowed value
065         * @param max maximum allowed value
066         * @param duration duration between values
067         */
068        public RandomLinearFloatValueAnimator(float min, float max, int duration) {
069                seed = (int) System.nanoTime();
070
071                this.min = min;
072                this.max = max;
073                this.duration = duration;
074                
075                reset();
076        }
077        
078        /**
079         * Construct a {@link RandomLinearFloatValueAnimator} with the given
080         * range, duration for each sub-animation and fixed initial value.
081         * 
082         * @param min minimum allowed value
083         * @param max maximum allowed value
084         * @param duration duration between values
085         * @param initial initial starting value
086         */
087        public RandomLinearFloatValueAnimator(float min, float max, int duration, float initial) {
088                this(min, max, duration);
089                setNextAnimator(initial);
090        }
091        
092        /**
093         * Construct a {@link RandomLinearFloatValueAnimator} with the given
094         * range and duration for each sub-animation.
095         * 
096         * The sub-animations will start after startWait ticks, and 
097         * finish stopWait ticks after startWait+duration.
098         * 
099         * @param startWait amount of time in ticks to wait before starting animation.
100         * @param stopWait amount of time in ticks to wait after finishing animation. 
101         * @param min minimum allowed value
102         * @param max maximum allowed value
103         * @param duration duration between values
104         */
105        public RandomLinearFloatValueAnimator(int startWait, int stopWait, float min, float max, int duration) {
106                seed = (int) System.currentTimeMillis();
107
108                this.min = min;
109                this.max = max;
110                this.duration = duration;
111                
112                reset();
113        }
114        
115        /**
116         * Construct a {@link RandomLinearFloatValueAnimator} with the given
117         * range, duration for each sub-animation and fixed initial value.
118         * 
119         * The sub-animations will start after startWait ticks, and 
120         * finish stopWait ticks after startWait+duration.
121         * 
122         * @param startWait amount of time in ticks to wait before starting animation.
123         * @param stopWait amount of time in ticks to wait after finishing animation. 
124         * @param min minimum allowed value
125         * @param max maximum allowed value
126         * @param duration duration between values
127         * @param initial initial starting value
128         */
129        public RandomLinearFloatValueAnimator(int startWait, int stopWait, float min, float max, int duration, float initial) {
130                this(min, max, duration);
131                setNextAnimator(initial);
132        }
133        
134        @Override
135        public Float nextValue() {
136                if (animator.hasFinished()) {
137                        setNextAnimator(animator.nextValue());
138                }
139
140                return animator.nextValue();
141        }
142
143        @Override
144        public boolean hasFinished() {
145                return false;
146        }
147
148        @Override
149        public void reset() {
150                rng = new Uniform(new MersenneTwister(seed));
151                
152                float v1 = (float)rng.nextFloatFromTo(min, max);
153                setNextAnimator(v1);
154        }
155        
156        protected void setNextAnimator(float v1) {
157                float v2 = (float)rng.nextFloatFromTo(min, max);
158                
159                animator = new LinearFloatValueAnimator(v1, v2, duration);
160        }
161}