diff --git a/include/KeyFrame.h b/include/KeyFrame.h index a60958a6..9724cc31 100644 --- a/include/KeyFrame.h +++ b/include/KeyFrame.h @@ -66,13 +66,6 @@ namespace openshot { bool needs_update; double FactorialLookup[4]; - /* - * Because points can be added in any order, we need to reorder them - * in ascending order based on the point.co.X value. This simplifies - * processing the curve, due to all the points going from left to right. - */ - void ReorderPoints(); - // Process an individual segment void ProcessSegment(int Segment, Point p1, Point p2); diff --git a/src/KeyFrame.cpp b/src/KeyFrame.cpp index 61b87146..2d4760bc 100644 --- a/src/KeyFrame.cpp +++ b/src/KeyFrame.cpp @@ -35,16 +35,6 @@ using namespace std; using namespace openshot; -// Because points can be added in any order, we need to reorder them -// in ascending order based on the point.co.X value. This simplifies -// processing the curve, due to all the points going from left to right. -void Keyframe::ReorderPoints() { - std::sort( - begin(Points), end(Points), - [](Point const & l, Point const & r) { - return l.co.X < r.co.X; - }); -} // Constructor which sets the default point & coordinate at X=1 Keyframe::Keyframe(double value) : needs_update(true) { @@ -67,17 +57,28 @@ void Keyframe::AddPoint(Point p) { // mark as dirty needs_update = true; - // Check for duplicate point (and remove it) - Point closest = GetClosestPoint(p); - if (closest.co.X == p.co.X) - // Remove existing point - RemovePoint(closest); - - // Add point at correct spot - Points.push_back(p); - - // Sort / Re-order points based on X coordinate - ReorderPoints(); + // candidate is not less (greater or equal) than the new point in + // the X coordinate. + std::vector::iterator candidate = + std::lower_bound(begin(Points), end(Points), p, [](Point const & l, Point const & r) { + return l.co.X < r.co.X; + }); + if (candidate == end(Points)) { + // New point X is greater than all other points' X, add to + // back. + Points.push_back(p); + } else if ((*candidate).co.X == p.co.X) { + // New point is at same X coordinate as some point, overwrite + // point. + *candidate = p; + } else { + // New point needs to be inserted before candidate; thus move + // candidate and all following one to the right and insert new + // point then where candidate was. + Points.push_back(p); // Make space; could also be a dummy point. + std::move_backward(candidate, end(Points) - 1, end(Points)); + *candidate = p; + } } // Add a new point on the key-frame, with some defaults set (BEZIER)