SuperTuxKart
Loading...
Searching...
No Matches
interpolation_array.hpp
1//
2// SuperTuxKart - a fun racing game with go-kart
3// Copyright (C) 2012-2015 Joerg Henrichs
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 3
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19
20#ifndef HEADER_INTERPOLATION_ARRAY_HPP
21#define HEADER_INTERPOLATION_ARRAY_HPP
22
23#include <assert.h>
24#include <vector>
25
32{
33private:
35 std::vector<float> m_x;
36
38 std::vector<float> m_y;
39
40 /* Pre-computed (x[i+1]-x[i])/(y[i+1]/-y[i]) . */
41 std::vector<float> m_delta;
42
43public:
45
47 void clear()
48 {
49 m_x.clear();
50 m_y.clear();
51 m_delta.clear();
52 }
53
58 int push_back(float x, float y)
59 {
60 if(m_x.size()>0 && x < m_x[m_x.size()-1])
61 return 0;
62 m_x.push_back(x);
63 m_y.push_back(y);
64 if(m_y.size()>1)
65 {
66 const unsigned int last=(unsigned int) m_x.size()-1;
67 // Avoid division by zero, just set m_delta to a large
68 // value with the right sign
69 if(m_x[last]==m_x[last-1])
70 m_delta.push_back( (m_y[last]-m_y[last-1])
71 / 0.001f );
72 else
73 m_delta.push_back( (m_y[last]-m_y[last-1])
74 /(m_x[last]-m_x[last-1]) );
75 }
76 return 1;
77 } // push_back
78 // ------------------------------------------------------------------------
80 unsigned int size() const { return (unsigned int) m_x.size(); }
81 // ------------------------------------------------------------------------
83 float getX(unsigned int i) const { return m_x[i]; }
84 // ------------------------------------------------------------------------
86 float getY(unsigned int i) const { return m_y[i]; }
87 // ------------------------------------------------------------------------
89 void setY(unsigned int i, float y)
90 {
91 m_y[i] = y;
92 if(i>0)
93 m_delta[i-1] = (m_y[i]-m_y[i-1])
94 /(m_x[i]-m_x[i-1]);
95 if(i<m_y.size()-1)
96 m_delta[i] = (m_y[i+1]-m_y[i])
97 /(m_x[i+1]-m_x[i]);
98 }
99 // ------------------------------------------------------------------------
101 float get(float x) const
102 {
103 if(m_x.size()==1 || x<m_x[0])
104 return m_y[0];
105
106 if(x>m_x[m_x.size()-1])
107 return m_y[m_y.size()-1];
108
109 // Now x must be between two points in m_x
110 // The array size in STK are pretty small (typically 3 or 4),
111 // so not worth the effort to do a binary search
112 for(unsigned int i=1; i<m_x.size(); i++)
113 {
114 if(x >m_x[i]) continue;
115 return m_y[i-1] + m_delta[i-1] * (x - m_x[i-1]);
116 }
117 assert(false); return 0; // keep compiler happy
118 } // get
119
120 // ------------------------------------------------------------------------
124 float getReverse(float y) const
125 {
126 if(m_y.size()==1) return m_x[0];
127
128 if(m_y[1]<m_y[0]) // if decreasing values
129 {
130 if(y > m_y[0]) return m_x[0];
131
132 const unsigned int last = (unsigned int) m_x.size();
133
134 for(unsigned int i=1; i<last; i++)
135 {
136 if(y < m_y[i]) continue;
137 return m_x[i-1] + (y-m_y[i-1])/ m_delta[i-1];
138 } // for i < last
139 return m_x[last-1];
140 }
141 else // increasing
142 {
143 if(y < m_y[0]) return m_x[0];
144
145 const unsigned int last = (unsigned int) m_x.size();
146
147 for(unsigned int i=1; i<last; i++)
148 {
149 if(y > m_y[i]) continue;
150 return m_x[i-1] + (y-m_y[i-1]) / m_delta[i-1];
151 } // for i < last
152 return m_x[last-1];
153 } // increasing
154 } // getReverse
155}; // InterpolationArray
156
157
158#endif
This class manages a set of (x_i,y_i) points, x_i must be sorted.
Definition: interpolation_array.hpp:32
void setY(unsigned int i, float y)
Sets the Y value for a specified point.
Definition: interpolation_array.hpp:89
float getReverse(float y) const
Returns the X value necessary for a specified Y value.
Definition: interpolation_array.hpp:124
float getX(unsigned int i) const
Returns the X value for a specified point.
Definition: interpolation_array.hpp:83
float get(float x) const
Returns the interpolated Y value for a given x.
Definition: interpolation_array.hpp:101
unsigned int size() const
Returns the number of X/Y points.
Definition: interpolation_array.hpp:80
std::vector< float > m_y
The y values.
Definition: interpolation_array.hpp:38
float getY(unsigned int i) const
Returns the Y value for a specified point.
Definition: interpolation_array.hpp:86
std::vector< float > m_x
The sorted x values.
Definition: interpolation_array.hpp:35
int push_back(float x, float y)
Adds the value pair x/y to the list of all points.
Definition: interpolation_array.hpp:58
void clear()
Removes all saved values from this object.
Definition: interpolation_array.hpp:47