Подтвердить что ты не робот

Нарисуйте квадратичную кривую Безье через три заданные точки

У меня три точки в 2D, и я хочу провести через них квадратичную кривую Безье. Как вычислить среднюю контрольную точку (x1 и y1 как в quadTo)? Я знаю линейную алгебру из колледжа, но мне нужна простая помощь.

Как я могу вычислить среднюю контрольную точку так, чтобы она также проходила через нее?

4b9b3361

Ответ 1

Пусть P0, P1, P2 - контрольные точки, а Pc - ваша фиксированная точка, через которую вы хотите пройти кривую.

Тогда кривая Безье определяется выражением

P(t) = P0*t^2 + P1*2*t*(1-t) + P2*(1-t)^2

... где t идет от нуля до 1.

На ваш вопрос бесконечное количество ответов, так как оно может пройти через вашу точку для любого значения t... Так что просто выберите один, например t = 0,5, и решите для P1:

Pc = P0*.25 + P1*2*.25 + P2*.25

P1 = (Pc - P0*.25 - P2*.25)/.5

   = 2*Pc - P0/2 - P2/2

Здесь значения "P" являются (x, y) парами, поэтому просто применяйте уравнение один раз для x и один раз для y:

x1 = 2*xc - x0/2 - x2/2
y1 = 2*yc - y0/2 - y2/2

... где (xc, yc) - это точка, которую вы хотите пройти, (x0, y0) - начальная точка, а (x2, y2) - конечная точка. Это даст вам Безье, проходящее через (xc, yc) при t = 0,5.

Ответ 2

Я использовал ответ Nemos в моем приложении JavaFX, но моя цель состояла в том, чтобы нарисовать кривую, чтобы визуальная точка поворота кривой всегда соответствовала выбранной фиксированной (CP).

CP = ControlPoint
SP = StartPoint
EP = EndPoint
BP (t) = переменная точка на BeziérCurve, где t находится между 0 и 1

Чтобы достичь этого, я сделал переменную t (not fix 0.5). Если выбранная точка CP больше не находится посередине между SP и EP, вам нужно немного поменять ее вверх или вниз. В качестве первого шага вам нужно знать, находится ли CP ближе к SP или EP: Пусть distanceSP - расстояние между CP и SP и distanceEP - расстояние между CP и EP то я определяю соотношение как:

ratio = (distanceSP - distanceEP) / (distanceSP + distanceEP);

Теперь мы будем использовать это для изменения t вверх и вниз:

ratio = 0.5 - (1/3) * ratio;

Примечание: это все еще приближение, и 1/3 выбирается с помощью попытки и ошибки.

Вот моя Java-функция: (Point2D - класс JavaFX)

private Point2D adjustControlPoint(Point2D start, Point2D end, Point2D visualControlPoint) {
    // CP = ControlPoint, SP = StartPoint, EP = EndPoint, BP(t) = variable Point on BeziérCurve where t is between 0 and 1
    // BP(t) = SP*t^2 + CP*2*t*(1-t) + EP*(1-t)^2
    // CP = (BP(t) - SP*t^2 - EP*(1-t)^2) / ( 2*t*(1-t) )
    // but we are missing t the goal is to approximate t
    double distanceStart  = visualControlPoint.distance(start);
    double distanceEnd    = visualControlPoint.distance(end);
    double ratio          = (distanceStart - distanceEnd) / (distanceStart + distanceEnd);
    // now approximate ratio to be t
    ratio = 0.5 - (1.0 / 3) * ratio;

    double ratioInv = 1 - ratio;
    Point2D term2 = start.multiply( ratio * ratio );
    Point2D term3 = end.multiply( ratioInv * ratioInv );
    double  term4 = 2 * ratio * ratioInv;

    return visualControlPoint.subtract(term2).subtract(term3).multiply( 1 / term4);
}

Надеюсь, это поможет.

Ответ 3

Если вам не нужна точная средняя точка, скорее вы хотите любое значение для t (от 0 до 1), уравнение равно:

controlX = pointToPassThroughX/t - startX*t - endX*t;
controlY = pointToPassThroughY/t - startY*t - endY*t;

Конечно, это также будет работать для средней точки, просто установите t равным 0,5. Просто!: -)