Кривая Безье математика - PullRequest
       3

Кривая Безье математика

0 голосов
/ 08 декабря 2018

3 недели назад Я задал вопрос о том, как сохранить соотношение для кривой Безье при изменении точек X.«MBo» помогает мне, но возникла проблема, и он порекомендовал мне создать новую тему.

Проблема в том, что P0.Y и P2.Y могут отличаться и, следовательно, кривая выглядит как «булочка»".

Теперь у меня есть это и при изменении P0.X и P2.X я хочу сохранить соотношение, которое работает нормально: https://ibb.co/4WJfyjG https://www.w3schools.com/code/tryit.asp?filename=FXDIZMBCCYNA

При измененииP0.Y, например, выглядит как «бролли» (P1.X не точно посередине): https://ibb.co/NKyXHyG https://www.w3schools.com/code/tryit.asp?filename=FXDJ733KQZM4

ОК, я пытаюсьЧтобы объяснить это более подробно.

У меня есть четыре точки (X1, Y1, X2, Y2) и я хочу кривую Безье на основе точек так: P0.X находится на X1, P1.X междуX1 и X2 и P2.X на X2.P0.Y находится на Y1, а P2.Y на Y2.

Когда у меня теперь есть это:

ctx.moveTo(0, 50);
ctx.quadraticCurveTo(100, 25, 200, 50);

И меняя положение x1 и x2, я сохраняю соотношение сверху:

ctx.moveTo(0, 50);
ctx.quadraticCurveTo(25, 44, 50, 50);

Хорошо, пока эта часть работает нормально.Теперь моя проблема в том, что когда я изменяю Y1 или Y2, это выглядит как «сумасшедший», и кривая не круглая, как выше, потому что P1.X не точно посередине.

ctx.moveTo(0, 250);
ctx.quadraticCurveTo(100, 25, 200, 50);

enter image description here

Где бы это ни понравилось:

enter image description here

Ответы [ 2 ]

0 голосов
/ 09 декабря 2018

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

В вашем случае преобразование - это вращение и масштабирование вокруг первой точки (P0) кривой.

Угол поворота

 fi = arctan((P2'.Y - P2.Y) / (P2.X - P0.X))

Коэффициент масштабирования

 Cf = Sqrt(1 + (P2'.Y - P2.Y)^2/(P2.X - P0.X)^2) 

Таким образом, новые координаты для контрольных точек:

xx = P1.X - P0.X
yy = P1.Y - P0.Y
nx = xx * Cos(fi) - yy * Sin(fi) 
ny = xx * Sin(fi) + yy * Cos(fi) 
P1'.X = P0.X + nx * Cf
P1'.Y = P0.Y + ny * Cf
0 голосов
/ 08 декабря 2018

Я вижу это так:

quadratic bezier

Итак, вы получили 3 очка (P0(x0,y0),P1(x1,y1),P2(x2,y2)).Теперь вы хотите, чтобы все еще оставалось неясным , но я предполагаю, что вы просто хотите изменить размер кривой вдоль оси x и сохранить форму на оси y тоже ...

вам нужно поменять все вещи пропорционально ... так что поддерживая это:

(x1-x0) /  (x2-x0) = (x1'-x0') /  (x2'-x0')
(y1-y0) /  (y2-y0) = (y1'-y0') /  (y2'-y0')
(x1-x0) /  (x1'-x0') = c
(y1-y0) /  (y1'-y0') = c
(x2-x0) /  (x2'-x0') = c
(y2-y0) /  (y2'-y0') = c
(x2-x1) /  (x2'-x1') = c
(y2-y1) /  (y2'-y1') = c

, где x,y - исходные точки и x',y' - измененные

для вашего примера:

P0=(  0,50)
P1=(100,25)
P2=(200,50)
x2'=50

вам нужно пересчитать остальные, начните со шкалы:

c = (x2-x0) / (x2'-x0') = (200-0)/(50-0) = 200/50 = 4

, а затем просто пересчитайте отсутствующее:

(x1-x0) / c = (x1'-x0') // x0=0, x0'=0 
x1 / c = x1'
x1' =  100/4 = 25

(y1'-y0') = (y1-y0) / c  // y0' = y0
y1' = (y1-y0) / c + y0
y1' = (25-50) / 4 + 50
y1' = 43.75

(y2'-y0') = (y2-y0) / c  // y0' = y0
y1' = (y2-y0) / c + y0
y1' = (50-50) / 4 + 50
y1' = 50

То же самое касается изменения y ... после того, как вы изменили y, вам нужно пересчитать оставшиеся x,y, затронутые таким же образом ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...