[英]Bezier curve math
3周前,我問了一個問題,即在更改X點時如何保持貝塞爾曲線的比率。 “ MBo”可以幫助我,但是有問題,他建議我提出一個新主題。
問題在於P0.Y和P2.Y可能不同,因此曲線看起來像“粗略”。
現在我有了這個,在更改P0.X和P2.XI時要保持工作正常的比例: https://www.w3schools.com/code/tryit.asp?filename=FXDIZMBCCYNA
例如,當更改P0.Y時,它看起來像“ brolly”(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);
它應該這樣:
我看到這樣的:
所以你得到了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
您需要重新計算其余部分,並從scale開始:
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
...
當貝塞爾曲線經過某種仿射變換時,會將相同的變換應用於其控制點。
在您的情況下,變換是圍繞曲線的第一個點(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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.