Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to chain Bezier Curves in Flutter Canvas?

I am trying to create a curve with the Flutter CustomPainter. However, when I try to chain them, the resulting curve has some annoying edges. How can I achieve a smooth curve?

Resulting Curve

enter image description here

Annoying edge

enter image description here

canvas.translate(0, size.height / 2);
final Paint wavePainter = Paint()
  ..color = Color(0xFF1f58a1)
  ..strokeWidth = 8
  ..style = PaintingStyle.stroke;
double high = size.height;
double offset = size.width / 13;
Path path = Path()
  ..moveTo(0, 0)
  ..quadraticBezierTo(offset, -high / 3, 2 * offset, 0)
  ..quadraticBezierTo(4 * offset, high / 2, 5 * offset, 0)
  ..quadraticBezierTo(offset * 7, -high, offset * 8, 2)
  ..quadraticBezierTo(offset * 9, high / 2, offset * 11, 0)
  ..quadraticBezierTo(offset * 12, -high / 3, offset * 13, 0);
canvas.drawPath(path, wavePainter);
like image 374
Carlos Mario Sarmiento Pinilla Avatar asked Dec 31 '18 14:12

Carlos Mario Sarmiento Pinilla


1 Answers

I'm having the same issue. For now, and this is not an elegant solution, I smoothed the curve around those "annoying edges". In practice, every point is an average of the point before it and after it. I stopped using quadraticBezierTo and I'm using the equation of the Bezier curve to draw it (using a multitude of points).

image

It is still far from perfect, and is a temporary solution at best, depending on your requirements!

That being said, I think the solution (mathematically more complex but way more elegant), would be to use a N order Bezier Curve. N being the number of points on your graph. For an exemple of the result, you can check this: https://www.jasondavies.com/animated-bezier/

For the math, I'm checking for now :

  • https://pomax.github.io/bezierinfo/
  • https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm#B%C3%A9zier_curve

If you found a better solution by now, I'm all ears!

like image 112
Eric Mallard Avatar answered Oct 23 '22 20:10

Eric Mallard