贝塞尔曲线数学

时间:2018-12-08 14:25:59

标签: javascript math

3 weeks ago我问了一个问题,当更改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时,它看起来像“ brolly”,曲线也不像上面那样圆,因为P1.X不在中间。

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

enter image description here

它应该在哪里:

enter image description here

2 个答案:

答案 0 :(得分:0)

我这样看:

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 ...

答案 1 :(得分:0)

当贝塞尔曲线进行仿射变换时,会将相同的变换应用于其控制点。

在您的情况下,变换是围绕曲线的第一个点(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