Reputation: 516
I have a CustomPainter
that looks like this:
class MyPainter extends CustomPainter {
Offset left, top, right, bottom;
MyPainter({this.left, this.top, this.right, this.bottom});
@override
void paint(Canvas canvas, Size size) {
Paint pp = Paint()
..color = Colors.blue
..strokeCap = StrokeCap.round
..strokeWidth = 10;
Paint p = Paint()
..color = Colors.red
..style = PaintingStyle.stroke
..strokeWidth = 2;
Path ph = Path();
ph.moveTo(left.dx, left.dy);
ph.quadraticBezierTo(top.dx, top.dy, right.dx, right.dy);
canvas.drawPoints(PointMode.points, [left, top, right, bottom], pp);
canvas.drawPath(ph, p);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
And this is the result: https://i.sstatic.net/u9mHp.jpg
However I want the curve line, pass the control point. Something like this: https://i.sstatic.net/lC7XG.jpg
How can I do that?!
Upvotes: 1
Views: 2299
Reputation: 80187
You need to calculate internal control point P1
coordinates based on needed point top
At first, roughly evaluate parameter t
for that point. Let it is 1/2
(if top
lies near the middle of curve). Using quadratic Bezier formula:
P(t) = P0 * (1-t)^2 + 2 * P1 * t * (1-t) + P2 * t^2
top {for t=1/2} = P0 * 1/4 + P1 * 1/2 + P2 * 1/4
P1 = 2 * top - (P0 + P2) / 2
in components:
P1.dx = 2 * top.dx - (left.dx + right.dx) / 2
P1.dy = 2 * top.dy - (left.dy + right.dy) / 2
and finally
ph.quadraticBezierTo(P1.dx, P1.dy, right.dx, right.dy);
Upvotes: 3