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

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


Edit:
Suppose this is a curve we want to get the highest and lowest points from.
[199680-curve.png|199680]
We can see that there are 2 keyframes in AnimationCurve and the curve lying between them is a quadratic curve. This bezier will have 2 control points first one somewhere below the trough, and 2nd one somewhere above the crest. All four points can be obtained as per the method mentioned in the first link. Then use my method to get the min Y and max Y by supplying the Y coordinates of those 4 points. Since this curve has only 1 bezier, the result is the min max of the whole curve, otherwise compare min/max of all the beziers to get correct min and max.

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.