I'm currently using GDI+ to draw a line graph, and using Graphics.DrawCurve
to smooth out the line. The problem is that the curve doesn't always match the points I feed it, and that makes the curve grow out of the graph frame in some points, as seen below(red is Graphics.DrawLines
, green is Graphics.DrawCurve
).
How would I go about solving this?
The simplest solution is to set a tension:
The green curve is drawn with the default tension, the blue one set a tension of
0.1f
:You will need to test what is the best compromise,
0.2f
is still ok,0.3f
is already overdrawing quite a bit..For a really good solution you will need to use
DrawBeziers
. This will let you draw curves that can go through the points without any overdrawing and with full control of the radius of the curves; but to to so you will need to 'find', i.e. calculate goodcontrol points
, which is anything but trivial..:This result is by no means perfect but already complicated enough.. I have displayed the
curve points
and their respectivecontrol points
in the same color. For each point there is an incoming and an outgoing control point. For a smooth curve they need to have the same tangents/gradients in their curve points.I use a few helper functions to calculate a few things about the segments:
The main function calculates the array of
bezier points
, that is thecurve points
and between each pair the previous left and the next rightcontrol points
.In the
Paint
event it is used like this:Here are the functions I used:
And finally the main function; here I make a distinction: Extreme points ( minima & maxima) should have their control points on the same height as the points themselves. This will prevent vertical overflowing. They are easy to find: The signs of their gradients will always altenate.
Other points need to have the same gradient for incoming and outcoming control points. I use the average between the segments' gradients. (Maybe a weighed average would be better..) And I weigh their distance according to the segment lengths..
Note that I didn't code for the case of points with the same x-coordinate. So this is ok for 'functional graphs' but not for, say figures, like e.g. stars..