2011-01-29 249 views
2

我已閱讀過類似主題以找到解決方案,但沒有成功。 我想要做的是使工具相同,可以在CorelDraw中找到,名爲「鋼筆工具」。我通過連接貝塞爾三次曲線來完成,但仍然缺少一個特徵,即拖動曲線(而不是控制點)以編輯其形狀。通過三點的貝塞爾曲線

我可以成功確定拖動應該開始的曲線上的「t」參數,但不知道如何重新計算該曲線的控制點。

在這裏,我想強調一些與CorelDraw的PenTool行爲有關的東西,這些行爲可以用作爲constaints。我注意到,嚴格垂直或水平拖動曲線時,該貝塞爾曲線的控制點會相應地表現出來,即它們分別在垂直或水平方向上移動。

那麼,如何在曲線拖動時重新計算控制點的位置?

+0

您認爲每個人都被告知有關CorelDraw的行爲... – 2011-01-29 18:41:17

+0

我認爲我已經很清楚地描述CorelDraw的與問題相關的PenTool行爲。但是,您可以忽略PenTool屬於CorelDraw。只關注提到的行爲。 – Rasa 2011-01-29 19:00:49

+0

對我來說還不夠清楚。如果Bezier是通過控制點定義的,那麼對它的任何操作都應該通過修改控制點來完成。你正在解釋另一種拖動,但不清楚你在拖動什麼。曲線是一個等式,其唯一的參數是t和ctrl點。 – 2011-01-29 19:08:15

回答

2

我剛看着Inkspace來源,發現這樣的代碼,可它幫助你:

// Magic Bezier Drag Equations follow! 
// "weight" describes how the influence of the drag should be distributed 
// among the handles; 0 = front handle only, 1 = back handle only. 
double weight, t = _t; 
if (t <= 1.0/6.0) weight = 0; 
else if (t <= 0.5) weight = (pow((6 * t - 1)/2.0, 3))/2; 
else if (t <= 5.0/6.0) weight = (1 - pow((6 * (1-t) - 1)/2.0, 3))/2 + 0.5; 
else weight = 1; 

Geom::Point delta = new_pos - position(); 
Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta; 
Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta; 

first->front()->move(first->front()->position() + offset0); 
second->back()->move(second->back()->position() + offset1); 

在你的情況下「一線>前()」和「第二 - > back()「將意味着兩個控制點

0

當你點擊曲線時,你已經知道當前控制點的位置。因此,您可以計算偏移量X,並將該點從該點偏移到鼠標位置。在鼠標移動的情況下,您可以在X/Y偏移的幫助下重新計算新的控制點。

對不起,我的英語

2

貝塞爾曲線只不過是兩個多項式:X(t), Y(t)

立方之一:

x = ax*t^3 + bx*t^2 + cx*t + dx 
           0 <= t <= 1 
y = ay*t^3 + by*t^2 + cy*t + dy 

所以,如果你有一個曲線 - 你有聚係數。如果你移動你的點並且你知道它是t參數 - 那麼你可以簡單地重新計算poly的係數 - 它將是一個係數爲6的線性方程組(對於每個點)。系統按照兩個系統(x和y)進行細分,並且可以精確求解或使用一些數值方法 - 它們也不難。

因此,您現在的任務是在知道曲線的顯式方程時計算曲線的控制點。

它也可以帶到線性系統。對於廣義Bezier曲線我不知道該怎麼做,但對於三次曲線或二次曲線並不難。

通過控制點的三次曲線:你所要做的

B(t) = (1-t)^3*P0 + 3(1-t)^2*t*P1 + 3(1-t)*t^2*P2 + t^3*P3 

一切生產標準的多項式形式(只要打開支架)和等同的係數。這將爲控制點提供最終的系統!