Project

General

Profile

Download (9.17 KB) Statistics
| Branch: | Revision:

library / src / main / java / org / distorted / library / Interpolator.java @ e0a16874

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.library;
21

    
22
import java.util.Random;
23

    
24
///////////////////////////////////////////////////////////////////////////////////////////////////
25
/** A class to interpolate between a List of Float{1,2,3,4}Ds.
26
* <p><ul>
27
* <li>if there is only one Point, just jump to it.
28
* <li>if there are two Points, linearly bounce between them
29
* <li>if there are more, interpolate a loop (or a path!) between them.
30
* </ul>
31
*/
32

    
33
// The way Interpolation between more than 2 Points is done:
34
// 
35
// Def: let w[i] = (w[i](x), w[i](y), w[i](z)) be the direction and speed we have to be flying at Point P[i]
36
//
37
// time it takes to fly though one segment v[i] --> v[i+1] : 0.0 --> 1.0
38
// w[i] should be parallel to v[i+1] - v[i-1]   (cyclic notation)
39
// |w[i]| proportional to | P[i]-P[i+1] |
40
//
41
// Given that the flight route (X(t), Y(t), Z(t)) from P(i) to P(i+1)  (0<=t<=1) has to satisfy
42
// X(0) = P[i  ](x), Y(0)=P[i  ](y), Z(0)=P[i  ](z), X'(0) = w[i  ](x), Y'(0) = w[i  ](y), Z'(0) = w[i  ](z)
43
// X(1) = P[i+1](x), Y(1)=P[i+1](y), Z(1)=P[i+1](z), X'(1) = w[i+1](x), Y'(1) = w[i+1](y), Z'(1) = w[i+1](z)
44
//
45
// we have the solution:  X(t) = at^3 + bt^2 + ct + d where
46
// a =  2*P[i](x) +   w[i](x) - 2*P[i+1](x) + w[i+1](x)
47
// b = -3*P[i](x) - 2*w[i](x) + 3*P[i+1](x) - w[i+1](x)
48
// c = w[i](x)<br>
49
// d = P[i](x)
50
//
51
// and similarly Y(t) and Z(t).
52

    
53
public abstract class Interpolator 
54
  {
55
  /**
56
   * One revolution takes us from the first vector to the last and back to first through the shortest path. 
57
   */
58
  public static final int MODE_LOOP = 0; 
59
  /**
60
   * We come back from the last to the first vector through the same way we got there.
61
   */
62
  public static final int MODE_PATH = 1; 
63
  /**
64
   * We just jump back from the last point to the first.
65
   */
66
  public static final int MODE_JUMP = 2; 
67
 
68
  protected static Random mRnd = new Random();
69
  
70
  protected static final int NUM_NOISE = 5; // used iff mNoise>0.0. Number of intermediary points between each pair of adjacent vectors
71
                                            // where we randomize noise factors to make the way between the two vectors not so smooth.
72
  protected int numPoints;
73
  protected int mVecCurr;    
74
  protected boolean cacheDirty; // VectorCache not up to date
75
  protected int mMode;          // LOOP, PATH or JUMP
76
  protected long mDuration;     // number of miliseconds it takes to do a full loop/path from first vector to the last and back to the first 
77
  protected float mCount;       // number of loops/paths we will do; mCount = 1.5 means we go from the first vector to the last, back to first, and to the last again. 
78
  protected float mNoise;       // how 'smooth' our path form each vector to the next is. mNoise = 0.0 (min) --> completely smooth; mNoise==1.0 (max) --> very uneven
79
  
80
///////////////////////////////////////////////////////////////////////////////////////////////////
81
// hide this from Javadoc
82
  
83
  Interpolator()
84
    {
85
    }
86
  
87
///////////////////////////////////////////////////////////////////////////////////////////////////
88
  
89
  public void interpolateMain(float[] buffer, int offset, long currentDuration)
90
    {
91
    if( mDuration<=0.0f ) 
92
      {
93
      interpolate(buffer,offset,mCount-(int)mCount);  
94
      }
95
    else
96
      {
97
      float x = (float)currentDuration/mDuration;
98
           
99
      if( x<=mCount || mCount<=0.0f )
100
        {
101
        interpolate(buffer,offset,x-(int)x);
102
        }
103
      }
104
    }
105
  
106
///////////////////////////////////////////////////////////////////////////////////////////////////
107

    
108
  public boolean interpolateMain(float[] buffer, int offset, long currentDuration, long step)
109
    {
110
    if( mDuration<=0.0f ) 
111
      {
112
      interpolate(buffer,offset,mCount-(int)mCount);
113
      return false;
114
      }
115
     
116
    float x = (float)currentDuration/mDuration;
117
           
118
    if( x<=mCount || mCount<=0.0f )
119
      {
120
      interpolate(buffer,offset,x-(int)x);
121
        
122
      if( currentDuration+step > mDuration*mCount && mCount>0.0f )
123
        {
124
        interpolate(buffer,offset,mCount-(int)mCount);
125
        return true;
126
        }
127
      }
128
    
129
    return false;
130
    }
131
 
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133
// internal debugging only!
134
  
135
  String print()
136
    {
137
    return "duration="+mDuration+" count="+mCount+" Noise="+mNoise+" numVectors="+numPoints+" mMode="+mMode;
138
    }
139
  
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141
  
142
  abstract void interpolate(float[] buffer, int offset, float time);
143
  abstract void createNoise();
144

    
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146
// PUBLIC API
147
///////////////////////////////////////////////////////////////////////////////////////////////////
148
/**
149
 * Sets the mode of the interpolation to Loop, Path or Jump.
150
 * <ul>
151
 * <li>Loop is when we go from the first point all the way to the last, and the back to the first through 
152
 * the shortest way.
153
 * <li>Path is when we come back from the last point back to the first the same way we got there.
154
 * <li>Jump is when we go from first to last and then jump back to the first.
155
 * </ul>
156
 * 
157
 * @param mode {@link Interpolator#MODE_LOOP}, {@link Interpolator#MODE_PATH} or {@link Interpolator#MODE_JUMP}.
158
 */
159

    
160
  public void setMode(int mode)
161
    {
162
    mMode = mode;  
163
    }
164

    
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166
/**
167
 * Returns the number of Float{1,2,3,4}Ds this Interpolator has been fed with.
168
 *   
169
 * @return the number of Float{1,2,3,4}Ds we are currently interpolating through.
170
 */
171
  public synchronized int getNumPoints()
172
    {
173
    return numPoints;  
174
    }
175

    
176
///////////////////////////////////////////////////////////////////////////////////////////////////
177
/**
178
 * Controls how many times we want to interpolate.
179
 * <p>
180
 * Count equal to 1 means 'go from the first Float{1,2,3,4}D to the last and back'. Does not have to be an
181
 * integer - i.e. count=1.5 would mean 'start at the first Point, go to the last, come back to the first, 
182
 * go to the last again and stop'.
183
 * Count<=0 means 'go on interpolating indefinitely'.
184
 * 
185
 * @param count the number of times we want to interpolate between our collection of Float{1,2,3,4}Ds.
186
 */
187
  public void setCount(float count)
188
    {
189
    mCount = count;  
190
    }
191

    
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193
/**
194
 * Sets the time it takes to do one full interpolation.
195
 * 
196
 * @param duration Time, in milliseconds, it takes to do one full interpolation, i.e. go from the first 
197
 *                 Point to the last and back. 
198
 */
199
  
200
  public void setDuration(long duration)
201
    {
202
    mDuration = duration;
203
    }
204

    
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206
/**
207
 * Sets the 'smoothness' of interpolation. 
208
 * <p>
209
 * When Noise=0 (the default), we interpolate between our Points through the most smooth path possible. 
210
 * Increasing noise makes the Interpolator increasingly deviate from this path, pseudo-randomly speeding 
211
 * up and slowing down, etc.
212
 * 
213
 * @param noise The noise level. Permitted range: 0 <= noise <= 1.
214
 */
215
  
216
  public void setNoise(float noise)
217
    {
218
    if( mNoise==0.0f && noise != 0.0f )  
219
      createNoise();
220
   
221
    if( mNoise<0.0f ) mNoise = 0.0f;
222
    if( mNoise>1.0f ) mNoise = 1.0f;
223
   
224
    mNoise = noise;
225
    }
226

    
227
///////////////////////////////////////////////////////////////////////////////////////////////////
228
// end of DistortedInterpolator
229
  }
(25-25/30)