- Home /
Find AnimationCurve highest point
I randomly generated some Animation Curves, and now I want to find the highest value on a curve through script. How to find it? Thanks
Answer by Bunny83 · Nov 01, 2020 at 12:01 PM
Well, that's not that easy and requires some math skills ^^. First of all an AnimationCurve is a set of cubic bezier curves. We had already several questions about how the curves work behind the scenes. However it's a bit outdated since Unity now allows a "weight" per tangent which allows even more complex curves.
Once you have the actual equation for each curve segment you can find the maxima of each segment. To do this you first need to calculate the first and second derivative of the equation. To find extreme points (minima and maxima) you have to set the first derivative equal to 0 and solve for "t". Those are the t values for the extreme points. You then use the second derivative to figure out if the extreme point is a minima or maxima. The second derivative has to be negative for a maxima.
The final step is to shift the determined "t" values from each segment back to the whole time of the curve and sort the found points based on their y value.
While bezier curves aren't that complicated it would be quite a mess you have to go through to find those points. If you know that your curve is a relative simple curve (just one maxima) of course you can simply use an iterative approximation (like Newton's method) to get arbitrarily close to your maxima. Though this won't really help if your curve has more than one maxima.
All in all it's questionable if it's worth the trouble. It would be important to know how you generate those "random curves", how many control points they contain and for what you need the maxima. If it's important to know the maxima, wouldn't it make more sense to enfoce a random generated maxima be inserting a control point at a randomly selected point? If you really want / need a purely random curve there are no ways around either approximating the maxima through an iterative process or to go the analytical route.
Thank you for your answer! I generate the curve by adding random points within a certain range. I managed to approximate the maxima by evaluating 1000 samples of the curve, and find its highest point, then evaluating 1000 more around this highest point and pick its highest again. I wish there were a function that finds or approximates its maxima in Unity :)
Answer by MonkeyDLuffy121 · Sep 20, 2021 at 06:56 PM
I know the questions already answered but anyone who is looking for a code solution just adding my answer.
Just like @Bunny83 has mentioned only way I found was converting the animation curve to bezier first, by iterating through each curve between 2 Keyframes convert them to 4 points of a cubic bezier curve and storing them in a collection.
Answers in this post also helped along with links provided by @Bunny83.
After that had to get into quadratic equations and math of bezier curves to finaly get a formula for the roots, hopefully the code itself helps. Iterate through every 4 points in the collection and calculate Minima and Maxima using this
public Tuple<float, float> GetLocalMaximaNMinimaWRTTime(float y0, float y1, float y2, float y3)
{
float l_numeratorPart1 = -y0 + (2 * y1) - y2;
float l_discriminant = Mathf.Pow(y1, 2) + Mathf.Pow(y2, 2) - (y0 * y2) + (y0 * y3) - (y1 * y2) - (y1 * y3);
float l_divider = -y0 + (3 * y1) - (3 * y2) + y3;
float l_1stRoot = (l_numeratorPart1 + Mathf.Sqrt(l_discriminant)) / l_divider;
float l_2ndRoot = (l_numeratorPart1 - Mathf.Sqrt(l_discriminant)) / l_divider;
if (l_1stRoot > l_2ndRoot)
return new Tuple<float, float>(l_1stRoot, l_2ndRoot);
return new Tuple<float, float>(l_2ndRoot, l_1stRoot);
}
Atlast compare the values get the min and max for the curve
Your answer
Follow this Question
Related Questions
How can I set the tangents of Keyframes in an AnimationCurve through scripting? 1 Answer
Why is Unity Adding Extra Frames to Animation? 4 Answers
Parameterising one axis of collider - projecting extents not quite working. 1 Answer
[Solved]Animation Curve in Code 1 Answer
Evaluating Animation Curves in Full 0 Answers