@@ -128,11 +128,14 @@ inline X Spline<X,Y>::solve( X x, typename PointContainer::const_iterator &segme
128
128
// If we hit the end of the points while searching, return the end point of the last valid segment
129
129
// this is just a linear search right now - it should be possible to optimise this using points.lower_bound
130
130
// to quickly find a better start point for the search.
131
- X co[4 ];
132
- basis.coefficients ( X ( 1 ), co );
131
+ X endCo[4 ];
132
+ basis.coefficients ( X ( 1 ), endCo );
133
+ X startCo[4 ];
134
+ basis.coefficients ( X ( 0 ), startCo );
133
135
X xp[4 ] = { X (0 ), X (0 ), X (0 ), X (0 ) };
134
136
135
137
segment = points.begin ();
138
+ It prevSegment = segment;
136
139
for ( int pointNum = 0 ;; pointNum += basis.step )
137
140
{
138
141
It xIt ( segment );
@@ -142,8 +145,20 @@ inline X Spline<X,Y>::solve( X x, typename PointContainer::const_iterator &segme
142
145
xIt++;
143
146
}
144
147
145
- if ( xp[0 ] * co [0 ] + xp[1 ] * co [1 ] + xp[2 ] * co [2 ] + xp[3 ] * co [3 ] > x )
148
+ if ( xp[0 ] * endCo [0 ] + xp[1 ] * endCo [1 ] + xp[2 ] * endCo [2 ] + xp[3 ] * endCo [3 ] > x )
146
149
{
150
+ // We've crossed the target value, we can stop the search
151
+
152
+ if ( segment != points.begin () && xp[0 ] * startCo[0 ] + xp[1 ] * startCo[1 ] + xp[2 ] * startCo[2 ] + xp[3 ] * startCo[3 ] > x )
153
+ {
154
+ // We've not only crossed the target, we'd already jumped past it at the start of
155
+ // this segment... this could happen when there is a discontinuity between segments
156
+ // ( ie. for the "constant" basis ). In this case, we want to take the end of the
157
+ // previous segment
158
+ segment = prevSegment;
159
+ return X ( 1 );
160
+ }
161
+
147
162
break ;
148
163
}
149
164
@@ -154,6 +169,7 @@ inline X Spline<X,Y>::solve( X x, typename PointContainer::const_iterator &segme
154
169
return X ( 1 );
155
170
}
156
171
172
+ prevSegment = segment;
157
173
for ( unsigned i=0 ; i<basis.step ; i++ )
158
174
{
159
175
segment++;
0 commit comments