3 weeks ago我问了一个问题,当更改X点时如何保持贝塞尔曲线的比率。 “ MBo”可以帮助我,但出现了问题,他建议我提出一个新主题。
问题在于P0.Y和P2.Y可能不同,因此曲线看起来像是“粗糙”。
现在我有了这个,在更改P0.X和P2.X时,我想保持工作正常的比例:
https://www.w3schools.com/code/tryit.asp?filename=FXDIZMBCCYNA
例如,当更改P0.Y时,它看起来像一个“硬朗的”(P1.X不在中间):
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);
它应该在哪里:
答案 0 :(得分:0)
我这样看:
因此,您得到了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