Skip to content

Commit cb55741

Browse files
committed
Keyframe::AddPoint() add at correct index, keeping Points ordered
AddPoint() now searches (binary search) for the best place to insert a new point, thus always maintaining the order of Points. Therefore, ReorderPoints() is no longer needed. CAVEAT: This breaks if some outside code changes (the public member) Points!
1 parent d9322c1 commit cb55741

File tree

2 files changed

+22
-28
lines changed

2 files changed

+22
-28
lines changed

include/KeyFrame.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,6 @@ namespace openshot {
6666
bool needs_update;
6767
double FactorialLookup[4];
6868

69-
/*
70-
* Because points can be added in any order, we need to reorder them
71-
* in ascending order based on the point.co.X value. This simplifies
72-
* processing the curve, due to all the points going from left to right.
73-
*/
74-
void ReorderPoints();
75-
7669
// Process an individual segment
7770
void ProcessSegment(int Segment, Point p1, Point p2);
7871

src/KeyFrame.cpp

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,6 @@
3535
using namespace std;
3636
using namespace openshot;
3737

38-
// Because points can be added in any order, we need to reorder them
39-
// in ascending order based on the point.co.X value. This simplifies
40-
// processing the curve, due to all the points going from left to right.
41-
void Keyframe::ReorderPoints() {
42-
std::sort(
43-
begin(Points), end(Points),
44-
[](Point const & l, Point const & r) {
45-
return l.co.X < r.co.X;
46-
});
47-
}
4838

4939
// Constructor which sets the default point & coordinate at X=1
5040
Keyframe::Keyframe(double value) : needs_update(true) {
@@ -67,17 +57,28 @@ void Keyframe::AddPoint(Point p) {
6757
// mark as dirty
6858
needs_update = true;
6959

70-
// Check for duplicate point (and remove it)
71-
Point closest = GetClosestPoint(p);
72-
if (closest.co.X == p.co.X)
73-
// Remove existing point
74-
RemovePoint(closest);
75-
76-
// Add point at correct spot
77-
Points.push_back(p);
78-
79-
// Sort / Re-order points based on X coordinate
80-
ReorderPoints();
60+
// candidate is not less (greater or equal) than the new point in
61+
// the X coordinate.
62+
std::vector<Point>::iterator candidate =
63+
std::lower_bound(begin(Points), end(Points), p, [](Point const & l, Point const & r) {
64+
return l.co.X < r.co.X;
65+
});
66+
if (candidate == end(Points)) {
67+
// New point X is greater than all other points' X, add to
68+
// back.
69+
Points.push_back(p);
70+
} else if ((*candidate).co.X == p.co.X) {
71+
// New point is at same X coordinate as some point, overwrite
72+
// point.
73+
*candidate = p;
74+
} else {
75+
// New point needs to be inserted before candidate; thus move
76+
// candidate and all following one to the right and insert new
77+
// point then where candidate was.
78+
Points.push_back(p); // Make space; could also be a dummy point.
79+
std::move_backward(candidate, end(Points) - 1, end(Points));
80+
*candidate = p;
81+
}
8182
}
8283

8384
// Add a new point on the key-frame, with some defaults set (BEZIER)

0 commit comments

Comments
 (0)