Путь quadraticBezierTo: кривая проходит контрольную точку - PullRequest
0 голосов
/ 23 января 2019

У меня есть CustomPainter, который выглядит следующим образом:

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;
  }
}

И вот результат: https://imgur.com/a/m4i6WEA

Как бы я ни хотел, чтобы линия кривой прошла контрольную точку.Примерно так: https://imgur.com/a/cumbAVz

Как мне это сделать?!

1 Ответ

0 голосов
/ 23 января 2019

Вам необходимо рассчитать внутреннюю контрольную точку P1 координаты на основе необходимой точки top

Сначала приблизительно оцените параметр t для этой точки. Пусть это 1/2 (если top лежит около середины кривой). Используя квадратичную формулу Безье:

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

в компонентах:

P1.dx = 2 * top.dx - (left.dx + right.dx) / 2
P1.dy = 2 * top.dy - (left.dy + right.dy) / 2

и, наконец,

 ph.quadraticBezierTo(P1.dx, P1.dy, right.dx, right.dy);
...