Skip to content

Commit 65cb3df

Browse files
committed
Keyframe::GetClosestPoint(): Use binary search
1 parent 54e8e37 commit 65cb3df

File tree

1 file changed

+22
-29
lines changed

1 file changed

+22
-29
lines changed

src/KeyFrame.cpp

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -121,39 +121,32 @@ bool Keyframe::Contains(Point p) const {
121121

122122
// Get current point (or closest point) from the X coordinate (i.e. the frame number)
123123
Point Keyframe::GetClosestPoint(Point p, bool useLeft) const {
124-
Point closest(-1, -1);
124+
if (Points.size() == 0) {
125+
return Point(-1, -1);
126+
}
125127

126-
// loop through points, and find a matching coordinate
127-
for (int64_t x = 0; x < Points.size(); x++) {
128-
// Get each point
129-
Point existing_point = Points[x];
128+
// Finds a point with an X coordinate which is "not less" (greater
129+
// or equal) than the queried X coordinate.
130+
std::vector<Point>::const_iterator candidate =
131+
std::lower_bound(begin(Points), end(Points), p.co.X, IsPointBeforeX);
130132

131-
// find a match
132-
if (existing_point.co.X >= p.co.X && !useLeft) {
133-
// New closest point found (to the Right)
134-
closest = existing_point;
135-
break;
136-
} else if (existing_point.co.X < p.co.X && useLeft) {
137-
// New closest point found (to the Left)
138-
closest = existing_point;
139-
} else if (existing_point.co.X >= p.co.X && useLeft) {
140-
// We've gone past the left point... so break
141-
break;
142-
}
133+
if (candidate == end(Points)) {
134+
// All points are before the queried point.
135+
//
136+
// Note: Behavior the same regardless of useLeft!
137+
return Points.back();
143138
}
144-
145-
// Handle edge cases (if no point was found)
146-
if (closest.co.X == -1) {
147-
if (p.co.X <= 1 && Points.size() > 0)
148-
// Assign 1st point
149-
closest = Points[0];
150-
else if (Points.size() > 0)
151-
// Assign last point
152-
closest = Points[Points.size() - 1];
139+
if (candidate == begin(Points)) {
140+
// First point is greater or equal to the queried point.
141+
//
142+
// Note: Behavior the same regardless of useLeft!
143+
return Points.front();
144+
}
145+
if (useLeft) {
146+
return *(candidate - 1);
147+
} else {
148+
return *candidate;
153149
}
154-
155-
// no matching point found
156-
return closest;
157150
}
158151

159152
// Get current point (or closest point to the right) from the X coordinate (i.e. the frame number)

0 commit comments

Comments
 (0)